MVC

MVC Request Life Cycle

WebBrowser >> IIS >> UrlRoutingModule (HttpModule) >> RouteData (Controller/Action) >> RequestContext >> MVCRouteHandler (HttpHandler) >> MVCHandler >> IControllerFactory >> ActionResult

Any web application has two main execution steps, first understanding the request and depending on the type of the request sending out appropriate response. MVC application life cycle is not different it has two main phases, first creating the request object and second sending our response to the browser.

Creating the request object: 

The request object creation has four major steps. The following is the detailed explanation of the same.

Step 1: Fill route

MVC requests are mapped to route tables which in turn specify which controller and action to be invoked. So if the request is the first request the first thing is to fill the route table with routes collection. This filling of route table happens in the global.asax file.

Step 2: Fetch route

Depending on the URL sent “UrlRoutingModule” searches the route table to create “RouteData” object which has the details of which controller and action to invoke.

Step 3: Request context created

The “RouteData” object is used to create the “RequestContext” object.

Step 4: Controller instance created 

This request object is sent to “MvcHandler” instance to create the controller class instance. Once the controller class object is created it calls the “Execute” method of the controller class.

Creating Response object


This phase has two steps executing the action and finally sending the response as a result to the view.




MVC Introduction



Convention over Configuration
  

The convention over configuration concept was made popular by Ruby on Rails a few years back and essentially means we know, by now, how to build a web application. Let’s roll that experience into the framework so we don’t have to configure absolutely everything again.

  

You can see this concept at work in ASP.NET MVC by taking a look at the three core directories that make the application work:
  • Controllers
  • Models
  • Views
You don’t have to set these folder names in the web.config file — they are just expected to be there by convention. This saves you the work of having to edit an XML file like your web.config, for example, in order to explicitly tell the MVC engine, “You can find my views in the Views directory” — it already knows. It’s a convention.



Each controller’s class name ends with Controller: ProductController, HomeController and so on, and lives in the Controllers directory.

There is a single Views directory for all the views of your application.

Views that controllers use live in a subdirectory of the Views main directory and are named according to the controller name (minus the Controller suffix). For example, the views for the ProductController discussed earlier would live in /Views/Product.

