Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该为MVC使用对象还是视图模型,或者两者都使用?_C#_Asp.net Mvc - Fatal编程技术网

C# 我应该为MVC使用对象还是视图模型,或者两者都使用?

C# 我应该为MVC使用对象还是视图模型,或者两者都使用?,c#,asp.net-mvc,C#,Asp.net Mvc,我正在学习MVC。我有一个使用webforms开发的应用程序,我正在移植它,但我遇到了一点障碍 我也在使用实体框架 目前,我的模型表示数据库表。通常,我的控制器将从表中获取数据,并创建一个将传递给视图的视图模型 我有点困惑的是,当我需要基于模型数据进行一些转换并将其传递给视图时,我不确定转换发生在哪里 在webforms应用程序中,我将有一个类,我将从中创建新对象,然后所有的转换都将在那里发生。一个很好的例子是用户;数据库将存储名字和姓氏,并且对象将具有在构造函数中设置的FullName的公共属

我正在学习MVC。我有一个使用webforms开发的应用程序,我正在移植它,但我遇到了一点障碍

我也在使用实体框架

目前,我的模型表示数据库表。通常,我的控制器将从表中获取数据,并创建一个将传递给视图的视图模型

我有点困惑的是,当我需要基于模型数据进行一些转换并将其传递给视图时,我不确定转换发生在哪里

在webforms应用程序中,我将有一个类,我将从中创建新对象,然后所有的转换都将在那里发生。一个很好的例子是
用户
;数据库将存储名字和姓氏,并且对象将具有在构造函数中设置的
FullName
的公共属性

我读过一些关于瘦控制器/胖模型的相互矛盾的讨论,反之亦然。我只是有点困惑。根据微软文档,瘦控制器和胖模型似乎是推荐的方式,但它们并没有给出实际的例子

举个例子:

public class UserEntity
{
    public int ID { get; set; }
    public string FName { get; set; }
    public string LName { get; set; }
}

public class UserController : Controller {
{
    protected readonly DBContext _context;
    public UserController(DBContext context)
    {
        _context = context;
    }

    public IactionResult Index(int id)
    {
        var _user = _context.Users.Single(u => u.id == id);

        UserViewModel _viewModel = new UserViewModel
        {
            FirstName = _user.FName,
            LastName = _user.LName,
            FullName = ""
        };

        return View(_viewModel)

    }

}
如果以上不是完美的,请原谅——我只是写了一个简单的例子。它并不打算成为完美的代码

对于Fullname,我将把提供这些信息的逻辑放在哪里。现在,我意识到,在这个非常简单的例子中,我可以很容易地得到全名。但让我们假设这是一个比串联两个字符串复杂得多的操作。在哪里放置
GetFullName
方法


我的模型中会有方法吗?我会创建一个
User
类并传递返回的模型数据吗?有一个单独的类库怎么样?如果是后者,我会将
User
对象传递给我的视图模型,还是从创建的
User
对象设置视图模型属性?

实体框架通常将业务表示与关系数据实现相关联。这种方法非常适合于业务模型的清晰表示。但是在一个网页中,直接表示往往不能在应用程序结构中很好地转换或发挥作用

他们最终通常实现一个称为模型-视图-模型(MVVM)的模式。基本上,将单个或多个实体转换为单个对象,并作为模型放置在视图中。例如,这种转换解决了大量问题

public class UserModel
{
     private readonly UserEntity user;

     public UserModel(UserEntity user) => this.user = user;

     public string Name => $"{user.First} {user.Last}";
}
实体和数据库反映了一个分开的用户名,第一个和最后一个。但是,将实体放置到另一个结构中,可以构建一个代表性的模型来附着视图。显然,这是一个简单的示例,但这种方法通常用于更透明的表示,因为视图和数据库可能并不直接彼此完全一致

所以现在你的控制器会沿着这些路线做一些事情

public class UserController : Controller
{
     public IActionResult Index(int id) => View(new UserModel(new UserService().GetUserInformation(id)));
}
我完成了回答,我想用一个例子来说明一个评论表达得很好


ViewModels就是这个名字所暗示的。特定视图的模型。他们 不是域实体或DTO。如果方法对视图的 模型,将其放置在ViewModel中的一个好位置。验证, 通知、计算属性等都是很好的候选项。A. 另一方面,抵押计算器将是一个糟糕的选择- 这是一项商业功能——7分钟前的Panagiotis Kanavos


如果您不想让viewmodel拥有任何方法,您可以编写扩展方法。这一方法本身就是错误的——可以设置一个参数,让控制器映射,或者让viewmodel拥有一个构造函数来获取它需要的模型。最重要的是保持与层的一致性—选择任意一种方式并使其在应用程序中保持一致。ViewModels就是其名称的含义。特定视图的模型。它们不是域实体或DTO。如果某个方法对视图的模型有意义,那么将其放在ViewModel中是一个很好的位置。验证、通知、计算属性等都是很好的候选者。另一方面,抵押贷款计算器将是一个糟糕的选择——这是一个生意functionality@gin93r如果方法只处理ViewModel,那么在ViewModel中放置方法没有什么错。你必须更加努力specific@gin93r
记住,在设计#WebAPI时,您的数据模型不是您的对象模型不是您的资源模型不是您的消息模型
就结构而言,我会有一个
/Entities/UserEntity.cs
和一个
/Models/UserModel.cs
?我想这可能就是我的困惑所在。Panagiotis Kanavos引用的关于数据模型的另一条评论不是对象模型。本质上,我创建表示该数据库的实体模型,然后创建进行转换等的对象模型。我的控制器将对象模型传递给视图。我理解正确吗?是的,您的实体是一个对象/数据模型,视图将在其中访问对象/视图模型。您的数据模型并不总是转换为视图模型,因此您需要将数据模型转换为有效的视图模型。好的,我想我现在明白了。@gin93r数据模型是数据库的数据表示,视图模型是页面的数据表示。数据模型并不总是适合视图模型的应用程序,因为有时您必须更改数据模型或组合多个数据模型以生成有效的视图模型来表示页面意图。希望我对术语的更改能为您澄清。