MVC 模型在 OnExecuted 操作过滤器中为 null ...或者设置模型的更优雅的方式?
我有一个 ActionFilter,它覆盖了 OnActionExecuted 方法。在 POST 操作中,filterContext.Controller.ViewData.Model 始终为 null。我确实发现下面的文章似乎在说它不应该为 null,但这肯定是 MVC 的早期版本。这就是MVC3。我应该得到什么?
更新:
我已经找到了原始问题的答案。我有一个自定义 ActionResult,它使用自定义日期格式化程序输出 JSON。问题是模型没有在控制器中设置。
在我的自定义 ActionResult 中,ExecuteResult 方法传递给 ControllerContext,如果我可以在那里设置模型,那就太好了:
context.Controller.ViewData.Model = _data;
但这已经是循环的后期,并且 ActionFilter 中的结果仍然为 null。这似乎意味着我需要在控制器中手动设置模型:
ControllerContext.Controller.ViewData.Model = model;
或者
View(model);
这意味着我需要记住每次使用此自定义 ActionResult 时都执行此操作。有更优雅的方式吗?
另一个更新:
我找到了一种方法来做到这一点,但它并不像我希望的那么优雅。
在我在控制器中发送的comstom ActionResult 的构造函数中,这样至少它将始终保持一致:
public JsonNetResult(object data, Controller controller) {
SerializerSettings = new JsonSerializerSettings();
_data = data;
controller.ControllerContext.Controller.ViewData.Model = _data;
}
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?
Model availability inside ActionFilter
UPDATE:
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.
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;
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;
Or
View(model);
Which then means I need to remember to do this every time I use this custom ActionResult. Is there a more elegant way?
YET ANOTHER UPDATE:
I found a way to do this it just isn't as elegant as I hoped.
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
另一种方法是使用基本控制器自动处理操作参数集合的存储以供以后使用:
然后在您的属性中:
它使用 HttpContext 项目,这不是很好,但我不知道您可以访问 ViewBag 或 ViewData在属性中。
为了决定是否要在属性中处理请求,您可以询问操作名称和其他参数信息:
Another approach is to use a base controller to automatically handle the storing of the action parameters collection for later use:
then in your attribute:
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:
我找到了像您一样的解决方案,之前使用 OnModelUpdated 事件来设置该属性。
我有 ModelBinder:
之后,您需要在 Global.asax 的 Application_Start() 部分将默认绑定器设置为新模型绑定器:
最后你可以在 ActionFilter 中访问你的模型:
I found a solution like yours using the OnModelUpdated event to set that property before.
I have the ModelBinder:
After that, you need to set the default binder to your new model binder in Application_Start() section in Global.asax:
Finally you can access your Model in an ActionFilter: