. NET Core Development logs-views and pages

Source: Internet
Author: User
Tags httpcontext

Tag: Buffer cannot find the finally length one ISP logger ice require

When an action completes its task, it is usually necessary to return an object that implements Iactionresult, and the most common is the view or Viewresult, the so-called views object. So what is the connection between the view and the page that we see finally, this is the problem that this article wants to discuss.

In the Resourceinvoker class, you can find the following code. This code is the further processing of the returned result--iactionresult.

case State.ResultInside:    {        ...        var task = InvokeResultAsync(_result);        if (task.Status != TaskStatus.RanToCompletion)        {            next = State.ResultEnd;            return task;        }        goto case State.ResultEnd;    }protected async Task InvokeResultAsync(IActionResult result){    var actionContext = _actionContext;    _diagnosticSource.BeforeActionResult(actionContext, result);    _logger.BeforeExecutingActionResult(result);    try    {        await result.ExecuteResultAsync(actionContext);    }    finally    {        _diagnosticSource.AfterActionResult(actionContext, result);        _logger.AfterExecutingActionResult(result);    }}

The method of the Viewresultexecutor class is called in the implementation class Viewresult of the Iactionresult interface.

public override async Task ExecuteResultAsync(ActionContext context){    ...    var executor = context.HttpContext.RequestServices.GetRequiredService<IActionResultExecutor<ViewResult>>();    await executor.ExecuteAsync(context, this);}

The Viewresultexecutor class needs to find the corresponding view first through the Razorviewengine class.

public async Task ExecuteAsync(ActionContext context, ViewResult result){    ...    var viewEngineResult = FindView(context, result);    viewEngineResult.EnsureSuccessful(originalLocations: null);    var view = viewEngineResult.View;    using (view as IDisposable)    {        await ExecuteAsync(            context,            view,            result.ViewData,            result.TempData,            result.ContentType,            result.StatusCode);    }    ...}

The result returned by the Razorviewengine class is the Razorview object. Note that the Irazorpage object is already contained within it.

Public Viewengineresult GetView (string Executingfilepath, String viewPath, bool ismainpage) {... var cacheresult = L    Ocatepagefrompath (Executingfilepath, ViewPath, ismainpage); Return Createviewengineresult (Cacheresult, ViewPath);} Public Viewengineresult Findview (actioncontext context, string viewName, bool ismainpage) {... var cacheresult = Loc    Atepagefromviewlocations (context, viewName, ismainpage); Return Createviewengineresult (Cacheresult, viewName);} Private Viewengineresult Createviewengineresult (viewlocationcacheresult result, string viewName) {... var page = Res Ult.    Viewentry.pagefactory (); var viewstarts = new Irazorpage[result.    Viewstartentries.count]; for (var i = 0; i < viewstarts.length; i++) {var Viewstartitem = result.        Viewstartentries[i];    Viewstarts[i] = Viewstartitem.pagefactory ();    } var view = new Razorview (this, _pageactivator, Viewstarts, page, _htmlencoder, _diagnosticsource); Return Viewengineresult.found (viewnAme, view);} 

After the

Finds the view, Viewresultexecutor calls its parent class Viewexecutor's Executeasync method. The Renderasync method of the Razorview class is called inside.

Protected Async Task Executeasync (ViewContext viewcontext, string contentType, int? statusCode) {... var r    Esponse = ViewContext.HttpContext.Response; Responsecontenttypehelper.resolvecontenttypeandencoding (ContentType, Response.    ContentType, Defaultcontenttype, out Var resolvedcontenttype, out Var resolvedcontenttypeencoding); Response.    ContentType = Resolvedcontenttype; if (StatusCode! = null) {response.    StatusCode = Statuscode.value; } using (var writer = writerfactory.createwriter (response).        Body, resolvedcontenttypeencoding) {var view = Viewcontext.view;        var oldwriter = Viewcontext.writer;            try {viewcontext.writer = Writer;            Diagnosticsource.beforeview (view, viewcontext); Await view.            Renderasync (ViewContext);        Diagnosticsource.afterview (view, viewcontext);       } finally {viewcontext.writer = Oldwriter; }//Perf:invoke Flushasync to ensure any buffered content are asynchronously written to the underlying// Response asynchronously. In the absence of this line, the buffer gets synchronously written to the//response as part of the The Dispose which        Has a perf impact. await writer.    Flushasync (); }}

The

Razorview class can see that its core processing is closely related to the Irazorpage Executeasync method.

Public virtual Async Task Renderasync (viewcontext context) {... _bufferscope = context.    Httpcontext.requestservices.getrequiredservice<iviewbufferscope> ();    var bodywriter = await Renderpageasync (razorpage, context, invokeviewstarts:true); Await Renderlayoutasync (context, bodywriter);} Private Async task<viewbuffertextwriter> Renderpageasync (Irazorpage page, ViewContext context, bool Invoke Viewstarts) {var writer = context.    Writer as Viewbuffertextwriter; ...//The writer for the body was passed through the viewcontext, allowing things like htmlhelpers//and Viewcompon    Ents to reference it. var oldwriter = context.    Writer; var Oldfilepath = context.    Executingfilepath; Context.    writer = writer; Context. Executingfilepath = page.    Path; try {if (invokeviewstarts) {//Execute view starts using the same context + writer as the PA            GE to render.        Await Renderviewstartsasync (context); } AWAIT Renderpagecoreasync (page, context);    return writer; } finally {context.        Writer = Oldwriter; Context.    Executingfilepath = Oldfilepath; }}private Async Task Renderpagecoreasync (Irazorpage page, ViewContext context) {page.    ViewContext = context;    _pageactivator.activate (page, context);    _diagnosticsource.beforeviewpage (page, context); try {await page.    Executeasync ();    } finally {_diagnosticsource.afterviewpage (page, context); }}

But when looking for an implementation of the Irazorpage interface. From RazorPageBase and to, RazorPage RazorPage<TModel> These are abstract classes, and there is no concrete implementation of the Executeasync method.

The source code can not find a further implementation class, the clue is broken here.

You can then build an MVC application, compile and find its bin directory, and see that it contains a *. View.dll file.

Using anti-compilation software, such as Dotpeek, to see what's inside, you'll find some classes generated by the cshtml file.

In the case of Views_home_index, it is actually RazorPage<TModel> an implementation class.

Its internal executeasync approach is the key to generating page content.

Because it is the auto-generated page of the VS template, the above code is very miscellaneous. To check the core code more clearly, you may want to reduce the complexity of the next page.

Change the contents of the index.cshtml file to read as follows:

@{    ViewData["Title"] = "Home Page";    Layout = null;}<p>Hello World!</p>

After compiling again, you can see that the contents of the Executeasync method become the following:

public virtual async Task ExecuteAsync(){  ((ViewDataDictionary) this.get_ViewData()).set_Item("Title", (object) "Home Page");  ((RazorPageBase) this).set_Layout((string) null);  ((RazorPageBase) this).BeginContext(65, 21, true);  ((RazorPageBase) this).WriteLiteral("\r\n<p>Hello World!</p>");  ((RazorPageBase) this).EndContext();}

It is not difficult to see that the final presentation of the page content is through the Razorpagebase class of Writeliteral method generated.

. NET Core Development logs-views and pages

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.