Access custom property from IdentityUser in ValuesController without extension - Web API - asp.net

I have followed on from the following answer here: How to extend IdentityUser with custom property
My variables I have added (following the above answer) are:
int numberID
string fullName
This is built upon the default Visual Studio 2017 ASP.net Web Application selected with options Web API and Individual User Accounts Authentication.
I am now trying to read the current value of both numberID and fullName of the current user inside the ValuesController of the project.
I have tried doing
var currentUser = System.Web.HttpContext.Current.User.Identity.GetUserId();
var currentnumberID = currentUser.numberID;
But am having no sucess with the last line of code.
I have also used User.Identity.GetUserName() and was wondering if there was a way to access my new variables WITHOUT creating a User Identity Extension?
OR
Better yet, with my Web API app what is the best way to add additional variables / fields for the user. Ie I would like to add both fullName and numberID associated to each user and be able to access these in my Web API controllers (eg call for current user and list the variables associated to the current user). I am beginning to think I have taken the wrong road by trying to use UserIdentity.
EDIT
Ended up biting the bullet and following the very easy approach here: How to Get Custom Property Value of the ApplicationUser in the ASP.Net MVC 5 View?
of adding a User Identity extension. Previous answers seemed complicated but that answer was simple and works!

The problem is that you are reading UserId and treating it like User object.
You need to use UserManager, to get the user User object. Inside controller's action method, you have access to UserManager, so you can simply use it:
var currentUser = UserManager.FindById(User.Identity.GetUserId());
If you are not inside controller's action method, then you need to get the UserManager from HttpContext:
var UserManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();

Related

Problem with customizing default identity in asp.net

I need help with something that I messed with.. I customized the default identity in Asp.Net, I changed the names of the tibles and the type of the user (from string to Guid). When I override the Id of my User I receive errors with the UserManager (for registration) and with SignInManager (for log in). I didn't find a way to change their implementation...
If I don't override the user Id, I get 2 Ids when an User is created - a new Guid that's needed and another with value "00000000-0000-0000-0000-00000000000"
How can this issue be solved?

Trying to obtain the current logged in user's ID for tracking fields

I am following this really good tutorial to setup a BaseEntity class that will contain 5 fields:
Active, DateCreated, UserCreated, DateModified, UserModified.
All of my entities that need these tracking fields will inherit from this class.
In the small tutorial below he shows me how to override the SaveChanges() method in my dbContext so that these fields will be set properly based on Creation/Updating.
I am trying to figure out how I would store the current logged in user's ID rather than the Name to the UserCreated and UserModified fields
Please let me know if the UserID shouldn't be what I am storing. This is always what I used to do in some of the webforms apps I created back in the day.
Also, what would be the best way to setup Active to always be true when adding new records. Should this be done in the db context also or within my BaseEntity class. I'm thinking I would create a function in the BaseEntity class called Disable() that will change Active=False.
Please view the small tutorial that I am using
You could create a custom implementation of IIdentity/IPrincipal which contains the UserID. Then you can retrieve this value from the Context or Thread and cast it to the correct type.
Set HttpContext.Current.User from Thread.CurrentPrincipal

Adding custom role to user ASP.NET Identity

Context of problem
In my web application I've been using ASP.NET Identity. I've created custom user profiles by inheriting the User class from IdentityUser. To be able to connect the Roles with for example rolegroups I've also created a custom role class within my database which inherits from the IdentityRole class.
My database model looks like this:
The problem isn't in creating a user. This just works:
var userManager = new UserManager<User>(new UserStore<User>(_context));
var result = userManager.Create(user, password);
Same with creating a role.
var rm = new RoleManager<Role>(new RoleStore<Role>(_context));
var result = rm.Create(new Role(name));
Problem
But its when I try to attach a role to a user (With the following code)
var um = new UserManager<User>(new UserStore<User>(_context));
var result = um.AddToRole(userId, roleName);
The error I get is basically "The entity type IdentityRole is not part of the model for the current context."
Which is true, btw. But how can I make it that my Role entity is seen as the IdentityRole entity, which it basically is, or has to be.
See the full stacktrace here: http://pastebin.com/sEPv5LiT
Thanks in advance!
As i understand you want to define custom roles for users i prefer to add library project in your solution and manage all membership and roles through this.
Custom Asp.Net Membership
I make library project for that if you want i will provide you

Getting and Displaying AD object properties via a webform

