如何在请求过滤器中的 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 上设置视图模型?的主要内容,如果未能解决你的问题,请参考以下文章

索引ViewResult在从ajax调用回调后不重新呈现

params ViewResult[] 将相同的模型应用于作为参数传递的所有 ViewResult 实例

如何在 OpenUI5 表列上设置过滤器以触发过滤

如何有效地设置http body请求?

在 ASP.NET MVC 3 中创建基于平台显示不同视图的自定义 ViewResult

根据打字稿中的请求参数设置猫鼬的查询过滤器