Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing username to Web Api methods in ASP.NET MVC 4

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

like image 265
Yasser Shaikh Avatar asked Dec 12 '22 21:12

Yasser Shaikh


1 Answers

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.

That's exactly what you should use:

[Authorize]
public List<Product> GetProductsFromId()
{
    string username = User.Identity.Name;
    return _productService.GetProductsFromUsername(username);
}

Notice the [Authorize] attribute. Depending on the authorization scheme you are using the User.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:

// arrange
var sut = new ProductsController();
var user = new Mock<IPrincipal>();
var identity = new Mock<IIdentity>();
user.Setup(x => x.Identity).Returns(identity.Object);
identity.Setup(x => x.Name).Returns("john");
Thread.CurrentPrincipal = user.Object;

// act
var actual = sut.GetProductsFromId();

// assert
...
like image 132
Darin Dimitrov Avatar answered Jan 28 '23 20:01

Darin Dimitrov