Before going to the actual implementation let’s go through some basics on MVC application.
MVC Application Lifecycle
When application starts at first time, it registers one or more patterns to the Route Table to tell the routing system what to do with any requests that match these patterns. An application has only one Route Table and this is setup in the Global.asax file of the application.
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Employee", action = "Index", id = UrlParameter.Optional } ); }
The MvcHandler is responsible for initiating the real processing inside ASP.NET MVC. MVC handler implements IHttpHandler interface and further process the request by using ProcessRequest method as shown below:
protected internal virtual void ProcessRequest(HttpContextBase httpContext) { SecurityUtil.ProcessInApplicationTrust(delegate { IController controller; IControllerFactory factory; this.ProcessRequestInit(httpContext, out controller, out factory); try { controller.Execute(this.RequestContext); } finally { factory.ReleaseController(controller); } }); }
As shown in above code, MvcHandler uses the IControllerFactory instance and tries to get a IController instance. If successful, the Execute method is called. The IControllerFactory could be the default controller factory or a custom factory initialized at the Application_Start
event, as shown below:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); Database.SetInitializer<EmployeeDAL>(null); ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory()); }
Once the controller has been instantiated the ActionInvoker class has some of the most important responsibilities of finding the action method in the controller and then invoking the action method. Action to be executed is chosen based on attributes ActionNameSelectorAttribute .
The action method receives user input, prepares the appropriate response data, and then executes the result by returning a result type. The result type can be ViewResult, RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult, and EmptyResult.
The first step in the execution of the View Result involves the selection of the appropriate View Engine to render the View Result. It is handled by IViewEngine interface of the view engine. By default Asp.Net MVC uses WebForm and Razor view engines. You can also register your own custom view engine to your Asp.Net MVC application as shown below:
protected void Application_Start() { //Remove All View Engine including Webform and Razor ViewEngines.Engines.Clear(); //Register Your Custom View Engine ViewEngines.Engines.Add(new CustomViewEngine()); //Other code is removed for clarity }
Action method may returns a text string, a binary file or a Json formatted data. The most important Action Result is the ViewResult, which renders and returns an HTML page to the browser by using the current view engine.
ViewData & ViewBag: ViewData and ViewBag is a good option for passing values between Controller and View. But in real time projects it’s not a good practice to use any of them. Values inside the ViewData are of type Object. We have to cast the value to correct type before using it. It adds additional overhead on performance. As a good programming practice, error should be tackled in compiled time but here we will not have any Type safety and no compile time errors
In Controller this is how we can return the ViewData to the view
ViewData["Employee"] = emp;
return View("MyView");
ViewBag is just a syntactic sugar for ViewData. ViewBag uses the dynamic feature of C# 4.0 and makes ViewData dynamic. ViewBag internally uses ViewData.
ViewBag.Employee = emp;
In Index.cshtml retrieving the Employee data from the ViewData and display it as follows.
<div> @{ WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee) ViewData["Employee"]; } <b>Employee Details </b> <br /> Employee Name : @emp.FirstName @emp.LastName <br /> Employee Salary: @emp.Salary.ToString("C") </div> For ViewBag we can write the code like: @{ WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee) ViewBag.Employee; }
A method to be public but not action method:
Simply decorate it with NonAction attribute as follows.
[NonAction] public string SimpleMethod() { return "Hi, this is a no action method"; }
When we try to make request to above action method we will get following response like : “The resource cannot be found”.
ActionResult and ViewResult : ActionResult is the abstract class whereas ViewResult is the multi-level child of ActionResult. Multilevel because, ViewResult is the child of ViewResultBase and ViewResultBase is the child of ActionResult.
public ActionResult GetView() { if (Some_Condition_Is_Matching) { return View("MyView"); } else { return Content("Hi Welcome"); } }
ViewResult represents a complete HTML response whereas ContentResult represents a scalar text response. It’s just like returning pure string. Difference is ContentResult is aActionResult wrapper around string result. ContentResult is also the child of ActionResult.
Action Filters:
An action filter is an attribute that you can apply to a controller action or an entire controller that modifies the way in which the action is executed. The ASP.NET MVC framework includes several action filters:
OutputCache – This action filter caches the output of a controller action for a specified amount of time.
HandleError – This action filter handles errors raised when a controller action executes.
Authorize – This action filter enables you to restrict access to a particular user or role.
You also can create your own custom action filters. For example, you might want to create a custom action filter in order to implement a custom authentication system.
The ASP.NET MVC framework supports four different types of filters:
1. Authorization filters – Implements the IAuthorizationFilter attribute.
2. Action filters – Implements the IActionFilter attribute.
3. Result filters – Implements the IResultFilter attribute.
4. Exception filters – Implements the IExceptionFilter attribute.
In the next section, we’ll see how you can implement each of these different methods.
Authentication:
We understood the real meaning of word ASP.NET and MVC. We understood that ASP.NET MVC is part of ASP.NET. Most of the features of ASP.NET are inherited in ASP.NET MVC. One of the features is Forms Authentication.
Before we start implementing let’s understand how Forms Authentication works in ASP.NET
1. End user make a request to Forms authentication enabled application with the help of browser.
2. Browser will send all the associated cookies stored in the client machine with request.
3. When request is received as server end, server examines the request and check for the special cookie called “Authentication Cookie”.
4. If valid authentication cookie is found, server confirms the identity of the user or in simple words, consider user as a valid user and make him go further.
5. If valid authentication cookie is not found server considers user as anonymous (or unauthenticated) user. In this case if the requested resource is marked as protected/secured user will be redirected to login page.
Validation:
In Login view, HTML elements are generated using HTML helper classes. Helper functions while generating HTML markup attach some attributes based on the data annotation attributes used.
@Html.TextBoxFor(x=>x.UserName) @Html.ValidationMessageFor(x=>x.UserName) Above code will generate following HTML. <input data-val="true" data-val-length="UserName length should be between 2 and 7" data-val-length-max="7" data-val-length-min="2" id="UserName" name="UserName" type="text" value="" /> <span class="field-validation-error" data-valmsg-for="UserName" data-valmsg-replace="true"> </span>
These custom HTML attributes will be used by “jQuery Unobtrusive validation files” and thus validation gets implemented at client side automatically. Automatic client side validation is the second advantage of Html helper classes.
ViewModel:
Model and ViewModel should be independent of each other. Controller will create and initializes ViewModel object based on one or more Model object. Every View will have its corresponding ViewModel. Every view should always have its own ViewModel even if ViewModel is going to contain same properties as model.
Let’s say we have a situation where View won’t contain presentation logic and it want to display Model data as it is. Let’s assume we won’t create a ViewModel in this situation.
Problem will be, if in future requirement, if we have been asked to show some new data in our UI or if we asked to put some presentation logic we may end with complete new UI creation from the scratch.
So better if we keep a provision from the beginning and Create ViewModel. In this case, in the initial stage ViewModel will be almost same as Model.
In the implementation section, we’ll see how you can implement each of these different methods.
As this article becomes a very lengthy in shape, so planning to write implementation of all the above sections in my next article.
Happy Coding
Tarun Kumar Chatterjee
Leave a comment