你在哪里摆在asp.net MVC 3的验证? [英] Where do you put your validation in asp.net mvc 3?

查看:284
本文介绍了你在哪里摆在asp.net MVC 3的验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在asp.net mvc的一个共同推荐的做法是,的你不应该把你的商业模式,你的看法.. 而不是你应该建立具体到每个视图的ViewModels。

One common recommended practice in asp.net mvc is that you should not send your business models to your views.. instead you should create viewmodels specific to each view.

当做到这一点,你叫你的控制器ModelState.IsValid方法,则需要有效地检查视图模型的有效性,而不是业务对象。

When that is done and you call the ModelState.IsValid method in your controller you are effectively checking the validity of the viewmodel but not the business object.

什么是处理这个传统的方法呢?

What is the conventional approach to dealing with this?

public class Person
{
public int ID {get; set;};

[Required]
public string Name {get; set;}

[Required]
public string LastName {get; set;}

public virtual ICollection<Exam> Exams {get; set;}

}

public class PersonFormViewModel
{

public int ID {get; set;};    


[Required]
public string Name {get; set;}

[Required]
public string LastName {get; set;}

}

这正是我现在,但林若[必需]属性应该出现在这两种模式或仅视图模型或只是商业模式不清楚。

This is exactly what I have right now but Im not sure if the [Required] attribute should appear on both models or just the ViewModel or just the Business Model.

在这个问题上的任何提示都AP preciatedd。

Any tips on this issue are appreciatedd.

更多链接来支持我的主张是一种常见的很好的做法,始终使用视图模型。

More links to support my claim that it is a common good practice to always use view models.

<一个href=\"http://stackoverflow.com/questions/5128303/how-to-add-validation-to-my-pocotemplate-classes\">How审定添加到我的POCO(模板)班

http://blogs.msdn.com/b/simonince/archive/2010/01/26/view-models-in-asp-net-mvc.aspx

推荐答案

我的preference是做对视图模型的输入验证和的域模型业务验证

My preference is to do input validation on the view models, and business validation on the domain models.

在换句话说,任何数据注释,比如必填字段,长度验证,正则表达式等,应在你的视图模型完成,并添加到模型状态时出现错误。

In other words, any data annotations such as required fields, length validation, regex, etc should be done on your view models, and added to the model state when error occurs.

你可能不得不依赖不仅仅是一个形式更多的业务/领域的规则,所以你应该做的,无论是在领域模型(它们映射回后,再执行验证),或与服务层。

And you'll probably have business/domain rules that rely on more than just a "form", so you should do that either in the domain models (execute the validation after they're mapped back), or with a service layer.

所有我们的模型有一个名为验证的方法,之前坚持我们称之为的服务。他们抛出自定义异常,如果他们失败业务验证,这将会由控制器捕获并也添加到模型状态。

All our models have a method called "Validate", which we call in the services prior to persisting. They throw custom exceptions if they fail business validation, which gets caught by the controller and also added to the model state.

可能无法茶每个人的杯子,但它是一致的。

May not be everyone's cup of tea, but it's consistent.

业务验证的示例,根据要求:

下面是我们有一个域模型,再$ P $的一个例子psents一个通用的邮报(问题,照片,视频等):

Here's an example of a domain model we have, which represents a generic "Post" (question, photo, video, etc):

public abstract class Post
{
   // .. fields, properties, domain logic, etc

   public void Validate()
   {
      if (!this.GeospatialIdentity.IsValidForThisTypeOfPost())
         throw new DomainException(this, BusinessException.PostNotValidForThisSpatial.);
   }
}

您看到有,我检查,对业务规则,并抛出自定义异常。 DomainException 是我们的基础,我们有很多衍生的实现。我们有一个叫 BusinessException 的枚举,其中包含了我们所有的异常值。我们使用的枚举扩展方法提供基于资源的错误消息。

You see there, i am checking against business rules, and throwing custom exceptions. DomainException is our base, and we have many derived implementations. We have an enum called BusinessException, which contains values for all our exceptions. We use extension methods on the enum to provide the resource-based error message.

这是不是简单地对模型IM检查的领域,如所有职位都必须有一个主题,因为尽管这是域的一部分,它的输入验证首先,进而通过数据的注释上的处理视图模型。

This is not simply a field on the model im checking, e.g "All posts must have a subject", because although that is part of the domain, it's input validation first and foremost, and thus is handled via the data annotations on the view model.

现在,控制器:

[HttpPost]
public ActionResult Create(QuestionViewModel viewModel)
{
   if (!ModelState.IsValid)
     return View(viewModel);

   try
   {
      // Map to ViewModel
      var model = Mapper.Map<QuestionViewModel,Question>(viewModel);

      // Save.
      postService.Save(model); // generic Save method, constraint: "where TPost: Post, new()".

      // Commit.
      unitOfWork.Commit();

      // P-R-G
      return RedirectToAction("Index", new { id = model.PostId });
   }
   catch (Exception exc) 
   {
      var typedExc = exc as DomainException;

      if (typedExc != null)
      {
         // Internationalised, user-friendly domain exception, so we can show
         ModelState.AddModelError("Error", typedExc.BusinessError.ToDescription());
      }
      else
      { 
         // Could be anything, e.g database exception - so show generic msg.
         ModelState.AddModelError("Error", "Sorry, an error occured saving the Post. Support has been notified. Please try again later.");
      }
   }

   return View(viewModel);
}

因此​​,通过我们得到的保存方法上的服务的时候,该模型已通过的输入验证的。然后保存方法调用 post.Validate(),调用业务规则。

So, by the time we get to the "Save" method on the service, the model has passed input validation. Then the Save method calls post.Validate(), invoking business rules.

如果将引发异常时,控制器捕获它并显示消息。如果它获得通过保存方法和发生其他错误(90%的时间,它的实体框架,例如),我们展示的一般错误消息。

If an exception is raised, the controller catches it and displays the message. If it gets pass the Save method and another error occurs (90% of the time, it's Entity Framework, for example), we show a generic error message.

正如我所说的,并不适合所有人,但是这很适合我们的球队。我们有presentation和域验证,并从原始HTTP POST控制的一致流的明确分工,成功后重定向。

As i said, not for everyone, but this works well for our team. We have a clear seperation of presentation and domain validation, and a consistent flow of control from the raw HTTP POST, to the redirect after success.

心连心

这篇关于你在哪里摆在asp.net MVC 3的验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