This article only lets you understand the display of the ASP. NET MVC View

Source: Internet
Author: User
Tags httpcontext

Some people want questions, why do I have to learn the framework? Here I would simply say that a deep understanding of a framework gives you the most immediate benefits:

    1. When working with frames, you can quickly locate problems and know how to solve them.
    2. When there are some functions in the framework with a bad mood, you can freely expand, to achieve the operation you want, and even can get the source code directly modified;
    3. The only way to become a framework teacher;
    4. Extracting excellent code and ideas from the frame for your own use;

More benefits, you can see for yourself, interested can look at the source code of the MVC part of asp: http://aspnetwebstack.codeplex.com/

purpose of this article

The last article is to let you understand the core of MVC two processes (if you have not seen the poke here, just a few minutes of your nap). Let's move on from the Controlleractioninvoker Invokeaction method to execute action:

Execute action and get ActionResult    actionresult ActionResult = method. Invoke (Controllercontext.controller,        parameters. ToArray ()) as ActionResult;    The final ActionResult uses HttpResponse to transmit the data back to the customer for display    Actionresult.executeresult (controllercontext);

The purpose of this article is to let you know what the code is doing. how the controller in MVC finds the view and displays it.

Start your journey

First put the class structure diagram related to this article:

This figure looks pretty complicated, but in fact he is very simple, give me two minutes, I will let you understand what these ghosts are, what is the relationship?

First said ActionResult, from the picture, ActionResult is an abstract class, his subclasses have many, such as Jsonresult,contentresult,viewresult,emptyresult and so on. This thing is often used when you use MVC, such as:

public class homecontroller:controller{Public    actionresult Index ()    {         return View ();    Public ActionResult GetInfo ()    {         ...        return Json (obj);      Public ActionResult getcontent ()     {         return Content ("Test");}      }

The above three action returns correspond to ViewResult, Jsonresult, Contentresult, and I only draw ViewResult, because it is one of our most used ActionResult, And is the most complex one (because the view is responsible for the display). And look at the core source of Contentresult, I think simple everyone laughed over:

public class Contentresult:actionresult    {public        string Content {get; set;}        public override void Executeresult (ControllerContext context)        {            Httpresponsebase response = context. Httpcontext.response;                        if (Content! = null)            {                response. Write (Content);}}}    

Its realization and the above I draw the structure diagram completely does not have the half gross money relations, the direct one Response.Write output completes. So I use Viewresult to write this article.

Next note viewengines this static class, look at its source code:

public static class Viewengines    {        private static readonly viewenginecollection _engines = new Viewenginecollection        {            new Webformviewengine (),            new Razorviewengine (),        };        public static viewenginecollection Engines        {            get {return _engines;}        }    

There is only one member of the static read-only viewenginecollection type, which encapsulates two view engines, Webformviewengine, and razorviewengine when initialized? What are these two? In order to facilitate everyone to understand, we look at the source of Razorviewengine (webformviewengine Basic, the space limit below I only use razor example):

public class Razorviewengine:buildmanagerviewengine {internal static readonly string viewstartfilename = "_vi Ewstart ";        Store Viewstart template public razorviewengine (Iviewpageactivator viewpageactivator): Base (Viewpageactivator) {//These constructs people should feel very kind viewlocationformats = new[] {"~/views/{1}/{0}.csh Tml "," ~/views/{1}/{0}.vbhtml "," ~/views/shared/{0}.cshtml "," ~/views/shared/            {0}.vbhtml "}; Masterlocationformats = new[] {"~/views/{1}/{0}.cshtml", "~/views/{1}/{0}.vbhtml            "," ~/views/shared/{0}.cshtml "," ~/views/shared/{0}.vbhtml "}; Partialviewlocationformats = new[] {"~/views/{1}/{0}.cshtml", "~/views/{1}/{0}.v            bHTML "," ~/views/shared/{0}.cshtml "," ~/views/shared/{0}.vbhtml "};        Fileextensions = new[] {"cshtml", "vbhtml",};        } protected override IView CreateView (ControllerContext controllercontext, String ViewPath, String masterpath) {var view = new Razorview (ControllerContext, ViewPath, Layoutpath:mast            Erpath, Runviewstartpages:true, Viewstartfileextensions:fileextensions, Viewpageactivator:viewpageactivator)            {displaymodeprovider = Displaymodeprovider};        return view; }    }

As you can see from the code, Razorviewengine just encapsulates the associated path to the view file. I'll explain how they were used in the back.

Once you know the basics of the above classes, take a look at their execution, and you will have a general idea of the functionality of each class, when the Controller's action returns a Viewresult and executes Executeresult (the code described in the beginning of the article):

