Asp.net mvc - 从自定义Action过滤器访问视图模型

ebr*_*own 37 c# asp.net-mvc custom-action-filter

我试图访问传递给动作过滤器OnActionExecuted中的视图的模型数据.有谁知道这是否可能?

我想做这样的事情:

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

    sitemap.SetCurrentNode(model.Name);
}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Ste*_*ons 57

该模型位于:

filterContext.Controller.ViewData.Model
Run Code Online (Sandbox Code Playgroud)

  • 它始终为null :( (10认同)
  • 在所有方法中对我来说都是空的(OnActionExecuting,OnActionExecuted,OnResultExecuting,OnResultExecuted) (9认同)
  • @Korayem - 取决于您尝试和访问它的时间.如果在控制器操作执行后得到它,它应该是viewmodel的一个实例. (4认同)
  • 请参阅[管道示意图](http://www.dotnettricks.com/learn/mvc/detailed-aspnet-mvc-pipeline),了解何时在viewdata上设置模型. (3认同)

小智 19

我不知道为什么但是filterContext.Controller.ViewData.Model即使之前执行模型绑定也总是为null OnActionExecuted.我找到了一个使用该OnModelUpdated事件来设置该属性的解决方案.

我有模型粘合剂:

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

之后,您需要Application_Start()在Global.asax 中的部分中将默认绑定器设置为新的模型绑定器:

ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
Run Code Online (Sandbox Code Playgroud)

最后,您可以访问您ModelActionFilterAttribute:

public class TraceLog : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //filterContext.Controller.ViewData.Model now isn't null
        base.OnActionExecuted(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)