ASP.NET MVC 3 - Model Validation

I am just learning MVC and I have some questions about design / how things should work.

I am using MVC 3 and Razor with Entity Framework classes (e.g. Location) and I am going to create a buddy class with validation annotations. In my view, I have a partial view that displays the DevExpress TreeView (using the list of locations) and a form for creating / editing locations in the tree. I have a LocationController, LocationManagementView, LocationManagementPartialView (contains code for the tree view) and LocationModel. LocationModel will hold the buddy class and get methods for getting children (children are selected only after the node extension). I have a service wrapper (for my service client) that will be introduced using StructureMap.

Should I embed a service shell in the controller constructor or in the model constructor?

In addition, my model receives methods that use the utility shell to retrieve data from the database (do these methods belong here in the model?): For example, GetChildren for a tree view.

Also, is it right to store the location buddy class in the model?

I want to make sure that I developed this application correctly, as it is part of a much larger project. Any design pointers are greatly appreciated. I read the ScottGu blog for MVC stuff.

Link: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

+2
source share
1 answer

Here are some guidelines for your framework.

Entity Framework

For each of your models returned from EF, Retrieve the EF model interface and use the interface as a data source, rather than an implemented EF class. The reason for this is that if you decide to use a different data source for any one or more models (or the entire Entity Framework), you can just make sure that your new data layer returns the same interfaces, without having to change your entire network code . The downside is that your interfaces are updated when the model changes.

It also allows your view models to implement the EF model interface (with additional logic of your choice). This is beneficial if all your calls for inserts / updates to the Data Layer accept the same interface models that were returned. This allows you to create several models with different requirements that correspond to what is required to enter / update the data level. The disadvantage is that in your Data Layer you need to [create a new EF model] / [Get the model to update] and map the fields from the interface to the model.

Browse Models

I highly recommend that each presentation model is not the actual model (s) to be displayed, but a class that contains the model (s). Examples:

public class Car //Not what I recommend passing to a view { public string Make { get; set; } public string Model { get; set; } } //Pass this to the view, i'll explain why... public class CarViewModel : IPartialViewCar { public Car Car { get; set; } public ColorCollection { get; set; } } 

By running the CarViewModel example, you can separate partial views from views. Here's how (using the above models):

 public interface IPartialViewCar { public Car { get; } } [BuildCar.cshtml] @Model MyNameSpace.Models.Car @Html.EditorFor(model) [PartialViewCar.cshtml] @Model MyNameSpace.Models.IPartialViewCar @Html.EditorFor(model) //something like that.. 

Now anytime you want to use a PartialViewCar , you just need to create a model that implements the IPartialViewCar interface, basically separating the partial view from the view.

Check

I would recommend creating interfaces (classes if you really want, but really don't need there) that have all of your validation logic.

Suppose we want anonymous users to enter both make and model, but registered users only need to enter Make. How this can be done easily, here's how: (in more detail about the previous code)

 public interface IAnonymouseCarValidation { [required] public string Make { get; set; } [required] public string Model { get; set; } } public interface IRegisteredCarValidation { [required] public string Make { get; set; } } public interface ICar { public string Make { get; set;} public string Model { get; set; } } [updating the Car model to abstract and use an interface now] public abstract class Car : ICar { //maybe some constructor logic for all car stuff public string Make { get; set;} public string Model { get; set; } //maybe some methods for all car stuff } //MetadataType tells MVC to use the dataannotations on the //typeof class/interface for validation! [MetadataType(typeof(AnonymouseCarValidation))] public class AnonymousCar : Car { } [MetadataType(typeof(AnonymouseCarValidation))] public class RegisteredCar : Car { } [Now update the ViewModel] public class CarViewModel : IPartialViewCar { public ICar Car { get; set; } //this is now ICar public ColorCollection { get; set; } } 

Now you can create either AnonymouseCar or RegisteredCar , transfer it to CarViewModel, and let MVC take care of the verification. When you need to update validation, you update one interface. The disadvantage of this is that it feels rather complicated.

Injection Requests and Data

My preference is to try to simplify the actions of the controller as much as possible and not include the code for data extraction there. The reason I donโ€™t want to do this is because I donโ€™t like repeating code. For instance:

 public class AccountControllers { DataServer _Service; public AccountControllers(DataServer Service) { this._Service = Service; } public ActionResult ShowProfiles() { ProfileViewModel model = new ProfileViewModel(); model.Profiles = this._Service.Profiles(); return View(model); } public ActionResult UpdateProfile(ProfileViewModel updatedModel) { service.UpdateProfile(updatedModel); ProfileViewModel model = new ProfileViewModel(); model.Profiles = this._Service.Profiles(); return View(model); } } 

Instead, I would do something like: (not fully)

  public ActionResult ShowProfile(Guid ID) { ProfileViewModel model = new ProfileViewModel(this._service); return View(model); } public ActionResult UpdateProfile(ProfileViewModel updatedModel) { // pass in the service, or use a property or have SetService method updatedModel.Update(this._service) ProfileViewModel model = new ProfileViewModel(this._service); return View(model); } public class ProfileViewModel() { DataServer _Service; Profile _Profile public ProfileViewModel() { } public ProfileViewModel(DataServer Service) { this._Service = Service; } public Profile Profiles() { get { if (this._service == null) { throw new InvalidOperationException("Service was not set."); } return = Service.Profiles(ID); } 

This means that the profiles are listed ONLY when they are requested, I do not have to fill it out myself. As a rule, these are fewer errors if I use this code to my advantage, instead of requiring me or other programmers to manually fill in the models.

+3
source

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


All Articles