Asp.net mvc 3 OneExecuted操作筛选器中的MVC模型为空。。。还是用一种更优雅的方式来设定模型?
我有一个ActionFilter,它覆盖了OnActionExecuted方法。在POST操作中,filterContext.Controller.ViewData.Model始终为空。我确实发现下面的文章似乎在说它不应该为null,但这一定是MVC的早期版本。这是MVC3。我应该得到什么 更新: 我已经找到了原来问题的答案。我有一个自定义ActionResult,它通过自定义日期格式化程序输出JSON。问题是控制器中没有设置模型 在我的自定义ActionResult中,ExecuterResult方法被传递到ControllerContext,如果我可以在那里设置模型,那就太好了: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
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);
}
}