Leer ActionParameters no primitivos de filterContext en ActionFilter

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:

Reguladora

[Validate(ParameterName = "userID", EntityType="User")]
public ActionMethod Edit(int userID){...

Filtro de acción

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]);

Vea

[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?

preguntado el 09 de marzo de 12 a las 13:03

1 Respuestas

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; }
}

Atributo de validación:

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();
        }
    }
}

Controlador:

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);
    }
}

Vista

@model User

@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.FirstName)
    <button type="submit">OK</button>
}

respondido 10 mar '12, 08:03

That was exactly the answer I was looking for! I had both IAuthorizationFilter and ActionFilterAttribute implemented in the same class. Now I divided them - works perfect! Thanks a lot - ckonig

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.