我一直在使用asp.net mvc和nhibernate开发一个Web应用程序。我正在尝试遵循DDD的一些原则和Asp.Net MVC的最佳实践。我的问题是关于用VIewModel清理POST。为了说明我的问题,请在我的域模型上查看此实体:
[Validator(typeof(EntityValidator))]
public class MyEntity {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Email { get; set; }
public virtual decimal UnitPrice { get; set; }
public virtual Category Category { get; set; }
public MyEntity() { }
}
它与nhibernate映射并且工作正常。为了验证,我正在使用Fluent验证,我有这个类:
public class EntityValidator : AbstractValidator<MyEntity>
{
protected IEntityRepository EntityRepository { get; set; }
public EntityValidator(IEntityRepository entityRepository) { // injected by a IoC Container
this.EntityRepository = entityRepository;
RuleFor(x => x.Name).NotEmpty();
RuleFor(x => x.UnitPrice).GreaterThan(0);
RuleFor(x => x.Category).NotNull();
RuleFor(x => x.Email).NotEmpty().EmailAddress().Must((entity, email) => EntityRepository.ExisteEmail(entity.Email));
}
}
我更倾向于使用Fluent验证而不是数据注释,因为它更灵活,并且可以与Asp.Net MVC一起使用。它配置和工作正常。所以,我有这个ViewModel:
public class EntityViewModel {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public decimal UnitPrice { get; set; }
public int IdCategory { get; set; }
}
现在,我正在尝试使用ViewModel在某些操作(如INSERT,UPDATE)中清理我的实体,因为我正在使用nhibernate。我
不知道为viewmodel创建验证是否正确,因为我在我的实体上有自己的验证,所以,我该怎么办呢?你过得怎么样?
将您的实体发布给要保留的操作吗?如何验证它并在MVC的ModelState上发布错误?
如果有可能的话,我想看一些如何做的代码。
谢谢大家!
答案 0 :(得分:11)
不知道为viewmodel创建验证是否正确,因为 我在我的实体上有自己的,所以,我该怎么做?
就个人而言,我为我的视图模型定义了流畅的验证器。它们包含对所需属性,格式等简单事物的验证规则......以便可以直接在视图上处理这些验证。
域模型还可以包含验证,但这些验证将是业务验证。以下是POST控制器操作的常用流程:
[HttpPost]
public ActionResult Insert(UpdateViewModel viewModel)
{
if (!ModelState.IsValid)
{
// the surface validation on our view model failed => redisplay the view so
// that the user can fix errors
return View(viewModel);
}
// at this stage the view model is valid => we can map it back to a domain model
// I use AutoMapper for this:
var domainModel = Mapper.Map<UpdateViewModel, DomainViewModel>(viewModel);
// then we pass the domain model to the service layer for processing:
string error;
if (!_service.Insert(domainModel, out error))
{
// something wrong happened on the service layer
ModelState.AddModelError("key", error);
return View(viewModel);
}
// everything went fine
return RedirectToAction("Success");
}
从这个例子中可以看出,我们将处理委托给服务层。实现此服务的方式不符合ASP.NET MVC应用程序的任何兴趣或含义。您可能正在使用NHibernate,Entitiy Framework,调用其他一些服务,您可以想到的任何事情,我们应该关注的是我们正在处理我们的域模型以备处理,并报告我们返回错误(如果有的话)。在服务层上处理验证的方式对于ASP.NET MVC应用程序来说也是不重要的=&gt;你可以使用Castle Validator,Fluent Validation,Data Annotations,等等......
就映射而言,如果您正在更新现有的域实体,则可能会有一个额外的步骤。在这种情况下,视图模型可能不包含域模型的所有属性,因为在此特定视图中,例如,我们仅允许编辑某些属性。在这种情况下,流程将是这样的:
// Fetch the original domain model we want to update
var domainModel = _service.Get(viewModel.Id);
// Update only the properties that are present on the view:
Mapper.Map<UpdateViewModel, DomainViewModel>(viewModel, domainModel);
// Pass to the service layer for processing:
string error;
if (!_service.Update(domainModel, out error))
{
...
}