ASP. NET core MVC implements pseudo-static function

Source: Internet
Author: User
Tags httpcontext
This article is mainly for you to introduce the ASP. NET core MVC implementation of pseudo-static function of the relevant data, with a certain reference value, interested in small partners can refer to

In the large-scale website system, in order to improve the system access performance, often will not often become content to publish to static pages, such as the Product Details page of the mall, the news details page, once published, the frequency of change will not be very high, if the dynamic output of the way to deal with it, Will certainly cause a great resource waste to the server. But we can not for these content are independent production static page, so we could use pseudo-static in the system to deal with, as to what is pseudo-static, we can Baidu under. Let's introduce how pseudo-static is implemented in ASP. NET core MVC.

In the MVC framework, view represents the views, and the result is the content of the final output to the client browser, including Html,css,js, and so on. If we want to achieve static, we need to save the result of view execution as a static file, save it to the specified location, such as disk, distributed cache, and so on, the next time access can read the saved content directly, without having to execute the business logic again. What should ASP. NET core MVC do with this functionality? The answer is to use filters, in the MVC framework, to provide a variety of filter types, here we want to use an action filter, the action filter provides two time points: the action before execution, the action after execution. We can determine whether or not a static page has been generated before the action is executed, and if it has been generated, read the file content output directly and the subsequent logic will be skipped. If there is no production, continue down, capture the results at this stage after the action is executed, and then save the static content generated by the result.

So we'll come to the concrete implementation code, first we define a filter type, we become staticfilehandlerfilterattribute, this class derives from the actionfilterattribute provided in the framework, Staticfilehandlerfilterattribute overrides the two methods provided by the base class: OnActionExecuted (after the execution of the action), OnActionExecuting (before the action executes), with the following code:

[AttributeUsage (attributetargets.class| AttributeTargets.Method, AllowMultiple = False, inherited = False)]public class Staticfilehandlerfilterattribute: actionfilterattribute{public   override void onactionexecuted (ActionExecutedContext context) {}   Public override void OnActionExecuting (ActionExecutingContext context) {}}

In onactionexecuting, it is necessary to determine whether the static content has been generated, if the direct output has been generated, the logical implementation is as follows:

Generate the name of the static file according to certain rules, here is the string controllername = Context generated by the area+ "-" +controller+ "-" +action+key rule. routedata.values["Controller"]. ToString (). ToLower (); string actionname = Context. Routedata.values["Action"]. ToString (). ToLower (); string area = Context. routedata.values["Area"]. ToString (). ToLower ()///The key here is the default equals ID, of course we can configure a different key name string id = context. RouteData.Values.ContainsKey (Key)? Context. Routedata.values[key]. ToString (): "", if (string. IsNullOrEmpty (ID) && context. HttpContext.Request.Query.ContainsKey (Key)) {id = context. Httpcontext.request.query[key];} String filePath = Path.Combine (appcontext.basedirectory, "wwwroot", area, Controllername + "-" + ActionName + (string). IsNullOrEmpty (ID)? "": ("-" + ID) + ". html");//Determine if the file exists if (file.exists (FilePath)) {//if present, directly read the file using (FileStream fs = File.Open (Filepat       H, FileMode.Open)) {using (StreamReader sr = new StreamReader (FS, Encoding.UTF8)) {//Return file contents via Contentresult Contentresult Contentresult = new Contentresult ();       Contentresult. Content = Sr.       ReadToEnd (); Contentresult.       ContentType = "text/html"; Context.    Result = Contentresult; }  }}

In the onactionexecuted we need the result action result, determine whether the action result type is a viewresult, if the result is executed through code, get the result output, according to the same rules, generate static page, the concrete implementation is as follows

