I am currently developing an ASP.NET MVC project.
I want to implement an ActionFilter, that takes care about ownership permissions. A user may only access entities with which he is associated in the database.
Now I do not want to implement this into every Controller. Instead I want to use an ActionFilter. I can already identify incoming parameters and read their values with the following code:
Controller
[Validate(ParameterName = "userID", EntityType="User")]
public ActionMethod Edit(int userID){...
ActionFilter
public string ParameterName { get; set; }
public string EntityType { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (EntityType != null && ParameterName != null)
{
Debug.Print("Checking if user has access to the Type \"" + EntityType + "\" with the
ID " + filterContext.ActionParameters[ParameterName]);
...
So far, this works fine. But when it comes to non-primitive types (e.g. User), I only find a NULL value in filterContext.ActionParameters[ParameterName]);
See
[HttpPost]
[Validate(ParameterName = "user", EntityType = "User")]
public ActionResult Edit(User user)
{....
I cant figure out why. Could it be because this is a HttpPost method?
This should work assuming you have derived from ActionFilterAttribute
and haven't implemented IAuthorizationFilter
because if you implement this interface the action filter will run before the model binder and you will not be able to get the result of this model binder, only simple HTTP request values. Here's an example:
public class User
{
public string FirstName { get; set; }
}
Validation attribute:
public class ValidateAttribute : ActionFilterAttribute
{
public string ParameterName { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var result = (User)filterContext.ActionParameters[ParameterName];
if (result.FirstName == "john")
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new User
{
FirstName = "john"
});
}
[HttpPost]
[Validate(ParameterName = "user")]
public ActionResult Index(User user)
{
return View(user);
}
}
View:
@model User
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.FirstName)
<button type="submit">OK</button>
}