我正在从Pro ASP.NET MVC 4这本书中学习ASP.NET MVC (顺便说一下,我喜欢这个版本).
我还在开头的章节中,它向我展示了System.ComponentModel.DataAnnotations
命名空间属性,如何使用这些注释来模拟我的模型类,然后如何使用它们来检查模型是否有效(ModelState.IsValid
在Controller
)中.
例如:
public class GuestResponse { [Required(ErrorMessage = "Please enter your name"] public string Name { get; set; } } ... public ViewResult RsvpForm(GuestResponse guestResponse) { if(ModelState.IsValid) { return View("Thanks", guestResponse); } }
有几件事让我感到不安.
为什么我想要在我的域模型中散布一堆属性?我喜欢我的域模型纯粹而且没有任何特定于实现的东西,并且任何真实世界模型都太复杂而不能像这样使用声明性验证.
ErrorMessage
验证属性的参数是否有些View
相关?不是那样的东西属于UI
图层吗?例如...如果由于空间限制我想要移动版本而不是说"请输入你的名字"说"需要姓名"怎么办?但这是我的模特!
为什么我要用来ModelState.IsValid
确定模型的状态?模特不应该告诉我吗?据我所知,ModelState
是利用了的DataAnnotations
那个属性是在我的模型,但是这似乎也只是非常简单的型号.更复杂的模型甚至可能没有有效/无效状态,它可能只有各种阶段和状态.我在这里散步,但我不喜欢以声明的方式说出是什么让我的模型有效或无效.
任何建议,保证或验证这些想法将不胜感激.
以下是我对你问题的回答:
1)为什么我要在整个域模型中散布一堆属性?我喜欢我的域模型纯粹而且没有任何特定于实现的东西,并且任何真实世界模型都太复杂而不能像这样使用声明性验证.
你绝对不希望这样.您想要的是拥有专为视图目的而设计的视图模型.这个视图模型将包含数据注释,而不是您的域模型.然后,控制器将在域模型和视图模型之间进行映射,并将视图模型传递给视图.将视图模型视为一个或多个域模型的投影.为了简化您的域和视图模型之间的映射,您可以结帐AutoMapper
.基本的经验法则是视图不应该知道您的域模型.
2)验证属性的ErrorMessage参数是否有些与View相关?这样的东西不属于UI层吗?例如...如果由于空间限制我想要移动版本而不是说"请输入你的名字"说"需要姓名"怎么办?但这是我的模特!
完全同意你的看法.这就是为什么你应该有一个专门为视图目的而设计的视图模型类的原因.
3)为什么我要使用ModelState.IsValid来确定模型的状态?模特不应该告诉我吗?我知道ModelState正在使用我的模型中的DataAnnotations属性,但这似乎只适用于非常简单的模型.更复杂的模型甚至可能没有有效/无效状态,它可能只有各种阶段和状态.我在这里散步,但我不喜欢以声明的方式说出是什么让我的模型有效或无效.
我再次同意你的看法.声明性验证(例如你开箱即用的数据注释)对于Hello World类型的应用程序非常有用,但是一旦你开始用复杂的验证规则编写真实世界的应用程序,你很快就会意识到声明式方法根本不会削减芥末.因此我使用FluentValidation.NET
.它为您提供了非常漂亮和流畅的语法来表达任意复杂的验证规则,integrates easily with ASP.NET MVC
并允许unit test your validation rules
完全隔离.