Razor View Engine

  • Razor is an ASP.NET programming syntax used to create dynamic web pages with the C# or Visual Basic .NET programming languages. 
  • Razor was in development in June 2010 and was released for Microsoft Visual Studio 2010 in January 2011
  • Razor is a markup syntax that lets you embed server-based code (Visual Basic and C#) into web pages.
  • Server-based code can create dynamic web content on the fly, while a web page is written to the browser. When a web page is called, the server executes the server-based code inside the page before it returns the page to the browser.
  • Razor is based on ASP.NET, and designed for creating web applications. It has the power of traditional ASP.NET markup, but it is easier to use, and easier to learn.
  • Razor is the first major update to rendering HTML since ASP.NET 1 shipped almost a decade ago.
  • The default view engine used in MVC 1 and 2 was commonly called the Web Forms view engine,
  • Because it uses the same ASPX/ASCX/MASTER files and syntax used in Web Forms. It works, but
  • it was designed to support editing controls in a graphical editor, and that legacy shows
  • Razor was designed specifically as a view engine syntax. It has one main focus: code-focused templating for HTML generation.

ViewData and ViewBag

  • ViewData and ViewBag are used for the same purpose to transfer data from controller to view. Both life lies only in current request.
  • ViewData is nothing but dictionary of object and it is accessible by string as key. ViewData is property of controller that exposes an instance of the ViewDataDictionary class.
  • ViewBag is very similar to ViewData. ViewBag is a dynamic property (dynamic keyword which is introduced in .net framework 4.0).
  • ViewBag is able to set and get value dynamically and able to add any number of additional fields without converts it to strongly typed.
  • ViewBag is just a wrapper around the ViewData.


Temp Data

  • TempData is a dictionary which is derived from TempDataDictionary class. TempData is stored data just like live session for short time.
  • TempData Keep data for the time of HTTP Request it mean that it hold data between two consecutive requests.
  • TempData help us to transfer data between controllers or between actions. TempData internally use Session variables.
  • Note that TempData is only work during the current and subsequent request. It is generally used to store one time message.
  • With the help of TempData.Keep() method we can keep value in TempData object after request completion.




Item

Code

BeginForm

@using (Html.BeginForm()) { }

TextBox

@Html.TextBoxFor(x => x.Name)

ComboBox

@Html.DropDownListFor(x => x.WillAttend, new[] {
new SelectListItem() {Text = "Yes, I'll be there", Value = bool.TrueString},
new SelectListItem() {Text = "No, I can't come", Value = bool.FalseString}
}, "Choose an option")

HttpGet

[HttpGet]
public ViewResult RsvpForm() {
return View();
}

HttpPost

[HttpPost]
public ViewResult RsvpForm(GuestResponse guestResponse) {
// TODO: Email guestResponse to the part organizer
return View("Thanks", guestResponse);
}

using System.ComponentModel.

DataAnnotations;

public class GuestResponse {
[Required(ErrorMessage="Please enter your name")]
public string Name { get; set; }
[Required(ErrorMessage="Please enter your email address")]
[RegularExpression(".+\\@.+\\..+",
ErrorMessage="Please enter a valid email address")]
public string Email { get; set; }
[Required(ErrorMessage="Please enter your phone number")]
public string Phone { get; set; }
[Required(ErrorMessage="Please specify whether you'll attend")]
public bool? WillAttend { get; set; }
}
Equalent to <form> </form>
@using (Html.BeginForm()){}
HTML Helper Hidden
@Html.Hidden("hdnSelectedNDJ")
Equalent to <a> tag
@Html.ActionLink("RDW""NDJResults"new { sortOrder = ViewBag.RDWParm })
Equalent to Span or Label
@Html.DisplayFor(modelItem => item.RDW)
Input type Text
@Html.TextBoxFor(m => m.UserName, new { @id = "UserName", @style = "width:150px;" })
CheckBox
@Html.CheckBoxFor(modelItem => item.IsAllowed, new { @id = "IsAllowed-" + item.UserName })
Display any HTML Content
@Html.Raw("&nbsp;");
External JS File in MVC3
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
Validator
@Html.ValidationMessageFor(m => m.UserName, ""new { @style="color:red;margin-left:60px;" })
Validotor
@Html.ValidationSummary(true"Login was unsuccessful. Please try again."new { @style = "font-weight:bold;font-family: Arial; font-size: 12px;margin-left:20px;" })
HTML Partial
@Html.Partial("_LogOnPartial")
Include CSS File
@Html.Raw(Html.CssInclude(typeof(W9FormController), Url.Content("~/Content/W9.css")))
Include CSS File
@Html.Raw(Html.JavascriptInclude(typeof(W9FormController), Url.Content("~/Scripts/scode.js")))
JavaScript Include
<%= Html.JavascriptInclude(typeof(CommissionsController),
Url.Content("~/static/js/jquery.jqplot.min.js"),
Url.Content("~/static/js/jqplot.barRenderer.min.js"))
CSS Include
<%= Html.CssInclude(typeof(LandingController),
                Url.Content("~/static/css/style-landing-min.css"))
    %>

Repository
A repository is an object that encapsulates data layer, it contain the logic of retrieving data and mapping it to the Entity Framework

CSRF (Cross Site Request Forgery)
Before the page is served the server injects a secret token inside the HTML in form of Hidden Field. ValidateAntoForgeryToken

Filters in MVC


Filter TypeInterfaceDescription
AuthenticationIAuthenticationFilterThese are Runs, before any other filters or the action method.
AuthorizationIAuthorizationFilterThese Runs first, before any other filters or the action method.
ActionIActionFilterThese Runs before and after the action method.
ResultIResultFilterRuns before and after the action result is executed.
ExceptionIExceptionFilterRuns only if another filter, the action method, or the action resultthrows an exception.


  1. public class CustomAuthorizeAttribute : AuthorizeAttribute  
  2. {  
  3.    Entities context = new Entities(); // my entity  
  4.    private readonly string[] allowedroles;  
  5.    public CustomAuthorizeAttribute(params string[] roles)  
  6.    {  
  7.       this.allowedroles = roles;  
  8.    }  
  9.    protected override bool AuthorizeCore(HttpContextBase httpContext)  
  10.    {  
  11.       bool authorize = false;  
  12.       foreach (var role in allowedroles)  
  13.       {  
  14.          var user = context.AppUser.Where(m => m.UserID == GetUser.CurrentUser/* getting user form current context */ && m.Role == role &&  
  15.          m.IsActive == true); // checking active users with allowed roles.  
  16.          if (user.Count() > 0)  
  17.          {  
  18.             authorize = true/* return true if Entity has current user(active) with specific role */  
  19.          }  
  20.       }  
  21.       return authorize;  
  22.    }  
  23.    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)  
  24.    {  
  25.       filterContext.Result = new HttpUnauthorizedResult();  
  26.    }  
  27. }  

Here is the Action method to demonstrate how to use our CustomAuthorize attribute.

  1. [CustomAuthorize(“Administrator”,”Moderator”)  
  2. public ActionResult AddArticle()  
  3. {  
  4. return View();  
  5. }  
Authentication Filter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Filters;

namespace MVCInBuiltFeatures.CustomAttributes
{
    public class AdminSuperAdminAttribute : FilterAttribute, IAuthenticationFilter
    {
        string superAdminRole = "SuperAdmin"; // can be taken from resource file or config file
        string adminRole = "Admin"; // can be taken from resource file or config file

        public void OnAuthentication(AuthenticationContext context)
        {
            if (context.HttpContext.User.Identity.IsAuthenticated &&
               (context.HttpContext.User.IsInRole(superAdminRole)
                || context.HttpContext.User.IsInRole(adminRole)))
            {
                // do nothing
            }
            else
            {
                context.Result = new HttpUnauthorizedResult(); // mark unauthorized
            }
        }

        public void OnAuthenticationChallenge(AuthenticationChallengeContext context)
        {
            if (context.Result == null || context.Result is HttpUnauthorizedResult)
            {
                context.Result = new RedirectToRouteResult("Default",
                    new System.Web.Routing.RouteValueDictionary{
                        {"controller", "Account"},
                        {"action", "Login"},
                        {"returnUrl", context.HttpContext.Request.RawUrl}
                    });
            }
        }
    }
}

Comments

Popular posts from this blog

ASP.NET