Querying AspNet Identity tables in Code First MVC application - c#

Is it possible to Query the AspNetUsers table based on the keyword using N-Tier design modeled after:
Implementing a generic data access layer using Entity Framework
I created the following Interfaces in my DAL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Library.Model;
namespace Library.DataAccessLayer
{
...
public interface IAspNetUserRepository : IGenericDataRepository<ApplicationUser>
{
}
public class AspNetUserRepository : GenericDataRepository<ApplicationUser>, IAspNetUserRepository
{
}
}
And the Following BLL entry:
using System;
using System.Collections.Generic;
using System.Linq;
using Library.DataAccessLayer;
using Library.Model;
namespace Library.BusinessLogicLayer
{
public interface IBusinessLogicLayer_AspNetUser
{
ApplicationUser GetAspNetUserByAspNetUserID(string _UserID);
}
public class BusinessLogicLayer_AspNetUser : IBusinessLogicLayer_AspNetUser
{
private readonly IAspNetUserRepository _AspNetUserRepository;
public BusinessLogicLayer_AspNetUser()
{
_AspNetUserRepository = new AspNetUserRepository();
}
public BusinessLogicLayer_AspNetUser(IAspNetUserRepository AspNetUserRepository)
{
_AspNetUserRepository = AspNetUserRepository;
}
public ApplicationUser GetAspNetUserByAspNetUserID(string _UserID)
{
return _AspNetUserRepository.GetSingle(u => u.Id.Equals(_UserID));
}
}
}
Now in the BLL file, the only Lambda expression does not contain Td so it errors out.
What is the correct model to use. The only information I can find is that ApplicationUser inherits Identity User.
What needs to be done or changed so I can get these fields added to the ApplicationUser model without it affecting the Code First portion for the database?

I finally found the answer. It was actually staring me right in the face.
simply use the following code to get the user(s) object:
var context = new ApplicationDbContext();
var user = context.Users.{Methods and Lambda expressions};
for example, say you need the existing KNOWN active user's UserName, use User.Identity.Name. And to get the active User's AspNetUsers database record:
var context = new ApplicationDbContext();
var user = context.Users.SingleOrDefault(u => u.UserName == User.Identity.Name);

Related

How can I execute a C# code from Azure SQL Server

Considering the following C# code, I would like to know how can I use it to create a computed column so when querying I could do SELECT ID, MaskedID FROM dbo.Product
ALTER TABLE dbo.Product ADD MaskedID AS (<Utils.Mask(ID) ???>) PERSISTED;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Util {
public string Mask(long id) {
var maskedId = $"do-something-with-{id}"; // it's way more complex than this
return maskedId;
}
}

C# ASP.NET | Is there any point in me using a model class when saving data to MongoDB?

