MVC 模型在 OnExecuted 操作过滤器中为空……还是设置模型的更优雅的方式? [英] MVC Model is null in OnExecuted action filter ... or a more elegant way to set the model?

查看:13
本文介绍了MVC 模型在 OnExecuted 操作过滤器中为空……还是设置模型的更优雅的方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an ActionFilter with an override on the OnActionExecuted method. The filterContext.Controller.ViewData.Model is always null on a POST operation. I did find the following article that seems to be saying that it should not be null but this must have been an earlier version of MVC. This is MVC3. What should I be getting?

ActionFilter 内的模型可用性

更新:

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

I've figured out the answer to the original question. I had a custom ActionResult that outputs JSON with a custom date formatter. The problem was that the model is not being set in the controller.

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

In my custom ActionResult the ExecuteResult method get passed the ControllerContext which would be nice if I could set the Model there:

context.Controller.ViewData.Model = _data;

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

But this is to late in the cycle and the result is still null in the ActionFilter. This seems to mean that I need to manually set the model in the controller:

ControllerContext.Controller.ViewData.Model = model; 

或者

View(model);

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

Which then means I need to remember to do this every time I use this custom ActionResult. Is there a more elegant way?

另一个更新:

我找到了一种方法来做到这一点,只是没有我希望的那么优雅.

I found a way to do this it just isn't as elegant as I hoped.

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

In my constructor for the comstom ActionResult I sending in the controller, that way at least it will alway be consistent:

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

推荐答案

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

Another approach is to use a base controller to automatically handle the storing of the action parameters collection for later use:

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

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

It uses HttpContext items which is not very nice but I don't know that you can access your ViewBag or ViewData in the attribute.

为了决定是否要处理你的属性中的请求,你可以查询动作名称和其他参数信息:

In order to decide whether you want to handle the request in your attribute, you can interrogate the action name and other parameter information:

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

这篇关于MVC 模型在 OnExecuted 操作过滤器中为空……还是设置模型的更优雅的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