Does ASP.NET MVC model check violate the MVC rule?

using ASP.NET MVC, I have a model to which I attach attributes so that I can use the MVC model binding check, but for this does not violate the MVC rule , where do you put the elements belonging to the view in the model? I hope I'm not trying to be smart, I'm curious about other opinions.

public class Payments { [DataType(DataType.Text)] [DisplayFormat(NullDisplayText="")] [Display(Name="Payment Id")] [Required(ErrorMessage="Required")] public int PaymentId { get; set; } //todo: make this into a dropdown [DataType(DataType.Text)] [Display(Name="Bill Name")] [Required(ErrorMessage = "Required")] public string PaymentName { get; set; } [DataType(DataType.Date)] [Display(Name="Date to Post Payment")] [Required(ErrorMessage = "Required")] public DateTime PaymentDate { get; set; } [DataType(DataType.Currency)] [Range(0, 922337203685477.5807)] [Required(ErrorMessage = "Required")] public double PaymentAmount { get; set; } } 
+6
source share
3 answers

Yes. That is why you should use ViewModels.

+10
source

You can, but should not, put these validation attributes in your model.

But it is better to use ViewModel:

 public class PaymentsViewModel { [DataType(DataType.Text)] [DisplayFormat(NullDisplayText="")] [Display(Name="Payment Id")] [Required(ErrorMessage="Required")] public int PaymentId { get; set; } //todo: make this into a dropdown [DataType(DataType.Text)] [Display(Name="Bill Name")] [Required(ErrorMessage = "Required")] public string PaymentName { get; set; } [DataType(DataType.Date)] [Display(Name="Date to Post Payment")] [Required(ErrorMessage = "Required")] public DateTime PaymentDate { get; set; } [DataType(DataType.Currency)] [Range(0, 922337203685477.5807)] [Required(ErrorMessage = "Required")] public double PaymentAmount { get; set; } } 

And in your view, instead of:

 @model YourProject.Models.Payments 

you're using:

 @model YourProject.Models.PaymentsViewModel 

for check.

+10
source

Is this a violation of MVC in the strict sense, yes, perhaps. Are there times when there is no harm in violating this? Of course. However, there are mechanisms to help you figure out and leave problems.

You can use your saved domain objects in the views and check them, but when your look starts to get complicated, ViewModels become a necessity. For dead simple domain models or view-only views (doesn't edit / create), I sometimes make up a little and send them to the view as part of a composite object:

 class MyViewModel { public MyDomainModel DomainObj; public int OtherViewInfo; } 

However, for creation and editing scenarios, ViewModels is much better. They allow you to fully control the data sent to and from the view.

If you use EF 4.1 and CodeFirst, then yes, you will get some duplication of attributes and properties between the domain and the ViewModel. This is inevitable, but gives you the flexibility to perform various checks specific to the presentation.

I found it useful to have one additional level of protection in the controller when actually saving the domain object in case I missed some verification in the view:

 public class MyController : Controller { [HttpPost] public ActionResult Edit(int id, MyViewModel model) { try { ...Do stuff, check ModelState.IsValid... _context.SaveChanges() } catch (DbEntityValidationException dbEx) { // Catch any validation errors on the domain that weren't duplicated // in the viewmodel ModelState.AddModelError("Form", dbEx); } return View(model); } } 

The next question you want to ask is the mapping between the domain model and the ViewModel. There are many strategies and tools - AutoMapper and ValueInjecter (yes, incorrectly spelled). Personally, I used ValueInjecter, although if you customized the display layer, you can try both. I found that none of them will work 100% of the time, or at least I could figure out how to do what I need, but the mapping service makes it easy to define custom maps from left to right.

+1
source

Source: https://habr.com/ru/post/888423/


All Articles