I have begun writing an ASP.NET Web API for an app that I am building. I have set up a MongoCRUD.cs class to save data from POST requests made by the app to a MongoDB database (and other CRUD actions).
I (following a beginner tutorial), also set up a Submission.cs model class to act as a blueprint for the objects I wanted to save to the database. However, now that I have implemented the InsertRecord() method in MongoCRUD.cs, I cannot see a use for this model.
MongoCRUD.cs:
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebAPI.Services
{
public class MongoCRUD
{
private IMongoDatabase db;
public MongoCRUD(string database)
{
var client = new MongoClient();
db = client.GetDatabase(database);
}
public void InsertRecord<T>(string table, T record)
{
var collection = db.GetCollection<T>(table);
collection.InsertOne(record);
}
}
}
Submission.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Web;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace WebAPI.Models
{
public class Submission
{
[BsonId]
public string SubId { get; set; }
public string Url { get; set; }
public string Text { get; set; }
}
}
SubmissionsController.cs:
using WebAPI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPI.Services;
using System.IO;
using System.Web.Script.Serialization;
namespace WebAPI.Controllers
{
public class SubmissionsController : ApiController
{
MongoCRUD db = new MongoCRUD("myDb");
Submission[] submission = new Submission[] {
new Submission { SubId = "test", Url = "test", Text = "test" };
};
public IEnumerable<Submission> GetAllSubmissions()
{
//add MongoCRUD functionality for load record
return submission;
}
public IHttpActionResult GetSubmission(string id)
{
//add MongoCRUD functionality for load record
return Ok();
}
public IHttpActionResult PostSubmission(object body)
{
//validate body
db.InsertRecord("Submissions", body);
return Ok();
}
}
}
As you can see at PostSubmission(), the body of the POST request can be saved to the database directly, so my question is what is the benefit of using a model such as Submission.cs instead of just using the object type?
I'm having some trouble traversing the body object to access its values (for carrying out validation etc), so my only guess is that using a model makes it easier to access values?
object is the base type for all classes (See - https://learn.microsoft.com/en-us/dotnet/api/system.object?view=netcore-3.1).
C# is an object-orientated language so we try to model classes based on our business domain, this makes it easier to reason about the code.
Like you said you can have models that can be used to validate the incoming data into the controller, also you might want to add extra methods on the models that related to your business domain.
For example
class CreditCard
{
string CardNumber { get;set; }
string Csv { get;set; }
bool ValidateChecksum()
{ }
}

Error CS0103 The name 'db' does not exist in the current context

I'm assuming I'm missing a namespace declared on the top of my controller but I tried with 'using WebMatrix.Data;' and 'using System.IO;' that they are the usual suggestions for this error. It didn't work.
I'm trying to display more than one database table in the same view and this error is stopping me. Help please.
My Controller:
using System.Linq;
using System.Web.Mvc;
using KMS.Models;
using WebMatrix.Data;
using System.IO;
namespace KMS.Controllers
{
public class KMSController : Controller{
public ActionResult Index()
{
KMSConection cs = new KMSConection();
cs.Areas = (from o in db.Areas select o).Tolist();
cs.AreaTypes = (from o in db.AreaTypes select or).Tolist();
return View(cs);
}
}
}
My ViewModel Class:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using KMS.Models;
namespace KMS.Models
{
public class KMSConection: ApplicationDbContext
{
public DbSet<Area> Areas { get; set; }
public DbSet<AreaType> AreaTypes { get; set; }
}
}
Thanks!
Because you are not mentioning the db variable you have created into your KMSController. Try this code to fix the error:
using System.Linq;
using System.Web.Mvc;
using KMS.Models;
using WebMatrix.Data;
using System.IO;
namespace KMS.Controllers
{
public class KMSController : Controller{
public ActionResult Index()
{
//Insert the actual entity referred to your db variable.
//Probably something like:
//var db = Some Database Context
KMSConection cs = new KMSConection();
cs.Areas = (from o in db.Areas select o).Tolist();
cs.AreaTypes = (from o in db.AreaTypes select or).Tolist();
return View(cs);
}
}
}

Client Side Partial For DevForce Entity cannot see Properties exposed in the models partial

I am currently facing an issue where I am trying to make a WPF Client Side Partial of one of our Model First DevForce entities. The issue is that the partial in the WPF client does not seem to have access to the properties in it's sibling partial in the model project which the client project has referenced.
I have used the same namespace in both the client and the model but the client side keeps coming back as it is a partial with only a single file.
My main reasoning for this is that I need to access properties on a static class that resides in my client project within a property I am adding to the client side entity Partial. A sample of which follows:
Model Buddy Class:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Principal;
using IbEm = IdeaBlade.EntityModel;
using IdeaBlade.EntityModel.Security;
using IdeaBlade.Validation;
// ReSharper disable CheckNamespace
namespace BearPaw.Models.Main
{
[MetadataType(typeof(NavigationButtonGroupMetadata))]
public partial class NavigationButtonGroup
{
[IbEm.AllowRpc]
public static object NameAlreadyInUse(IPrincipal principal,
IbEm.EntityManager entityManager, params Object[] args)
{
string buttonGroupNameToCheck = (string)args[0];
var serverButtonGroup = entityManager.GetQuery<NavigationButtonGroup>().FirstOrDefault((u) => u.Name == buttonGroupNameToCheck);
return serverButtonGroup != null;
}
}
public class NavigationButtonGroupMetadata
{
[RegexVerifier("Name", #"^[A-Za-z_]*$")]
[StringLengthVerifier(MaxValue = 100, IsRequired = true, ErrorMessage = "Button Group Name must be unique")]
public static string Name;
}
}
Client Side Partial:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Principal;
using IbEm = IdeaBlade.EntityModel;
using IdeaBlade.EntityModel.Security;
using IdeaBlade.Validation;
// ReSharper disable CheckNamespace
namespace BearPaw.Models.Main
{
[MetadataType(typeof(NavigationButtonGroupMetadata))]
public partial class NavigationButtonGroup
{
public bool IsEnabled
{
get
{
{
if (NavigationButtonGroupType.AlwaysVisible || (DynamicMenuItemsHelper.MenuDetails != null && DynamicMenuItemsHelper.MenuDetails.Count() > 0 )) return true;
var currentUser = Authenticator.Instance?.DefaultAuthenticationContext?.Principal?.Identity;
return currentUser != null && NavigationButtons.
Any(b => b.IsEnabled);
}
}
}
}
}
Visual Studio is showing compile errors on NavigationButtonGroupType.AlwaysVisible stating an object reference is required for the non-static field even though NavigationButtonGroupType is a nav prop on the entity in the model. A similar issue applies in that NavigationButtons is also a nav property but Visual Studio is stating that it doesn't exist in the current context.
Any help or pointers as to why this would not be working would be greatly appreciated.
Many thanks
Lee
A partial class definition allows you to spread a class definition over multiple files, but only in the same assembly. This is a C# thing, not a DevForce restriction. See here for more information.
If I'm understanding correctly, you want some functionality of the entity class available only on the client (and some on the server too?). If you're defining client and server model projects you can use conditional compilation to determine which features of the entity are available in each assembly. This is fairly standard in DevForce SL applications, although maybe less used in WPF.
Another option is to put properties like this in the ViewModel, if you're using this type of architecture.

ASP.NET MVC placing userID in hidden field

I am using ASP.NET MVC 5 Razor
I am trying to apply the membership userID to a hidden field so that I can associate table data to a spceific user.
(users completes a form that is stored in a table, userID used to associate to login profile)
I just don't know how to do this and is an important part of my current project and future projects.
Any guidance, advice, links to solutions would be of great help as I am completely at a loss with this.
I tried passing the data from the model class for the view but I get an error saying "The name 'User' does not exist in the current context"
this is an extract of my model class
using System;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Globalization;
using System.Web.Security;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace mySite_Site.Models
{
[Table("accountInfo")] // Table name
public class accountInfo
{
[Key]
public int AccountID { get; set; }
public int UserIdent { get; set; } //this is the field that would store the userID for association
public string LastName { get; set; }
public string FirstName { get; set; }
public string Locality { get; set; }
public string EmailAddress { get; set; }
public bool Active { get; set; }
public DateTime LastLoggedIn { get; set; }
public string UserIdentity = User.Identity.GetUserId();
}
Expanding on Brandon O'Dell's answer, using "Membership" in that block of code didn't work for me (unhandled errors). Nevertheless, I think his approach to this solution is great because it means you can call the current user's Id from practically anywwhere. So, I went on ahead and played a little bit with the code, and voilá!.
In case using "Membership" doesn't work for you as well, try this one:
using <your project's name>.Models
public class GeneralHelpers
{
public static string GetUserId()
{
ApplicationDbContext db = new ApplicationDbContext();
var user = db.Users.FirstOrDefault(u => u.UserName == HttpContext.Current.User.Identity.Name);
return user.Id;
}
}
This one gets the whole user, so, you can create even more methods inside this "GeneralHelper" class (or whatever name you wish to give it) to get the current user's info and use it in your application.
Thanks, Brandon!
You just need something like this, assuming your ViewModel has the user profile on it.
#Html.HiddenFor(m=>m.UserProfile.UserId)
Since your model is not in the controller, you need to explicitly tell the code Where the user object is, which is contained in the HttpContext. So, update this line here:
public string UserIdentity = User.Identity.GetUserId();
to the following
public string UserIdentity = HttpContext.Current.User.Identity.GetUserId();
The controller and view base classes have a reference to the current HttpContext, which is why you can shortcut in those items and simply use User.Identity. Anywhere else in your project, you will need the fully qualified HttpContext.Current.User.
Edit
In further looking at your code, it looks like you are trying to save the user Id as a column in your database. In that instance, I think (based on your code sample) that you should remove that last part - public string UserIdentity = User.Identity.GetUserId();. When you save a new account info object, that is where you would save the user id.
var info = new accountInfo();
accountInfo.UserIdent = HttpContext.Current.User.Identity.GetUserId();
db.accountInfos.Add(info);
db.SaveChanges();
Why not just create a static helper class?
public static class UserUtils
{
public static object GetUserId()
{
return Membership
.GetUser(HttpContext.Current.User.Identity.Name)
.ProviderUserKey;
}
}

Categories