【问题标题】:multiple models in a view .NET Core一个视图中的多个模型 .NET Core
【发布时间】:2019-06-03 23:07:31
【问题描述】:

我使用的是 Asp.net core 2.2。在 A 视图中,我想添加两个模型并遍历它们,但我不知道该怎么做。 这是我的 ProductCategory 域模型

public class ProductCategory
{
    public int ProductCategoryID { get; set; }
    public string ProductCategoryName { get; set; }
}

这是我的产品领域模型

public class Product
{
     public int ProductID { get; set; }
     public string ProductName { get; set; }
     public int ProductCategoryID{ get; set; }

     [ForeignKey("ProductCategoryID")]
     public virtual ProductCategory ProductCategory{ get; set; }
}

现在我想将它们添加到一个视图(或一个视图和多个部分视图)中,如下所示:

正如this article 建议的那样,我不想在视图模型/视图中使用域模型。您如何解决这个问题?起初我认为首先 MyView 加载 ProductCategories 然后不同的局部视图加载产品是个好主意。但是这样我应该对每个部分的模型进行硬编码。我想让它动态化,因此当管理员添加类别及其产品时,控制器会将它们动态添加到 MyView。 如果您在理解我的想法时遇到问题,请告诉我按照您的意愿提供您需要的信息。因为我不知道这篇文章的必要信息是什么。

所以当我设计 MyView 时,我可以做这样的事情(只是我想做的一个模拟和抽象的想法。)

@foreach(var p in model.ProductCategory)
{
    <div>
       <h1>p.ProductTypeName</h1>
        @foreach(var c in model.Product)
        { 
           c.ProductName
        }

    </div>


}

【问题讨论】:

  • 首先是 ProductCategories 的列表,然后是每个 productCtegories 的产品列表。
  • 在你的模型中有数据库依赖会使得分离应用层变得非常困难。就像提示一样。

标签: c# asp.net asp.net-core


【解决方案1】:

我不想在视图模型/视图中使用域模型

为此目的创建一个视图模型或 DTO,并在您的视图中使用它。作为一种好的做法,您应该在您的实际域实体/模型和用于您的视图以显示数据的模型之间保持隔离。

public class MyViewModel
{
  public IEnumerable<Product> Products {get; set;}
  public ProductCategory ProductCategory {get; set;} 
}

发布的示例只是一个简单的示例。您可以根据需要对其进行自定义(我的意思是您要显示的特定字段),并且仅在您的视图模型中使用这些字段。不仅如此,现在您还可以在视图模型中使用 DataAnnotations,例如

public class MyViewModel
{
  [Display(Name="My Products")]
  public IEnumerable<Product> Products {get; set;}
  public ProductCategory ProductCategory {get; set;} 
}

【讨论】:

  • 但您在 MyViewModel 中使用域模型(产品和 ProductCategory)。链接的文章说“您的 API 和视图模型不应引用域模型”
  • @ArianShahalami 查看更新的答案。链接的答案并不意味着根本不使用域实体,而是不直接将其用于查看目的
  • 使用命名空间,我通常有 Dbos.Product 和 Dtos.Product 或 ViewModels.Product,它们就是它们,Product,只是用途不同
  • 好的,这是个好主意。如何制作ProductViewModelProductCategory ViewModel 并将它们传递给MyViewModel 而不是传递域?这可以接受吗?我的意思是它是标准的吗?
  • @ArianShahalami 是的,只要它更容易、更易于维护、更有意义,你就可以;我不会太担心标准
【解决方案2】:

您需要一个ViewModel,如下所示:

public class MyPageProductVM 
{
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public int ProductCategoryID { get; set; }
}
public class MyPageProductCategoryVM 
{
    public int ProductCategoryID { get; set; }
    public string ProductCategoryName { get; set; }

    public IList<MyPageProductVM> { get; set; }
}

您的视图现在可以使用IList&lt;MyPageProductCategoryVM&gt; 作为模型。您当然可以继续创建另一个 MyPageVM 类来包含列表和任何其他字段,并使视图使用 MyPageVM 作为模型。

我相信这不是您想要的,但为了完整起见,另一种选择是非规范化域模型:

public class MyPageProductVM 
{
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public int ProductCategoryID { get; set; }

    public int ProductCategoryID { get; set; }
    public string ProductCategoryName { get; set; }
}

您可以使用 AutoMapper 或 Mapster 之类的库将领域模型与视图模型进行映射。

【讨论】:

  • 我认为您提供的第二种解决方案更好。因为我在某处读到 ViewModel 是一个模型,它提供了视图所需的一切。在第一个解决方案中,MyPageProductVM 不是 ViewModel,因为我们不在视图中使用它。这有点像 DTO。我说的对吗?
  • @ArianShahalami ViewModels DTO(用于将数据传输到视图)。所以MyPageProductVM 是 DTO,MyPageProductCategoryVM 也是。理想情况下,您希望 ViewModel 反映数据在视图中的布局方式。所以我会根据你分享的图片选择第一个选项。如果视图重复了 ProductCategoryName/ProductCategoryID 字段,我会选择选项 2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 2012-01-04
相关资源
最近更新 更多