
The Internet is full of examples like "We make wikis on ASP.NET MVC in 15 minutes." The problem with such examples is that they use VideData or ViewBag to transfer data to the View.
Html.TextBox()
methods like
Html.TextBox()
are used to generate forms. And to get data from forms, simply parameters to the controller's methods, or worse, the entities themselves from ORM.
This can be wonderful from the point of view of who in life deals only with the creation of such “video lessons”. But in slightly more complicated cases, you certainly want to have strongly typed models, use strongly typed methods like
Html.TextBoxFor(m=>..)
, and get exactly what you want to get in the controller's method from the form all models are consistent.
')
So, the rules, if you want to develop in MVC:
- Each View has its own personal ViewModel class.
- Only View dictates what properties the ViewModel will have. The rest is controller problems.
- ViewModel is a simple DTO, without logic.
- View uses only the data that comes from the ViewModel, nothing more. Do not touch
Request.IsAuthenticated
in your View, for this there is a model.
The question may arise, but what about
_Layout (master pages) - this is also a View and they also want their models. It is quite reasonable - after all, we remember that view dictates the model, everything else follows. Therefore, create the SharedLayoutViewModel class in the application with the _Layout.cshtml properties you need, and inherit your models from it for the rest of the View. Use Result-filters to fill this model in one place for all methods of your controllers. Or reimplement
OnResultExecuting
in the base class of your controllers, and do it there.
For convenience, organize your models in the directory. Looks quite viable option of this structure:

We process forms
Let's try to create a controller, model and view for this form:

To do this, we will add a View, for which we specify the
AccountRegisterViewModel
as a model:
@model AccountRegisterViewModel
< h2 >
Register </ h2 >
@using (Html.BeginForm())
{
@Html.ValidationSummary()
< label >
Name
@Html.TextBoxFor(m = > m.Form.Name)
</ label >
< label >
State
@Html.DropDownListFor(m = > m.Form.State, Model.StateSelectList)
</ label >
< input type ="submit" value ="Register me" />
}
Add a model class to the project in the ViewModels / Account directory, which includes data for the State drop-down list and the property with the form itself (here it is, and in life there can be several in one View):
public class AccountRegisterViewModel : SharedLayoutViewModel<br/>
{ <br/>
public AccountRegisterForm Form { get ; set ; } <br/>
<br/>
public IEnumerable < SelectListItem > StateSelectList { get ; set ; } <br/>
}
For our form, we define a separate class. It will include the necessary DataAnnotations attributes for form validation, and maybe even sometime implements IValidatableObject:
public class AccountRegisterForm<br/>
{ <br/>
[ Required ] <br/>
public string Name { get ; set ; } <br/>
<br/>
[ Required ] <br/>
public string State { get ; set ; } <br/>
}
The controller of the toga will look like this:
[ HttpGet ] <br/>
public ActionResult Register ( ) <br/>
{ <br/>
var model = new AccountRegisterViewModel ( ) ; <br/>
<br/>
SetupRegisterViewModel ( model ) ; <br/>
return View ( model ) ; <br/>
} <br/>
<br/>
[ HttpPost ] <br/>
public ActionResult Register ( [ Bind ( Include = "Form" ) ] AccountRegisterViewModel model ) <br/>
{ <br/>
if ( ModelState. IsValid ) <br/>
{ <br/>
// save model.Form <br/>
<br/>
TempData [ "Message" ] = "Thank you for registering" ; <br/>
return RedirectToAction ( "Index" ) ; <br/>
} <br/>
<br/>
SetupRegisterViewModel ( model ) ; <br/>
return View ( model ) ; <br/>
} <br/>
<br/>
private void SetupRegisterViewModel ( AccountRegisterViewModel model ) <br/>
{ <br/>
model. StateSelectList = new SelectList ( new [ ] { string . Empty , "NY" , "VA" } ) ; <br/>
}
That's all.
I hope this example will be useful for ASP.NET MVC developers, especially those who create applications on it, and not video tutorials.
PS I note that the selected example for this approach is not indicative. The form of two fields without formatting is chosen only to save reader time.