How to find users by custom property in .net identity? - asp.net-mvc

My ApplicationUser class has a property called CompanyID.
All users are tied to a specific company. Now I'd like to list user accounts by CompanyID but can't figure out how to do it, UserManager.findxxx seem to be limited to whats built in and I can't seem to query it about custom properties.

Incase you extended the User model class with the CompanyId field:
var context = new ApplicationDbContext();
var usersByCompanyId = context.Users.Where(user => user.CompanyID == 1234).ToList();

use bottom code for get custom ApplicationUser in identity with custom property
var context=new AuthContext();
var result=context.Users.OfType<ApplicationUser>.SingleOrDefault(item => item.NationalCode == "");

Related

MVC6 Identity Custom Field Retrieval

I have added a new column called CompanyName to my AspNetUsers table. I'm looking to use this in queries within my API.
I have used the [Authorized] attribute to get
User.Identity.Name
This obviously gets the name of the user. I'm looking for a way to get the CompanyName.
Will I have to query the aspnetusers table directly to get this info?
You need to create an instance of your user in order to access user's properties, I use the UserManager class to create the user. There may be other ways to to get this done however this is what I have done in the past.
at the top of the controller class:
private Microsoft.AspNet.Identity.UserManager<YourApplication.Models.ApplicationUser> um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));//new up a UserManager
now inside the action method:
public ActionResult Index()
{
ApplicationUser user = um.FindById(User.Identity.GetUserId());//Create an instance of the user
ViewBag.CompanyName = user.CompanyName ;//Read the property
return View();
}
The following way will help you to put custom data.
if this doesnt help, please provide more information. like the source code of where you create or where you retrieve it.
string username = HttpContext.Current.User.Identity.Name;
var identity = new MyIdentity(username, true);
var principal = new MyPrincipal(identity, identity.Roles);
HttpContext.Current.User = principal;

MVC - unable to query Identity tables

I am trying to query the AspNetUsers table.
I have set up the db variable as follows
public ApplicationDbContext db = new ApplicationDbContext();
However, the intellisense for db does not list any of the Identity tables, but it does the others created for the web site (which are listed in IdenityModels.cs) e.g .......
public System.Data.Entity.DbSet<FeatureRequestMVC.Models.Feature> Features { get; set; }
How can I get the Identity tables (like AspNetUsers) listed in the db intellisense ?
Thanks
You can use the following code to instantiate the UserManager Class,
UserManager<ApplicationUser> userManager;
userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
Once you have added all the using statements required, you can call all sorts of methods to deal with Identity users.
// find user by id, also available for email and username
var user = await userManager.FindByIdAsync(Id param);
// with the user object above you can delete the referenced user
await userManager.DeleteAsync(user);
// Update user
await userManager.UpdateAsync(user);
All methods above use the async and await keyword
MSDN UserManager
Hope this helps.
The identity wants you to go through the UserManager for data, however there are cases where you need to query the identity tables. You can do something like
var sqlQuery = #"SELECT Users.UserName FROM AspNetUserClaims AS Claims
INNER JOIN AspNetUsers AS Users ON Claims.UserId = Users.Id
WHERE Claims.ClaimType = {0} AND Claims.ClaimValue = {1}";
var userName = dbContext.Database.SqlQuery<string>(sqlQuery, "MyClaimType", theClaimValue).ToList().FirstOrDefault();
This is pulling a single UserName and setting the variable as a string. You can create a model and pass that model into SqlQuery<T> as long as the property names match the column or alias names in your query.

ASP MVC 5 Identity 2: Cannot Determine how to Reference Custom role properties to User

