I am using ASP.NET MVC 4 with Web Api
I have the following ApiController.
public class ProductsController : ApiController
{
public List<Product> GetProducts()
{
return _productService.GetAllProducts();
}
public List<Product> GetProductsFromId(string username)
{
return _productService.GetProductsFromUsername(username);
}
}
Now if you see the second Action GetProductsFromId(string username)
here I need to pass username which earlier (i.e before upgrading from MVC 3) I was using User.Identity.Username
to get the username.
How should I handle this in such a scenario.
How do I pass the username ? Is there something I could do.
Also the I dont want to use User.Identity.Username
inside the GetProductFromId(string username)
method as it will defeat the entire purpose of using web api and will not be testable too.
Please guide me help me on this. Thanks
Here is the basic outline of what I'm doing.
I use the "username" to get the IPrincipal.
I use the MemoryCache/ObjectCache to I'm only hitting the database, every 60 minutes. If you need it "per login" and not "per user".. (if your principal definition changes often or you need to code for the possibility, just change the cache-key to something that is username AND session based.
Note, I cannot stand using "IsInRole" in any app that isn't your kid's soccer club. (I don't have any kids, its a metaphor).
That's exactly what you should use:
Notice the
[Authorize]
attribute. Depending on the authorization scheme you are using theUser.Identity
will be populated differently. For example if you have enabled forms authentication then the username will obviously come from the forms authentication cookie that the client need to pass when invoking the action. You could also write a custom handler for example if you are using basic authentication instead of forms authentication. I wrote an example here.This doesn't defeat any purpose of unit testing. This method is perfectly fine unit testable. The User property of the ApiController is an
IPrincipal
which could be trivially mocked in a unit test. For example with Moq: