ViewModel 如何在 MVC 中工作

本文关键字:工作 MVC ViewModel | 更新日期: 2023-09-27 18:32:33

我真的不知道如何在MVC中使用ViewModel。 假设我有两个简单的域模型:

public class Customer
{
    public int Id { get; set; }
    public string CustomerName { get; set; }
}
 public class Order
{
    public int Id { get; set; }
    public string ProductName { get; set; }
}

现在我的目标是创建一个视图模型,该模型显示(组合)要显示到视图的客户名称和产品名称。 我很困惑在视图模型中包含什么来完成此操作。我是否像这样使用与域模型相同的属性名称?

public class MyViewModel
{
    public string CustomerName { get; set; }
    public string ProductName { get; set; }
}

视图模型如何知道属性来自两个不同的类?还是我不正确地形成了我的视图模型?

ViewModel 如何在 MVC 中工作

正如我所看到的,你在这里有一个更大的设计问题。

假设您只需要在UI上显示CustomerNameProductName。那么,只需将这两个添加到您的 ViewModel 类中,您就可以开始了,正如您所描述的那样。

public class MyViewModel
{
    public string CustomerName { get; set; }
    public string ProductName { get; set; }
}

获取两个变量中的数据不是问题:

Customer customer = service.GetCustomer();
Product product = service.GetProduct()

现在您已经拥有了所需的一切,您只需设置数据并将其传递给视图即可。

MyViewModel viewModel = new MyViewModel();
viewModel.CustomerName = customer.CustomerName;
viewModel.ProductName = product.ProductName;

它始终取决于您需要在 UI 上显示的内容,并且只发送您需要的内容,仅此而已。您不需要只有一个模型在应用程序中到处传递,BusinessDataAccessUI 。如果你真的需要,你可以有一些定制的东西。

您必须在ViewModel中自己设置它,作为模板,它可能看起来像这样:

public class MyViewModel
{
    public string CustomerName { get; set; }
    public string ProductName { get; set; }
    public void GetCustomerName(int customerId) 
    {
       CustomerName = CustomerServiceLayer.GetCustomerName(customerId);
       // CustomerService Layer (I.e. a repository that contains this info;
    }
    public void GetProductName(int productId) 
    {
       ProductName = ProductServiceLayer.GetProductName(productId); 
       // ProductService Layer (I.e. a repository that contains this info;
    }
}

然后,您将拥有另外两个服务层(ProductServiceLayerCustomerServiceLayer),它们与数据库/存储库对话以获取所需的信息。 然后,该信息将返回到视图(通过 ViewModel)并显示给用户。

或者,您可以将CustomerProduct对象直接传递到 ViewModel(通过构造函数)中。

public class MyViewModel 
{
    public Customer MyCustomer { get; set; }
    public Product MyProduct { get; set; }
    public MyViewModel(ICustomer customer, IProduct product) 
    {
       MyCustomer = customer;
       MyProduct = product;
    }
}

这里的缺点是您在视图中公开整个CustomerProduct类。

您可以这样做,但您通常会在 get 操作中的渲染上构建视图模型,然后将该视图模型的一部分提交回来并在发布操作中处理它。MVC 绑定在从窗体回发值后就会发挥作用。

我不会将业务逻辑放在视图模型中,而是使用管理器/服务在控制器中构建视图模型。

您也可以使视图模型具有复杂的模型类型作为这样的属性。

public class MyViewModel
{
    public Customer Customer { get; set; }
    public Product Product { get; set; }
}

ViewModel 显示您用来转到视图的模型。在控制器中,您将检索数据并将其传递给视图模型。

假设您的视图中有一个复选框,该复选框表示金牌客户:不适合更改域模型以添加此信息,并且使用 Viewbag 和 Viewdata(恕我直言)弄脏代码不是一个好做法。

因此,您可以创建一个包含所需所有信息的模型或模板。在我们的例子中:

public class MyViewModel
{
    public string CustomerName { get; set; }
    public string ProductName { get; set; }
    public boolean IsGoldCustomer { get; set; }
}

通常,您必须将模型转换为ViewModel和viceversa,以便将数据从"DOMAIN模型"传递到"VIEW模型"。