Asp.net mvc 3 OneExecuted操作筛选器中的MVC模型为空。。。还是用一种更优雅的方式来设定模型?

Asp.net mvc 3 OneExecuted操作筛选器中的MVC模型为空。。。还是用一种更优雅的方式来设定模型?,asp.net-mvc-3,model,null,controller,onactionexecuted,Asp.net Mvc 3,Model,Null,Controller,Onactionexecuted,我有一个ActionFilter,它覆盖了OnActionExecuted方法。在POST操作中,filterContext.Controller.ViewData.Model始终为空。我确实发现下面的文章似乎在说它不应该为null,但这一定是MVC的早期版本。这是MVC3。我应该得到什么 更新: 我已经找到了原来问题的答案。我有一个自定义ActionResult,它通过自定义日期格式化程序输出JSON。问题是控制器中没有设置模型 在我的自定义ActionResult中,ExecuterRes

我有一个ActionFilter,它覆盖了OnActionExecuted方法。在POST操作中,filterContext.Controller.ViewData.Model始终为空。我确实发现下面的文章似乎在说它不应该为null,但这一定是MVC的早期版本。这是MVC3。我应该得到什么

更新:

我已经找到了原来问题的答案。我有一个自定义ActionResult,它通过自定义日期格式化程序输出JSON。问题是控制器中没有设置模型

在我的自定义ActionResult中,ExecuterResult方法被传递到ControllerContext,如果我可以在那里设置模型,那就太好了:

context.Controller.ViewData.Model = _data;
但这已经到了周期的后期,ActionFilter中的结果仍然为空。这似乎意味着我需要在控制器中手动设置模型:

ControllerContext.Controller.ViewData.Model = model; 

这就意味着我需要记住每次使用这个自定义ActionResult时都要这样做。还有更优雅的方式吗

还有一个更新:

我找到了一种方法,但它并不像我希望的那样优雅

在我发送给控制器的comstom ActionResult的构造函数中,这样至少它始终是一致的:

public JsonNetResult(object data, Controller controller) {
    SerializerSettings = new JsonSerializerSettings();
    _data = data;
    controller.ControllerContext.Controller.ViewData.Model = _data;
}

另一种方法是使用基本控制器自动处理动作参数集合的存储,以供以后使用:

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Items["ActionParms"] = filterContext.ActionParameters.ToDictionary(p => p.Key, p => p.Value);
        base.OnActionExecuting(filterContext);
    }
}
然后在属性中:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var dictionary = filterContext.HttpContext.Items["ActionParms"] as Dictionary<string, object>;
    if (dictionary != null)
    {
        foreach (var o in dictionary.Keys)
        {
            // do something here
        }   
    }            
    base.OnActionExecuted(filterContext);
}

我发现了一个类似于您的解决方案,使用OnModelUpdated事件在之前设置该属性

我有ModelBinder:

public class CustomModelBinder: DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.Controller.ViewData.Model = bindingContext.Model;
        base.OnModelUpdated(controllerContext, bindingContext);
    }
}
之后,您需要在Global.asax的Application_Start()部分将默认活页夹设置为新的模型活页夹:

ModelBinders.Binders.DefaultBinder=新的CustomModelBinder()

最后,您可以在ActionFilter中访问您的模型:


我找到了一个解决方案并发布在这里:
var action = filterContext.ActionDescriptor.ActionName;
var parms = filterContext.ActionDescriptor.GetParameters();
foreach (var parameterDescriptor in parms)
{
    // do something here
}
public class CustomModelBinder: DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.Controller.ViewData.Model = bindingContext.Model;
        base.OnModelUpdated(controllerContext, bindingContext);
    }
}
public class TraceLog : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //filterContext.Controller.ViewData.Model now isn't null
        base.OnActionExecuted(filterContext);
    }
}