繁体   English   中英

ViewModel的POST和DomainModel上的验证

[英]POST of ViewModel and Validation on DomainModel

我一直在使用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验证而不是Data Annotations,因为它更灵活,并且可以与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上发布错误?

如果可能的话,我想看一些如何做的代码。

感谢大家!

不知道为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应用程序也没有任何重要性=>您可以使用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))
{
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM