【问题标题】:How to get the Model from an ActionResult?如何从 ActionResult 中获取模型?
【发布时间】:2011-01-05 11:29:52
【问题描述】:

我正在编写一个单元测试并调用这样的操作方法

var result = controller.Action(123);

结果是ActionResult,我需要以某种方式获取模型,有人知道该怎么做吗?

【问题讨论】:

    标签: asp.net-mvc unit-testing


    【解决方案1】:

    在我的 ASP.NET MVC 版本中,Controller 上没有 Action 方法。但是,如果您的意思是 View 方法,那么您可以通过以下方式对结果进行单元测试,以确保结果包含正确的模型。

    首先,如果你只从一个特定的Action返回ViewResult,将方法声明为returning ViewResult instead of ActionResult

    例如,考虑这个索引操作

    public ViewResult Index()
    {
        return this.View(this.userViewModelService.GetUsers());
    }
    

    您可以像这样轻松访问模型

    var result = sut.Index().ViewData.Model;
    

    如果您的方法签名的返回类型是 ActionResult 而不是 ViewResult,则需要先将其强制转换为 ViewResult。

    【讨论】:

    • 最好转换成 ViewResultBase (这包括部分);也(很少)可以考虑使用反射来检查 ViewData/Model 属性并获取模型(以防有未知的视图结果类型)。
    • 关于 ViewResultBase 的观点很好,但你为什么要在这样的事情上使用反射?
    【解决方案2】:

    我们将以下部分放在 testsbase.cs 中,以便在测试中使用类型化模型

    ActionResult actionResult = ContextGet<ActionResult>();
    var model = ModelFromActionResult<SomeViewModelClass>(actionResult);
    

    ModelFromActionResult...

    public T ModelFromActionResult<T>(ActionResult actionResult)
    {
        object model;
        if (actionResult.GetType() == typeof(ViewResult))
        {
            ViewResult viewResult = (ViewResult)actionResult;
            model = viewResult.Model;
        }
        else if (actionResult.GetType() == typeof(PartialViewResult))
        {
            PartialViewResult partialViewResult = (PartialViewResult)actionResult;
            model = partialViewResult.Model;
        }
        else
        {
            throw new InvalidOperationException(string.Format("Actionresult of type {0} is not supported by ModelFromResult extractor.", actionResult.GetType()));
        }
        T typedModel = (T)model;
        return typedModel;
    }
    

    使用索引页面和列表的示例:

    var actionResult = controller.Index();
    var model = ModelFromActionResult<List<TheModel>>((ActionResult)actionResult.Result);
    

    【讨论】:

    【解决方案3】:

    考虑 a = ActionResult;

    ViewResult p = (ViewResult)a;
    p.ViewData.Model
    

    【讨论】:

    • 这是一个无效的演员表。
    【解决方案4】:

    这有点作弊,但在 .NET4 中这样做是一种非常简单的方法

    dynamic result = controller.Action(123);
    
    result.Model
    

    今天在单元测试中使用了这个。可能值得进行一些健全性检查,例如:

    Assert.IsType<ViewResult>(result); 
    Assert.IsType<MyModel>(result.Model);
    
    Assert.Equal(123, result.Model.Id);
    

    如果结果将是视图或部分结果,则您可以跳过第一个,具体取决于输入。

    【讨论】:

      猜你喜欢
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      相关资源
      最近更新 更多