Reputation: 16290
I have a web api controller and I need to audit the user that did the changes. Currently I do the following:
public class CustomerController : ApiController
{
private readonly ICustomerService customerService;
private bool userSet = false;
public CustomerController(ICustomerService customerService)
{
this.customerService = customerService;
}
[NonAction]
private SetUser(string userId)
{
if (userSet)
return;
//Get user from repository... here just for the example
var User = GetUser(userId);
customerService.SetUser(user);
userSet = true;
}
public Customer GetCustomer()
{
CookieHeaderValue cookie = Request.Headers.GetCookies("userId").FirstOrDefault();
SetUser(cookie["userId"].Value);
//code...
}
public int PostCustomer(Customer customer)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("userId").FirstOrDefault();
SetUser(cookie["userId"].Value);
//code...
}
public void PutCustomer(int id, Customer customer)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("userId").FirstOrDefault();
SetUser(cookie["userId"].Value);
//code..
}
public void DeleteCustomer(int id)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("userId").FirstOrDefault();
SetUser(cookie["userId"].Value);
//code...
}
}
I am getting the userid that is in the request, and I set the user in the service. However, I have many more controllers and these have many more actions.
Is this the way to do it or is there any alternative that I can set the userId for the 'session' (although not using the standard Session in Web API)?
Upvotes: 1
Views: 1372
Reputation: 98
you can inherit DelegatingHandler
,
for example:
public class MessageHandler1 : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
Debug.WriteLine("Process request");
// Call the inner handler.
var response = await base.SendAsync(request, cancellationToken);
Debug.WriteLine("Process response");
return response;
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new MessageHandler1());
// Other code not shown...
}
}
If you want to see in more detail,see here
Upvotes: 1
Reputation: 16393
You can make a base controller:
public abstract AuditableActionController : ApiController
{
private readonly ICustomerService customerService;
protected AuditableActionController(ICustomerService customerService)
{
this.customerService = customerService;
}
protected ICustomerService CustomerService { get { return this.customerService; } }
protected override void Initialize(HttpControllerContext controllerContext)
{
SetUser(cookie["userId"].Value);
// Make sure you call the base method after!
base.Initialize(controllerContext);
}
private void SetUser(string userId) { ... }
}
Then simply inherit all controllers which need auditing from it
public class CustomerController : AuditableActionController
You can also use ActionFilter
s to do this however there will be more complexity to share the ICustomerService
with the Controller
.
Upvotes: 1
Reputation: 142024
You achieve these kind of cross cutting concerns with either a MessageHandler or ActionFilter.
Upvotes: 1