首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >`View`方法中更具体的参数类型

`View`方法中更具体的参数类型
EN

Stack Overflow用户
提问于 2020-07-16 20:48:09
回答 2查看 63关注 0票数 0

关于专业核心的最受欢迎的书籍之一是亚当·弗里曼的“专业ASP.NET核心3”。

在第7-11章中,他构建了一个示例应用程序SportsStore。

HomeControllerIndex方法显示了一个产品列表:

下面是Index方法:

代码语言:javascript
运行
复制
public ViewResult Index(int productPage = 1)
   => View(new ProductsListViewModel {
       Products = repository.Products
           .OrderBy(p => p.ProductID)
           .Skip((productPage - 1) * PageSize)
           .Take(PageSize),
       PagingInfo = new PagingInfo {
           CurrentPage = productPage,
           ItemsPerPage = PageSize,
           TotalItems = repository.Products.Count()
       }
   });

与此方法对应的视图文件是Views\Home\Index.cshtml。此文件的顶部有以下行:

代码语言:javascript
运行
复制
@model ProductsListViewModel

所以视图需要一个ProductsListViewModel类型的对象。但是,在Visual Studio中,IntelliSense将View显示为需要object类型的参数

令我惊讶的是,这里的View没有显示为期望ProductsListViewModel类型的对象。因为它被设置为接受object类型的参数,所以我们实际上可以传入一些无意义的值:

代码语言:javascript
运行
复制
public ViewResult Index(string category, int productPage = 1) =>
    View(10);

并且项目仍然会被编译!

有没有办法让View实际上只接受视图文件中指定的模型类型?也就是说,在这种情况下,设置使View只接受ProductsListViewModel

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2020-07-17 00:04:44

通过使用泛型,我完成了以下操作。

代码语言:javascript
运行
复制
   //This is the Base class for every model must inherit.
   public class EntityModel
    {
        public int ID { get; set; }
    }

 //Model / view model must inherit from   EntityModel
 public class EmployeeModel : EntityModel
{
    public string Name { get; set; }
}

创建一个仅接受EntityModel或其派生类的新ViewController。将视图及其重载方法标记为过时,以便只能使用实体模型调用作为参数。另外,如果有人使用它,请限制他们使用它。因此抛出错误。

代码语言:javascript
运行
复制
public class ViewController<T> : Controller where T: EntityModel
{
    [Obsolete]
    public override ViewResult View()
    {
        return base.View(); 
    }

    [Obsolete]
    public override ViewResult View(object model)
    {
        throw new Exception("Use view method which accepts EntityModel");
    }

    [Obsolete]
    public override ViewResult View(string viewName)
    {
        throw new Exception("Use view method which accepts EntityModel");
    }

    [Obsolete]
    public override ViewResult View(string viewName, object model)
    {
        throw new Exception("Use view method which accepts EntityModel");
    }

    public new ViewResult View(T model)
    {
        return base.View(model);
    }
}

使用家庭控制器中新创建的ViewController。

代码语言:javascript
运行
复制
public class HomeController : ViewController<EmployeeModel>
{

    public IActionResult Index()
    {

        EmployeeModel emp = new EmployeeModel();
        emp.ID = 1;
        emp.Name = "Satish Pai";
        return View(emp);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-07-17 03:36:59

我不认为有办法捕捉任何错误的视图模型在编译时传递到视图中!

问题所在

视图与您在顶部声明的视图模型是强类型的,因此它知道要进入哪个模型,但控制器不知道您希望它返回到哪个视图……

默认情况下,控制器将返回与该方法同名的视图,但您可以更改该默认设置,甚至可以将视图的名称作为字符串参数传递给某个View()重载:

代码语言:javascript
运行
复制
public IActionResult Index(string category, int page = 1)
{
    ...
    return View("OutOfStock", vm);
}

现在,Visual Studio不知道您希望控制器构建哪个视图模型并将其传递给视图。事实上,Visual Studio甚至不知道我想要返回什么视图。即使在我把"OutOfStock“作为视图名称之后,Visual Studio甚至不知道视图是否存在……

使用泛型

@Satish的解决方案确实很有趣,但它假设您只为一个控制器使用一个单一视图模型,通常情况并非如此。通常,对于不同的操作,您会有不同的视图模型。

如果泛型是可行的,我建议把它放在动作上,而不是放在控制器上:

代码语言:javascript
运行
复制
public abstract class BaseController : Controller
{
    public ViewResult View<T>(T viewModel)  where T : new()
    {
        return View(viewModel);
    }
}

然后你可以像这样在控制器中使用它:

代码语言:javascript
运行
复制
public class ProductController : BaseController
{
    public IActionResult Index(string category, int page = 1)
    {
        var vm = new ProductListViewModel
        {
            ...
        };
    
        return View<ProductListViewModel>(vm);
        
        // This would give you the compile time error!
        // return View<ProductListViewModel>(10);
    }
}

但是为什么呢?这样做的意义是什么?作为开发人员,您必须知道ProductListViewModel无论如何都是要传递的正确视图模型。只有当有初级或新员工正在处理您的代码,而不检查返回的视图所要求的视图模型时,这样的事情才会有帮助?

也许吧?

现在,我知道像Resharper这样的工具也许能够在编译时帮助并捕捉不匹配的情况。

另外,编写关于控制器中返回的方法的单元测试可能会有所帮助?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62935070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档