C# 为HttpGet和HttpPost设计包含显示数据和绑定数据的ViewModel的最佳实践
我已经阅读StackOverflow有一段时间了,现在是我的第一篇文章的时间了: 我目前正在使用C#/ASP.NET Core 3.1。为HttpGet和HttpPost设计包含显示数据和绑定数据的ViewModel的最佳实践是什么。我发现了一些关于保持显示和绑定数据分离或不分离的讨论,但没有任何示例。在HttpPost上使用相同的ViewModel(没有绑定属性)的问题是,显示数据引用会获得无效的modelstate,因为它们在传入模型中当然为null 我通常倾向于使用以下精简的代码。继承是要走的路还是其他模式?或者,对于非绑定数据,最好将所有内容都放在具有绑定属性的视图模型中 谢谢大家C# 为HttpGet和HttpPost设计包含显示数据和绑定数据的ViewModel的最佳实践,c#,asp.net-core,C#,Asp.net Core,我已经阅读StackOverflow有一段时间了,现在是我的第一篇文章的时间了: 我目前正在使用C#/ASP.NET Core 3.1。为HttpGet和HttpPost设计包含显示数据和绑定数据的ViewModel的最佳实践是什么。我发现了一些关于保持显示和绑定数据分离或不分离的讨论,但没有任何示例。在HttpPost上使用相同的ViewModel(没有绑定属性)的问题是,显示数据引用会获得无效的modelstate,因为它们在传入模型中当然为null 我通常倾向于使用以下精简的代码。继承是要
public class CMyBindModel
{
public int ProductQuantity ( get; set; } // Binding Data
// Other Binding properties ...
}
public class CMyViewModel : CMyBindModel
{
public string ProductName ( get; set; } // Display Data
// Other Display properties ...
}
Cart.cshtml
@模型CMyViewModel
@Model.ProductName
更新
在HttpPost上使用相同的ViewModel(不带绑定属性)的问题是,显示数据引用获得无效的modelstate,因为它们在传入模型中当然为null
通过使用相同的视图模型(这里是CMyViewModel
),您可以通过在判断ModelState.IsValid
之前从ModelState
中删除字段来克服验证错误
请参阅我的简单演示:
型号:
public class CMyViewModel
{
[Required]
public int ProductQuantity { get; set; } // Binding Data
// Other Binding properties ...
[Required]
public string ProductName{get; set; } // Display Data
// Other Displaying properties ...
}
行动:
public void RemoveDisplayingDataValidation()
{
ModelState.Remove("ProductName");
//remove other Displaying properties' validation
}
[HttpPost]
public IActionResult Cart(CMyViewModel viewModel)
{
RemoveDisplayingDataValidation();
if (ModelState.IsValid)
{
SetProductQuantity (viewModel.ProductQuantity) ;
return RedirectToAction("Cart");
}
CMyViewModel viewModel = BuildViewModel () ;
return View(viewModel);
}
指
此外,克里斯托夫·吕特仁(Christoph Lütjen)提出的分别使用两种模型的建议也会奏效
在HttpPost上使用相同的ViewModel(不带绑定属性)的问题是,显示数据引用获得无效的modelstate,因为它们在传入模型中当然为null
通过使用相同的视图模型(这里是CMyViewModel
),您可以通过在判断ModelState.IsValid
之前从ModelState
中删除字段来克服验证错误
请参阅我的简单演示:
型号:
public class CMyViewModel
{
[Required]
public int ProductQuantity { get; set; } // Binding Data
// Other Binding properties ...
[Required]
public string ProductName{get; set; } // Display Data
// Other Displaying properties ...
}
行动:
public void RemoveDisplayingDataValidation()
{
ModelState.Remove("ProductName");
//remove other Displaying properties' validation
}
[HttpPost]
public IActionResult Cart(CMyViewModel viewModel)
{
RemoveDisplayingDataValidation();
if (ModelState.IsValid)
{
SetProductQuantity (viewModel.ProductQuantity) ;
return RedirectToAction("Cart");
}
CMyViewModel viewModel = BuildViewModel () ;
return View(viewModel);
}
指
此外,Christoph Lütjen关于分别使用两个模型的建议也会起作用。您的第一个模型描述了请求的外观。视图模型描述了渲染视图所需的内容。两者看起来可能相似,但它们显然负责不同的事情。也就是说:我将使用两个类。没有继承权。如果您需要视图中请求的零件,请复制属性。-只有我的5美分。这里有一些策略。我经常使用您概述的继承方法,尤其是当每个视图模型特定于底层绑定模型时。例如,如果一个
用户
实体有一个只读的DateJoined
属性,应该显示该属性,这是用户视图模型
的一个很好的用例。对于视图模型具有跨绑定模型使用的一组公共属性的区域,我使用具有通用绑定模型属性的通用视图模型。它包含常见的只读元数据和共享用户界面元素,如PageTitle
,LastModified
。非常感谢大家的建议。是的,我想不同的策略在不同的情况下是有用的(继承、单独的模型、ModelState.Remove等等)。纯粹主义者可能不同意继承解决方案,因为大多数情况下,它不是isA关系。我很少使用两个单独的模型,但最近我有一个模型,其中包含一个商店类列表,其中包含一个要显示的产品类列表,每个类中都有一些绑定属性—两个单独的视图和绑定模型解决了我的问题。干杯。您的第一个模型描述了请求的外观。视图模型描述了渲染视图所需的内容。两者看起来可能相似,但它们显然负责不同的事情。也就是说:我将使用两个类。没有继承权。如果您需要视图中请求的零件,请复制属性。-只有我的5美分。这里有一些策略。我经常使用您概述的继承方法,尤其是当每个视图模型特定于底层绑定模型时。例如,如果一个用户
实体有一个只读的DateJoined
属性,应该显示该属性,这是用户视图模型
的一个很好的用例。对于视图模型具有跨绑定模型使用的一组公共属性的区域,我使用具有通用绑定模型属性的通用视图模型。它包含常见的只读元数据和共享用户界面元素,如PageTitle
,LastModified
。非常感谢大家的建议。是的,我想不同的策略在不同的情况下是有用的(继承、单独的模型、ModelState.Remove等等)。纯粹主义者可能不同意继承解决方案,因为大多数情况下,它不是isA关系。我很少使用两个单独的模型,但最近我有一个模型,其中包含一个商店类列表,其中包含一个要显示的产品类列表,每个类中都有一些绑定属性—两个单独的视图和绑定模型解决了我的问题。干杯