What would be the easiest way to get AD user object properties via a webform based on user input?
To elaborate a bit more this is what I would need:
User enters input to an input field (Employee number - we store it as an extension attribute in AD)
On button click the form returns additional user object properties of the account (such as sAMAccountname, Manager) and displays it on the page (preferably)
I also need to have these properties converted to variables the form can use to pass on to another page sending an e-mail with the retrieved information.
We're using asp for our webforms. So far we only needed to pass user input directly to the mail sender, but this one seems more tricky.
Appreciate any help, thanks!
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// display the various properties of the "user" object in your web page
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Need help designing to ASP.NET MVC action methods

I'm just starting out learning ASP.NET MVC 3. I've been going through the Music store sample on the ASP.NET website, as well as starting to develop my own site, but I'm having some trouble understanding how I should setup my controller action methods.
On my site each user that is logged in will be able to perform standard CRUD operations on their Projects. I've set this up similar to the Music Store sample with the following action methods on a ProjectController. So far this makes sense to me.
ActionMethod View
ProjectController.Index() Lists the active users's projects
ProjectController.Details(int id) Shows details for project 123
ProjectController.Create() Shows a form to edit a new project
ProjectController.Create(FormCollection col) Adds a new project with the form contents
ProjectController.Edit() Shows a form to edit a new project
ProjectController.Edit(int id, FormCollection col) Adds a new project with the form contents
ProjectController.Deiete(int id) Shows a delete confirmation form
ProjectController.Delete(int id, FormCollection col) Deletes a project with the provided id.
In addition, users will be able to add Items to each project. Items can not exist on their own and must be associated to a project when being created. What I'm having trouble understanding is how to pass along the reference to the project an Item should be created in. For example in my item controller I have a pair of Create() action methods similar to the controller above.
ItemController.Create() Shows a form to create a new item
ItemController.Create(FormCollection col) Creates a new item with the details from the form.
Yet I don't understand how the first Create() method passes a reference to the project which the new Item should be created in since the View() helper method can only accept one object parameter. Should I just add a reference to a project to a property of the ViewBag? I'm new to dynamic types as well and the ViewBag just seems magic to me at the point. So I'm a little hesitant to use it. I've also always thought strongly typed design is better. So should I create a separate "NewItemData" model object that contains a reference to a new Item as well as the project it is being added to?
Once the form knows which project it is adding an item to how should it pass this information back when submitted? Should there be a hidden "ProjectID" field in the form? Or should the form POST back to a URL with the project id in the query string?
www.mysite.com/Item/Create?ProjectID=1234
Finally, I also want to be able to list the items that are added to each project. Should this be part of the ItemController or the ProjectController. For simplicities sake I'm sticking with the default Controller\Action[ID] URL routing. A few of my ideas are listed below. I'm leaning towards the last option, but would really like to hear what others with more experience with this stuff think.
Action Method URL
ItemController.Index(int ProjectID) \Item?ProjectID=1234
ItemController.List(int id) \Item\List\1234
ProjectController.Items(int id) \Project\Items\1234
To answer your last question, it depends. Do Items in your model exist independently of a project? If the answer is no, then I would tend to do
ProjectController.AddItem(int id)
ProjectController.Items(int id)
where id represents the projectID.
The name of the parameters you use in the action signature directly correspond to values from the routedata and request values. {controller}/{action}/{id} is a pattern that uses the braced names as keys in the route dictionary. If you wanted you could change the routes to be {controller}/{action}/{projectid} for that action and your method signature could be the (int projectid) signature.
I don't recommend you do this just to get awesome signatures. Use comments instead if you think people will get confused.
Without changing the route pattern, if you would prefer your urls to be /project/items?projectid=3 than /project/items/3 then the action would be this:
ProjectController.Items(int projectId)
I like the prettier urls, so i'd be more apt to use the id version. That being said, if Items do not exist independently of the Project object, I would be be more likely to do this. However, if you are going to have a TON of different actions that can be performed on an Item, it would make sense to separate them into ItemController and ProjectController.
It comes down, to a large extent, about what makes sense for your application and how many actions you think a controller should have on it.
In this case you'd create a hidden field with the name=projectId and then in your Create controller have an action method.
[HttpPost]
public ActionResult Create( int projectId, FormCollection postData )
Usually you'd also use a strongly typed viewmodel so instead the FormCollection parameter use:
[HttpPost]
public ActionResult Create( int projectId, Item or ItemViewModel postData )
And as long as the name attributes match the properties in Item or ItemViewModel MVC's ModelBinder will take care of hydrating those values.

Resources