OnExecuted动作过滤器中的MVC模型为空...或者设置模型的更优雅方式?

Mik*_*ike 7 null controller model onactionexecuted asp.net-mvc-3

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

ActionFilter中的模型可用性

更新:

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

在我的自定义ActionResult中,ExecuteResult方法传递了ControllerContext,如果我可以在那里设置模型那将是很好的:

context.Controller.ViewData.Model = _data;
Run Code Online (Sandbox Code Playgroud)

但这是在循环的后期,结果在ActionFilter中仍为null.这似乎意味着我需要在控制器中手动设置模型:

ControllerContext.Controller.ViewData.Model = model; 
Run Code Online (Sandbox Code Playgroud)

要么

View(model);
Run Code Online (Sandbox Code Playgroud)

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

再来一次更新:

我找到了一种方法来做到这一点它并不像我希望的那样优雅.

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

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

Rob*_*ent 2

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的属性中:

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);
}
Run Code Online (Sandbox Code Playgroud)

它使用 HttpContext 项目,这不是很好,但我不知道您可以在属性中访问 ViewBag 或 ViewData 。

为了决定是否要在属性中处理请求,您可以询问操作名称和其他参数信息:

var action = filterContext.ActionDescriptor.ActionName;
var parms = filterContext.ActionDescriptor.GetParameters();
foreach (var parameterDescriptor in parms)
{
    // do something here
}
Run Code Online (Sandbox Code Playgroud)