I am using MVC 5 with Identity 2. I have created two roles, one for administrators, and one for vendors. The problem I have is that the registration form must use properties that are defined in the vendor role. I cannot figure out how to make MVC use those role properties for register purposes. I've tried assigning the appropriate role to the applicationuser but, after assigning it the role it still says it doesn't exist. Is there anyway of doing this, or am I going to have to split this into two register screens (ie one to handle initial user creation and a second one to handle role specific implementation)?
public async Task<ActionResult> Register(RegisterVendorViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName,
PhoneNumber = model.PhoneNumber,
CompanyName = model.CompanyName,
Address = model.Address,
City = model.City,
State = model.State,
PostalCode = model.PostalCode
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
UPDATE: I split the views, the first view deals solely with the creation of the Application User, while the second view is where I add the VendorUser Role fields to the user created in the first view. It now errors, and says that I am not able to add VendorUserRole attributes to IdentityUserRole.
Error Code "Error 2 Argument 1: cannot convert from 'Project1.Models.VendorUserRole' to 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole'"
I clearly failed to update or override something in my roles implementation. Does anyone have any idea of where this can be fixed? I thought I altered all of them to work properly.
// POST: /Account/RegisterP2
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> RegisterP2([Bind(Include = "Id")]RegisterPart2ViewModel model)
{
if (ModelState.IsValid)
{
var vendorUser = new VendorUserRole()
{
Id = model.Id,
CompanyName = model.CompanyName,
Title = model.Title,
Address = model.Address,
City = model.City,
State = model.State,
PostalCode = model.PostalCode,
};
var user = await UserManager.FindByIdAsync(vendorUser.Id);
**user.Roles.Add(vendorUser);**
UPDATE: I clearly need more understanding of Identity, before I try any more code; can someone tell me if my basic premise is correct?:
I need two different users: vendors and administrators which have different properties, I have one user class ApplicationUser which came with Identity 2. I have created roles with the different properties for each, and am now stuck. I cannot figure out how to reference the different roles to the main user class. According to my research in .NET a user is simply the entity that logs in, out, etc. Properly defined roles are supposed to allow you to attach the roles to a user instance, thereby creating the necessary role.
I hope I have not done hours of coding based on a faulty premise...
It is because before the user registers, his user is not yet created, therefore his not-yet-existent user cannot have a role. You should have two separate views, using the same models and controllers, but you should be aware the user does not exist yet.

How to assign a Role to a user in MVC5?

In MVC4 I was using the code
Roles.AddUserToRole(User.Identity.Name, "Approved");
Is there any other way of doing the same(adding user to role "Approved") in MVC5 Identity Model?
EDIT: I meant to ask is this the right way of adding a user to a role? Because in a lot of examples they do not use this code.
You can call AddToRole or AddToRoleAsync as an instance method on any object of type UserManager<TUser> to achieve it in MVC 5, like below:
var _context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_context));
UserManager.AddToRole("UserName", "UserRole");
For more details, take a look at the following link:
http://msdn.microsoft.com/en-us/library/dn468199(v=vs.111).aspx
http://blogs.msdn.com/b/webdev/archive/2013/10/20/building-a-simple-todo-application-with-asp-net-identity-and-associating-users-with-todoes.aspx

ASP.NET (OWIN) Identity: How to get UserID from a Web API controller?

(Using VS2013 RTW, ASP.NET MVC5)
I've seen lots of documentation on how to add properties to the ApplicationUser class (and table) when using ASP.NET identity. But I haven't seen any documentation on how to have a separate table with content that maps to the ApplicationUser table via a foreign key.
I've successfully derived my own Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext, and now my own "UserPreferences" table coexists in harmony with the various "AspNet*" tables in my SQL Server database. But I'm not clear on the best way to get the current user's ID so as to write a new row to the "UserPreferences" table. Note that the project is ASP.NET MVC, but I've added (and am working inside of) a Web API controller.
I have a working solution, which is:
var uman = new Microsoft.AspNet.Identity.UserManager<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new App1.Data.App1DbContext()));
var uident = User.Identity;
var userobject = uman.FindByNameAsync(uident.Name);
var userid = userobject.Result.Id;
// (Perform new row creation including the userid we just looked up
Consider that the AspNetUsers table (as defined by the Identity framework) consists of these fields:
-id (PK, nvarchar(128) - seems to contain a GUID, not sure why not an autoincrement integer, but I assume there are reasons for this)
-Username (nvarchar(max))
-PasswordHash (nvarchar(max))
-SecurityStamp (nvarchar(max))
I think that the id field (not the username) is the correct field to reference in this table. (I was thinking that a user may change his/her username, and someone else could then assume the other user's username, which is why both fields are there likely.) So then, I need to get the current user's ID for storage in the "UserPreferences" table, which is what the above code does. But it seems inefficient to have to do this lookup.
An important point is that in the context of a System.Web.Mvc.Controller, I can do:
User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity)
But in the context of a System.Web.Http.ApiController (Web API), I cannot because that method does not exist (runtime type of User.Identity: System.Security.Claims.ClaimsIdentity) which is why I must rely instead on:
User.Identity.Name
and do the extra lookup to convert Name to ID. Does anyone have any suggestions for how this can be improved? Am I approaching the task of writing user data to separate tables in the correct way?
You should be able to get user id on both MVC controller and web api controller by same extension method in identity 1.0 RTW package.
Here is the extensions from identity package:
namespace Microsoft.AspNet.Identity
{
public static class IdentityExtensions
{
public static string FindFirstValue(this ClaimsIdentity identity, string claimType);
public static string GetUserId(this IIdentity identity);
public static string GetUserName(this IIdentity identity);
}
}
The IIdentity is the base interface for all identity types. You may need to add "using Microsoft.AspNet.Identity" in order to see the extension method.
BTW: regarding adding a foreign table for user, why not using ApplicationUser and add navigation property to UserPreference to let EF to handle their relationship? That will be easier.
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID));
ClaimTypes.NameIdentifier is the claim for the function User.Identity.GetUserId()
I'm using claim base approach:
private ApplicationUser GetCurrentUser(ApplicationDbContext context)
{
var identity = User.Identity as ClaimsIdentity;
Claim identityClaim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
return context.Users.FirstOrDefault(u => u.Id == identityClaim.Value);
}
Short description for the best answer:
Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1
var userId = User.Identity.GetUserId();
Tried #Mastenka answer and it gave me nothing. I checked ClaimsIdentity and there were
claims type "UserName", so as a result, I get username by using "UserName" as ClaimsType.
Hope someone will give more info about it. It looks strange that "ClaimTypes.NameIdentifier" had no effect. (ApiController, ASP MVC API)
var userName = ((ClaimsIdentity)RequestContext.Principal.Identity).Claims.FirstOrDefault(cl => cl.Type == "UserName")?.Value;

Resources