如何在请求过滤器中的 ViewResult 上设置视图模型?
Posted
技术标签:
【中文标题】如何在请求过滤器中的 ViewResult 上设置视图模型?【英文标题】:How to set view model on ViewResult in request filter? 【发布时间】:2013-12-01 07:19:37 【问题描述】:我做了一个 MVC 项目,我想从过滤器中将模型设置为视图。
但我不知道,我该怎么做。
模型:
public class TestModel
public int ID get; set;
public string Name get; set;
控制器:
[CustomFilter(View = "../Test/Test")]//<===/Test/Test.cshtml
public ActionResult Test(TestModel testModel)//<===Model from Page
//the Model has Value!!
// if has some exception here
return View(model);//<=====/Test/Test.cshtml
过滤器(只是演示):
public override void OnActionExecuting(ActionExecutingContext filterContext)
ViewResult vr = new System.Web.Mvc.ViewResult()
ViewName = this.View,//<======/Test/Test.cshtml
ViewData = filterContext.Controller.ViewData
;
//How can I set Model here?!!
vr.Model = ???? //<========the Model is only get
filterContext.Result = vr;
编辑开始感谢@Richard Szalay @Zabavsky @James @spaceman
更改过滤器扩展到 HandleErrorAttribute
ViewResult vr = new System.Web.Mvc.ViewResult()
ViewName = this.View,//<======/Test/Test.cshtml
ViewData = new ViewDataDictionary(filterContext.Controller.ViewData)
//I want get testModel from Action's paramater
//the filter extends HandleErrorAttribute
Model = new ID = 3, Name = "test" // set the model
;
编辑结束
测试/Test.chtml
@model TestModel
<h2>Test</h2>
@Model //<=====model is null
当我请求时
http://localhost/Test/Test?ID=3&Name=4
测试页无法获取模型。
【问题讨论】:
【参考方案1】:模型属性实际上只是一个 ViewDataDictionary,您可以使用您的实际模型初始化它的实例,即
vr.Model = new ViewDataDictionary(model);
【讨论】:
也非常感谢。【参考方案2】:ViewResult vr = new System.Web.Mvc.ViewResult
ViewName = this.View, //<======/Test/Test.cshtml
ViewData = new ViewDataDictionary(filterContext.Controller.ViewData)
Model = // set the model
;
【讨论】:
非常感谢,我也想知道,在 filter Model = testModel @zt9788,OnActionExecuting
在动作之前运行,你还没有任何模型。
如果过滤器扩展了 HandleErrorAttribute 并且异常在 Action 中抛出。能拿到Model吗?【参考方案3】:
来自 asp.net mvc 源,他们只是在视图数据中设置模型。 http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Controller.cs
protected internal virtual ViewResult View(string viewName, string masterName, object model)
if (model != null)
ViewData.Model = model;
return new ViewResult
ViewName = viewName,
MasterName = masterName,
ViewData = ViewData,
TempData = TempData,
ViewEngineCollection = ViewEngineCollection
;
【讨论】:
【参考方案4】:您可以修改过滤器上下文,并设置视图、模型、视图数据以及您想要的任何内容。您必须考虑一些事情:
// You can specify a model, and some extra info, like ViewBag:
ViewDataDictionary viewData = new ViewDataDictionary
Model = new MyViewModel
ModelProperty = ...,
OtherModelProperty = ...,
...
;
// You can take into account if it's a partial or not, to return a View
// or Partial View (casted to base, to set the remaining data):
ViewResultBase result = filterContext.IsChildAction
? new PartialViewResult()
: (ViewResultBase) (new ViewResult());
// Set the remaining data: Name of the View, (if in Shared folder) or
// Relative path to the view file with extension, like "~/Views/Misc/AView.cshtml"
result.ViewName = View;
result.ViewData = viewData; // as defined above
// Set this as the result
filterContext.Result = result;
这样,您的视图将根据需要接收模型。
【讨论】:
【参考方案5】:你可以从 filtercontext 中获取控制器,然后在控制器上使用 View 方法,像这样:
filterContext.Result = (filterContext.Controller as Controller).View(model);
【讨论】:
以上是关于如何在请求过滤器中的 ViewResult 上设置视图模型?的主要内容,如果未能解决你的问题,请参考以下文章
params ViewResult[] 将相同的模型应用于作为参数传递的所有 ViewResult 实例