Asp.net MVC-accès au modèle de vue à partir d'un filtre d'Action personnalisé

J'essaie d'accéder aux données du modèle transmises à la vue dans le filtre D'action OnActionExecuted. Est-ce que quelqu'un sait si c'est possible?

J'essaie de faire quelque chose comme ceci:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    //get model data
    //...

    sitemap.SetCurrentNode(model.Name);
}

Un conseil?

34
demandé sur ebrown 2009-05-16 20:52:11

4 réponses

Le modèle est à:

filterContext.Controller.ViewData.Model
53
répondu Steven Lyons 2009-05-16 16:56:01

Je ne sais pas pourquoi mais filterContext.Controller.ViewData.Model est toujours null même lorsque la liaison du modèle est exécutée avant OnActionExecuted. J'ai trouvé une solution en utilisant l'événement OnModelUpdated pour définir cette propriété avant.

J'ai le classeur modèle:

public class CustomModelBinder: DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.Controller.ViewData.Model = bindingContext.Model;
        base.OnModelUpdated(controllerContext, bindingContext);
    }
}

Après cela, vous devez définir le classeur par défaut sur votre nouveau classeur de modèle dans la section Application_Start() dans Global.asax:

ModelBinders.Binders.DefaultBinder = new CustomModelBinder();

Enfin, vous pouvez accéder à votre Model en ActionFilterAttribute:

public class TraceLog : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //filterContext.Controller.ViewData.Model now isn't null
        base.OnActionExecuted(filterContext);
    }
}
19
répondu gustavocs 2016-01-13 15:33:42

Sur. net Core, vous avez un IDictionary ActionArguments sur le contexte, avec tous les paramètres de votre méthode

Donc, si vous avez la méthode de contrôleur suivante

    [HttpPost]
    public void Post([FromBody]BaseRequest request)
    {
    }

Vous pouvez accéder au champ comme

    public override void OnActionExecuting(ActionExecutingContext context)
    {
      var request = context.ActionArguments["request"] as BaseRequest;`
      //do whatever, 
    }
2
répondu Safin Ahmed 2017-01-12 00:17:52

Si vous obtenez null - comme alternative à la réponse de @Gustavo Clemente, vous pouvez essayer de remplacer OnActionExecuted et de passer votre viewModel en vue de la manière suivante:

Action:

[Breadcrumb("Index")]
public ActionResult UnitIndex()
{
    View(new Answers());
}

Attribut:

public class BreadcrumbAttribute : ActionFilterAttribute
{
    public string Page { get; set; }

    public BreadcrumbAttribute(string page)
    {
        Page = page;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var model = (IBreadcrumbs)filterContext.Controller.ViewData.Model;
        model.Breadcrumbs = BreadcrumbHelper.GetBreadCrumbs(string.Format("{0}", filterContext.RouteData.DataTokens["area"]), Page);
    }
}

entrez la description de l'image ici

1
répondu Matas Vaitkevicius 2015-11-17 14:10:24