    1. Getting Viewresultengine objects from Viewengines's engines is essentially traversing razorviewengine and Webformviewengine, Then, by inheriting Virtualpathproviderviewengine member functions themselves Findview create Viewresultengine "as can be seen from the sequence diagram below, although MVC hides this thing deep, But the basic is passed between the parent class and subclass, the structure is still clear ";
    2. Through the obtained viewresultengine in the View execution render interface display, internal calls Razorview Renderview for the final display processing;

The core process is the above two steps, and the sequence diagram is as follows (click to view larger image):

Now notice the 17th step of the process, which is to execute Buildmanagercompliedview's render function, which is the soul of the view display:

        public virtual void Render (ViewContext viewcontext, TextWriter writer)        {            object instance = null;                        This viewpath is a view specific path based on the template location of Razorviewengine, and the type type of the Viewengineresult passed in Razorviewengine is created            = Buildmanager.getcompiledtype (ViewPath);            if (type = null)            {                instance = viewpageactivator.create (_controllercontext, type);            }            if (instance = = null)            {                throw new InvalidOperationException (                    String.Format (                        CultureInfo.CurrentCulture,                        mvcresources.cshtmlview_viewcouldnotbecreated,                        ViewPath));            }            Renderview (ViewContext, writer, instance);        }

What is the instance that is generated above according to Viewpath? Look at the implementation of Rendview in Razorview to know:

protected override void Renderview (ViewContext viewcontext, TextWriter writer, object instance)        {            webviewpage Webviewpage = instance as webviewpage;            Other code regardless            of Webviewpage.executepagehierarchy (new Webpagecontext (Context:viewContext.HttpContext, Page:null, Model:null), writer, startpage);        }

The original is a Webviewpage object, check MSDN know, all the view is from the webviewpage generic webviewpage<tmode> directly inherit. Let's take a look at this class:

    Public abstract class Webviewpage:webpagebase, Iviewdatacontainer, iviewstartpagechild {private Viewdatad        Ictionary _viewdata;        Private Dynamicviewdatadictionary _dynamicviewdata;        Public ajaxhelper<object> Ajax {get; set;}        Public htmlhelper<object> Html {get; set;}        Public object Model {get {return viewdata.model;}        } public tempdatadictionary TempData {get {return viewcontext.tempdata;}        Public Urlhelper Url {get; set;}                    Public dynamic ViewBag {get {if (_dynamicviewdata = = null) {                _dynamicviewdata = new Dynamicviewdatadictionary (() = ViewData);            } return _dynamicviewdata;        }} public ViewContext ViewContext {get; set;}  public override void Executepagehierarchy () {Execute (); This function is defined in the base classThe abstract function will be overloaded in the final aspx/cshtml generated class} public virtual void Inithelpers () {Ajax = new ajaxhelper&            Lt;object> (ViewContext, this);            Html = new Htmlhelper<object> (ViewContext, this);        URL = new Urlhelper (viewcontext.requestcontext); }    }

is not in the inside see a lot of usual most commonly used attributes. When a page is generated with Executepagehierarchy, the Execute function is actually called, and the function is overloaded in the resulting class such as the final cshtml,aspx. Let's look at a simple example:

Suppose we have a strongly typed view:/views/home/index.cshtml, a simple demomodel type with only one username attribute:

@model controllers.demomodel<div>index</div> @Model. UserName

Then this index.cshtml is compiled and generates the following class:

public class _page_views_home_index_cshtml:webviewpage<demomodel>{public    override void Execute ()    { This          . Writeliteral ("<div>index</div");          This. Write (model.username);}    }

In this way, the Web is eventually displayed.

This article only lets you understand the display of the ASP. NET MVC View

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.