Get results Iactionresult ActionResult = context. Result;      Determine if the result is a ViewResult if (ActionResult is ViewResult) {ViewResult ViewResult = ActionResult as ViewResult; The following code executes the Viewresult and puts the HTML content of the result into a Stringbuiler object, var services = context.      Httpcontext.requestservices; var executor = Services.      Getrequiredservice<viewresultexecutor> (); var option = Services.      Getrequiredservice<ioptions<mvcviewoptions>> (); var result = executor.      Findview (context, viewResult); Result.      Ensuresuccessful (Originallocations:null); var view = result.      View;       StringBuilder builder = new StringBuilder ();          using (var writer = new StringWriter (builder)) {var viewcontext = new ViewContext (context, View, Viewresult.viewdata, Viewresult.tempdata, writer, option.         Value.htmlhelperoptions); View. Renderasync (ViewContext). Getawaiter ().        GetResult (); This sentence must be called, otherwise the content will be empty writeR.flush (); }//Generate static file names by rule string area = context. routedata.values["Area"]. ToString ().      ToLower (); String controllername = context. routedata.values["Controller"]. ToString ().      ToLower (); String actionname = context. Routedata.values["Action"]. ToString ().      ToLower (); String id = context. RouteData.Values.ContainsKey (Key)? Context. Routedata.values[key].      ToString (): ""; if (string. IsNullOrEmpty (ID) && context. HttpContext.Request.Query.ContainsKey (Key)) {id = context.      Httpcontext.request.query[key];      } String devicedir = Path.Combine (appcontext.basedirectory, "wwwroot", area); if (!      Directory.Exists (Devicedir)) {directory.createdirectory (devicedir); }//write file string filePath = Path.Combine (appcontext.basedirectory, "wwwroot", area, Controllername + "-" + actio Nname + (String. IsNullOrEmpty (ID)?      "": ("-" + ID) + ". html"); using (FileStream fs = File.Open (FilePath, FileMode.Create)) {uSing (StreamWriter sw = new StreamWriter (FS, Encoding.UTF8)) {SW. Write (builder.        ToString ());      }}//outputs the current result contentresult Contentresult = new Contentresult (); Contentresult. Content = Builder.      ToString (); Contentresult.      ContentType = "text/html"; Context.    Result = Contentresult; }

The key mentioned above, we directly add the corresponding property

public string key{  Get;set;}

This allows us to use this filter, using the method: Add [Staticfilehandlerfilter] on the controller or controller method, if you want to configure a different Key, you can use the [Staticfilehandlerfilter (key= " Set value ")]

Static has been implemented, we also need to consider the update, if the background to update an article, we have to update the static page, there are many scenarios: one is in the background for content updates, synchronization of the corresponding static page deleted. We introduce another kind of, regular update, that is, static pages have a certain period of validity, after the expiration date automatically updated. To implement this logic, we need to get the creation time of the static page in the OnActionExecuting method, then compare it to the current time, determine if it has expired, and if it has expired, continue with the subsequent logic if it is out of date. The specific code is as follows:

Gets the file information object FileInfo fileinfo=new fileInfo (FilePath);//settlement interval, if less than or equal to two minutes, the direct output, of course, the rules here can be changed to a timespan ts = DateTime.Now- Fileinfo.creationtime;if (TS. totalminutes<=2) {  using (FileStream fs = File.Open (FilePath, FileMode.Open))  {    using (StreamReader sr = New StreamReader (FS, Encoding.UTF8))    {      Contentresult contentresult = new Contentresult ();      Contentresult. Content = Sr. ReadToEnd ();      Contentresult. ContentType = "text/html";      Context. Result = Contentresult;}}  }

To this pseudo-static to achieve good. The current approach can only improve access performance to a certain extent, but it may not be enough for large portal systems. In the way described above, other functional extensions can be made, such as generating static pages that can be published to a CDN or published to a separate content server, and so on. No matter what the way, the realization of ideas are the same.

The above is the whole content of this article, I hope that everyone's learning has helped, but also hope that we support topic.alibabacloud.com.

Related Article

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.