June by Dino Espositoby Dino Esposito
We ' ve inherited from the original MVC pattern a rather simplistic idea's what should is in the Model. In fact, in ASP. NET MVC, there is three distinct types of model:the domain model, view model and input model. As the data behind an ASP. Application becomes more complex, the more of the view model and domain model may diverge.
When you use the standard project template for creating ASP. NET MVC 3 applications in Visual Studio, the newly create D project comes with a predefined folder named Models. The Models folder goes Hand-in-hand with the other predefined folders called views and Controllers. Models, views, and Controllers form the triad of roles that underlie any application this conforms to the popular MVC (Mod El-view-controller) design pattern.
in ASP. NET MVC, the views and Controllers folders is not simply containers of classes; If you remove or rename views and Controllers then your project won ' t compile unless your do some (legal and documented) MA GIC with the internal plumbing of the ASP runtime. Moreover, the Views folder must also is deployed as-is onto the production server. So in the end, views and Controllers play a key role in ASP. What's about Models?
First and foremost, the Models folder plays no decisive role in the working of an ASP. You can freely remove or rename it; This won ' t has any significant impact on your project. As the name itself seems to suggest, the intended role of the Models folder are acting as a central repository of model CLA SSEs. Oh Nice, but wait a moment! What ' s a model class ultimately?
In the end, the term "model" was fairly overloaded these days and needs some qualifying attribute to be fully understood. This have to does with the evolution, the MVC pattern, and applications, underwent recently. ASP. Just one implementation of the original MVC pattern, but some further considerations apply.
From the MVC Pattern to ASP.
A few decades ago, when the MVC pattern is first formulated, software applications weren ' t as tiered and sophisticated as They is today. The controller was responsible-just about everything, including grabbing input data from the view, orchestrating opera tions for producing a response and packing the response for the view. A single object model is used to manage the entire flow of data, and this object model was just called "the model."
In the original formulation of the MVC pattern, the view and model know about each other and is connected through an OBSE RVer relationship. The view writes its content to the model following users ' clicking; The controller reads input data from the model, orchestrates operations and then updates to the model with computed results. Finally, the model notifies the view of occurred changes and the view reads data back and refreshes itself. The MVC pattern was formulated some-years. For quite some time, the relatively low level of complexity of the most applications never required that the "model" got a MOR e precise definition.
It would be ingenuous to pretend, the MVC pattern for modern ASP. Applications is the same as it was the years ago. The MVC pattern is originally devised to better organize the entire application; Today, instead, it is still a effective pattern but limited to the frontend of layered applications-the presentation Laye R.
In ASP., a controller is primarily the repository of presentation logic much like the Code-behind class in Web and Windows Forms. The controller sets up and possibly delegates any further work required to serve the request. This role was nearly the same as in the original MVC pattern. The view grabs input data and produces the user interface. This role was also nearly the same as in the original MVC pattern. The model is in the original MVC pattern, the representation of the data being worked on the view.
This definition is the too limiting in modern layered applications such as those the be writing with ASP. The concept of the "model" needs expansion.
Flavors of a Model
In general, there is three distinct types of a model. With regard to ASP, we can call them domain model, view model and input model. Let's find out more.
the domain Model describes The data of the middle tier of the application. The domain model is expected-provide a faithful representation of the entities that populate the business domain. These entities is typically persisted by the data-access layer and consumed by services that implement business processes . The domain model is also often referred to as the entity model or simply as the data model. The domain model pushes a vision of data, in general, distinct from the vision of data you find in the Presentatio n Layer. (Note that the domain model "may" is the same model, the presentation layer, but this should is taken as T He exception rather than the rule.)
the view Model describes The data being worked on the presentation layer. Any data from the present in the view (whether strings, collections, dates) finds it place in one of the properties of the Vie W Model classes. Any view model class represents the data, the controller transmits after processing operations for serving a response to the users. The view model results from the aggregation of multiple classes, one per view or page so you display.
Finally, the input model is the collection of classes that describe the input data flow, which goes from the Web PA GE down to the controllers and backend. The input model faithfully represents the data being uploaded with individual HTTP requests. Usually, you manage the data as strings and read (serialized) values from collections such asQueryString and Form. Turning strings into strong types are entirely your responsibility in ASP. Web Forms. in ASP. NET MVC, the model-binding infrastructure does most of these chores for your and attempts to maps incoming strings to Matching properties of the input model types. Let's find out about the details.
Anatomy of the Input Model
in ASP. NET MVC, the input model can be envisaged as a collection of classes that model any data coming your A-through HTTP request. The input model is made of simple data transfer objects-just properties and no methods. Input model classes is used by controller methods as a-to-receive posted data parameters or data being passed on the Query string or HTTP headers. Here's a example of a controller method leveraging a class in the input model:
public ActionResult Repeat(RepeatInfo model){ var viewModel = new RepeatViewModel {Number = number, Text = text}; return View(viewModel);}
In the example, the Repeat method was invoked to Repeat a given text a given number of times. Therefore, the pieces of information to transmit is two-a string and a number. All data are moved across the wire as strings packaged in the HTTP packet. Once the request is handed to the selected controller method, ASP. Does some magic to turn the content found in the Body of the request into a fresh instance of the type declared as an argument of the controller. With a eye on the previous code snippet, the body of the HTTP request is revived to an instance of therepeatinfo class.
the RepeatInfo class can be a plain Data-transfer object defined as follows:
public class RepeatInfo { public String Text { get; set; } public Int32 Number { get; set; }}
It is one of your tasks as a developer to decide about the name and structure of the input model classes. There ' s some freedom as far as naming and structure of the input model classes are concerned. The structure outlined above is not the only possible one. Here ' s another equally valid class:
public class AnotherRepeatInfoClass { public String Text { get; set; } public Long Number { get; set; }}
As guessed, repeatinfo and anotherrepeatinfoclass has member names in Common-text and number. The type of these members could not be as important as their names but it's anyway required that the types was compatible a S Int32 and Long. How does mapping between values in the HTTP request packet and properties declared on the input model class actually work? The model binder is the ASP. Component responsible for.
Under the Hood of Model Binding
Any controller method executes under the control of the action Invoker component. The developer decides about the signature of the Controller method. For each declared parameter, the invoker obtains a model binder object. The binder ' s job consists in trying to find a possible value for this parameter out of the HTTP request context. Each parameter can is bound to a specific model binder class; However, most of the time a default model binder class is used. The default model binder corresponds to the defaultmodelbinder Class and it are the binder used for all parameters unless otherwise specified.
Each model binder uses it own algorithm to try to find a value for the parameters of a controller method. The default binder object makes an intensive of reflection. In particular, for each parameter the binder attempts to find a match between the parameter ' s name and one of the values U Ploaded with the request. So if the parameter is named, say,TextThen it looks in the collections of the request context (i.e., Form, QueryString) to find a entry with the same name. If a match is found then the binder attempts to convert the uploaded value (always a string) to the declared type of the P Arameter. If The conversion is successful, the computed value is and then used in the call to the Controller method; Otherwise, an exception is thrown. Note that a exception is thrown on the first failure. This means, the Controller method call proceeds successfully only if all of the declared parameters can is resolved by The binder. Be aware that a exception generated by the binder cannot is caught up in the controller method ' s code. You need to set up a global error handler inGlobal.asaxIn order to catch and handle those exceptions in some. Note also that a exception is thrown only if the declared method parameter can ' t be assignedNULL. For example, if you had an Int32 parameter failing in resolving the value would throw an exception because Null was not a V Alid value for an Int32 variable. By simply changing Int32-nullable<int32> in the controller method signature you fix the code.
The default binder looks into a variety of collections around the HTTP request context. The first place where it looks to is the Form collection. In this case, names of the input field is processed in a case-insensitive manner. If you had, say, an input text field named TextBox1 then a method parameter with the same name would be assigned. The content of the uploaded string would be converted to the type of the parameter if the conversion works. If a match can ' t is found in Form, then the binder looks into the route parameters and then the Querystrin G Collection.
When you had several parameters to upload and maps to variables, using primitive types and individual parameters could not B e a great idea-the signature of method may become confusingly long. The nice thing about the default binder was if the parameter type to fill in is a. NET complex type (such as theRepeatInfo Class) Then the binder attempts-populate the public properties based on the same name-matching algorithm. In and words, if the class to bind have a property namedTextof typeString(as in the example) then the property is initialized to the value of any posted data with the same name. Put another, if the ASP. Form posting data has a text box with an ID ofTextBox1, then the binder would try to find the match between that value and a property on the target type named TextBox1. If no match can found, then the property on the target type would retain the default value for the type.
Custom Default Binders
The default model binder is generic enough to work with most of the time. However, there might is situations in which you want to create a custom one. This happens specifically if you need to aggregate a few values being uploaded individually together to form a new objec T. For example, suppose that your ASP. NET form has three distinct fields for day, month and year. On the server, you ' d like these three distinct fields to form a DateTime object. You can bind the individual values to distinct parameters and then perform the conversion manually in the controller Metho D, as shown below:
public ActionResult Index(Int32 day, Int32 month, Int32 year)
In alternative, can declare a parameter of type DateTime and bind it to a custom binder this just works to PR Oduce DateTime objects.
public ActionResult Index( [ModelBinder(typeof(DateTimeModelBinder))] DateTime theDate)
The binding expressed here would only be occur when the Index method is invoked. You can also register a binder type for all occurrences of a given type (such as DateTime in this example). Here's the code you need:
ModelBinders.Binders[typeof(DateTime)] = new DateTimeModelBinder();
A model binder object is a class this implements the Imodelbinder interface or that simply inherits fromDefau Ltmodelbinder. For more information and examples on a custom model binder can check my book "Programming ASP.", 2nd edition FR Om Microsoft Press.
Summary
The model in MVC is frequently a misunderstood concept because it's often mistaken for the domain model. In summary, the model in the MVC pattern refers to modeling the data as seen by the view. In this regard, I-D call it the view model. In the addition to the view model, you have the domain model that describes the data of the the backend. These, models, coincide in CRUD applications, and in some other relatively simple scenarios. However, not using distinct view and domain models when the both do not coincide is a serious architectural weak point.Finally, in ASP. Which data flows into the controller is modeled through another bunch of ad ho C Classes-the Input Model. However, of the three models, the input model is probably the one so you can consider optional without compromising the Stability of your architecture. The input model helps in the design and understanding of data flow; But if you consider it part of the view model you ' re not necessarily doing a wrong thing.
The three Models of ASP. NET MVC Apps