Heim  >  Artikel  >  Backend-Entwicklung  >  asp.net core mvc implementiert pseudostatische Funktionen

asp.net core mvc implementiert pseudostatische Funktionen

高洛峰
高洛峰Original
2017-02-20 17:00:221448Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen zum asp.net-Kern-MVC im Detail vor. Er hat einen bestimmten Referenzwert.

In großen Website-Systemen Um die Systemzugriffsleistung zu verbessern, werden einige seltene Inhalte häufig als statische Seiten veröffentlicht, z. B. die Produktdetailseite und die Nachrichtendetailseite des Einkaufszentrums. Sobald diese Informationen veröffentlicht sind, ist die Häufigkeit von Änderungen nicht sehr hoch Durch dynamische Ausgabe verarbeitet, führt dies definitiv zu einer enormen Ressourcenverschwendung auf dem Server. Wir können jedoch keine unabhängigen statischen Seiten für diese Inhalte erstellen, sodass wir im System eine pseudostatische Verarbeitung verwenden können. Was Pseudostatik ist, können Sie auf Baidu durchsuchen. Lassen Sie uns hier vorstellen, wie Pseudostatik in asp.net Core MVC implementiert wird.

Im MVC-Framework stellt die Ansicht die Ansicht dar, und das Ergebnis ihrer Ausführung ist der Inhalt, der letztendlich an den Client-Browser ausgegeben wird, einschließlich HTML, CSS, JS usw. Wenn wir eine Statik erreichen möchten, müssen wir das Ergebnis der Ansichtsausführung als statische Datei speichern und an einem bestimmten Ort speichern, z. B. auf der Festplatte, im verteilten Cache usw., damit wir den gespeicherten Inhalt beim nächsten Mal direkt lesen können Zugriff darauf ist nicht erforderlich. Was sollte asp.net core mvc also tun, um eine solche Funktion zu erreichen? Die Antwort ist die Verwendung von Filtern. Im MVC-Framework werden mehrere Filtertypen bereitgestellt. Aktionsfilter stellen zwei Zeitpunkte bereit: vor der Ausführung der Aktion. Wir können zunächst feststellen, ob die statische Seite generiert wurde, bevor die Aktion ausgeführt wird. Wenn sie generiert wurde, können wir den Dateiinhalt direkt lesen und ausgeben, und die nachfolgende Logik wird übersprungen. Wenn keine Produktion erfolgt, fahren Sie mit dem Herunterfahren fort, erfassen Sie die Ergebnisse in dieser Phase nach Ausführung der Aktion und speichern Sie dann den durch die Ergebnisse generierten statischen Inhalt.

Dann kommen wir zum spezifischen Implementierungscode, den wir StaticFileHandlerFilterAttribute nennen. Diese Klasse wird vom ActionFilterAttribute abgeleitet, das im Framework bereitgestellt wird, und überschreibt die beiden von der Basisklasse bereitgestellten Methoden. OnActionExecuted( Nachdem die Aktion ausgeführt wurde), OnActionExecuting (bevor die Aktion ausgeführt wurde), lautet der spezifische Code wie folgt:

[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, Sie Sie müssen feststellen, ob der statische Inhalt generiert wurde. Wenn der direkte Ausgabeinhalt generiert wurde, lautet die Logikimplementierung wie folgt:

//按照一定的规则生成静态文件的名称,这里是按照area+"-"+controller+"-"+action+key规则生成
string controllerName = context.RouteData.Values["controller"].ToString().ToLower();
string actionName = context.RouteData.Values["action"].ToString().ToLower();
string area = context.RouteData.Values["area"].ToString().ToLower();
//这里的Key默认等于id,当然我们可以配置不同的Key名称
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");
//判断文件是否存在
if (File.Exists(filePath))
{
  //如果存在,直接读取文件
  using (FileStream fs = File.Open(filePath, FileMode.Open))
  {
    using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
    {
       //通过contentresult返回文件内容
       ContentResult contentresult = new ContentResult();
       contentresult.Content = sr.ReadToEnd();
       contentresult.ContentType = "text/html";
       context.Result = contentresult;
    }
  }
}

In OnActionExecuted, Wir benötigen das Aktionsergebnis, um zu bestimmen, ob der Aktionsergebnistyp ein ViewResult ist. Wenn das Ergebnis über Code ausgeführt wird, wird die Ergebnisausgabe abgerufen und eine statische Seite gemäß den gleichen Regeln wie oben generiert

//获取结果
IActionResult actionResult = context.Result;
 //判断结果是否是一个ViewResult
    if (actionResult is ViewResult)
    {
      ViewResult viewResult = actionResult as ViewResult;
      //下面的代码就是执行这个ViewResult,并把结果的html内容放到一个StringBuiler对象中
      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();
        //这句一定要调用,否则内容就会是空的
        writer.Flush();
      }
      //按照规则生成静态文件名称
      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);
      }
 
      //写入文件
      string filePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", area, controllerName + "-" + actionName + (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());
        }
      }
      //输出当前的结果
      ContentResult contentresult = new ContentResult();
      contentresult.Content = builder.ToString();
      contentresult.ContentType = "text/html";
      context.Result = contentresult;
    }

oben erwähnter Schlüssel, wir fügen direkt das entsprechende Attribut hinzu

public string Key
{
  get;set;
}

Damit wir diesen Filter verwenden können, verwenden wir die Methode: Fügen Sie im Controller oder in der Controller-Methode die Funktion [StaticFileHandlerFilter] hinzu. Wenn Sie verschiedene Schlüssel konfigurieren möchten, können Sie [StaticFileHandlerFilter(Key="set value")]

Wir müssen auch Aktualisierungen berücksichtigen. Nach dem Aktualisieren eines Artikels müssen wir auch die statische Seite aktualisieren. Eine davon besteht darin, die entsprechende statische Seite zu löschen Der Inhalt wird im Hintergrund aktualisiert. Wir stellen hier eine weitere Funktion vor, die geplante Aktualisierung. Dies bedeutet, dass die statische Seite eine bestimmte Gültigkeitsdauer hat und nach dieser Gültigkeitsdauer automatisch aktualisiert wird. Um diese Logik zu implementieren, müssen wir die Erstellungszeit der statischen Seite in der OnActionExecuting-Methode ermitteln und sie dann mit der aktuellen Zeit vergleichen, um festzustellen, ob sie abgelaufen ist. Wenn sie nicht abgelaufen ist, wird der Inhalt direkt ausgegeben Es ist abgelaufen. Führen Sie die folgende Logik weiter aus. Der spezifische Code lautet wie folgt:

//获取文件信息对象
FileInfo fileInfo=new FileInfo(filePath);
//结算时间间隔,如果小于等于两分钟,就直接输出,当然这里的规则可以改
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;
    }
  }
}

An diesem Punkt wird Pseudostatik erreicht. Die aktuelle Verarbeitungsmethode kann die Zugriffsleistung nur bis zu einem gewissen Grad verbessern, reicht für große Portalsysteme jedoch möglicherweise nicht aus. Gemäß der oben vorgestellten Methode können weitere funktionale Erweiterungen durchgeführt werden. Beispielsweise kann eine statische Seite nach dem Generieren auf einem CDN oder auf einem separaten Inhaltsserver veröffentlicht werden usw. Unabhängig von der Methode ist die Implementierungsidee dieselbe.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er zum Lernen aller beiträgt. Ich hoffe auch, dass jeder die PHP-Chinesisch-Website unterstützt.

Weitere Artikel zur Implementierung pseudostatischer Funktionen durch asp.net core mvc finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn