English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

asp.net core mvc Implementierung der Pseudostatischen Funktion

      In großen Websystemen wird oft, um die Systemzugriffsleistung zu verbessern, einige Inhalte, die nicht oft geändert werden, in statische Seiten veröffentlicht, wie z.B. die Produktseiten eines E-Commerce-Shops, die Detailseiten von Nachrichten. Diese Informationen ändern sich nach der Veröffentlichung nicht oft. Wenn man sie weiterhin in Form dynamischer Ausgaben verarbeitet, wird dies sicherlich großen Ressourcenverbrauch auf dem Server verursachen. Aber wir können diese Inhalte nicht alle unabhängig in statische Seiten umwandeln. Daher können wir im System eine Pseudostatisierung verwenden, was Pseudostatisierung ist, kann man im Internet suchen. Hier stellen wir eine Möglichkeit zur Implementierung der Pseudostatisierung in ASP.NET Core MVC vor.

  Im MVC-Framework repräsentiert view die Ansicht, und das Ergebnis ihrer Ausführung ist der Inhalt, der letztlich an den Clientbrowser ausgegeben wird, einschließlich html, css, js und so weiter. Wenn wir eine Verifikation implementieren möchten, müssen wir das Ergebnis der view-Ausführung in eine statische Datei speichern, die an einem bestimmten Ort abgelegt wird, wie z.B. auf einer Festplatte, in einem verteilten Cache usw. Wenn der Zugriff darauf erneut erfolgt, kann der gespeicherte Inhalt direkt gelesen und ausgegeben werden, ohne dass eine erneute Ausführung der Geschäftslogik erforderlich ist. Wie sollte man dies in ASP.NET Core MVC umsetzen? Die Antwort ist, einen Filter zu verwenden. Im MVC-Framework werden verschiedene Filter-Typen bereitgestellt, und hier verwenden wir den Action-Filter. Der Action-Filter bietet zwei Zeitpunkte: vor dem Ausführen der Aktion und nach dem Ausführen der Aktion. Wir können vor dem Ausführen der Aktion überprüfen, ob bereits eine statische Seite generiert wurde. Wenn ja, können wir den Dateiinhalt direkt lesen und ausgeben, und die nachfolgende Logik überspringen. Wenn nicht, gehen wir weiter und fangen wir das Ergebnis in dieser Phase nach dem Ausführen der Aktion ab und speichern die generierte statische Inhalte.

  Dann kommen wir zur konkreten Implementierung des Codes. Zunächst definieren wir einen Filter-Typ, den wir StaticFileHandlerFilterAttribute nennen. Diese Klasse leitet sich von der in der Framework bereitgestellten ActionFilterAttribute ab. StaticFileHandlerFilterAttribute überschreibt die beiden Methoden der Basisklasse: OnActionExecuted (nach dem Ausführen der Aktion) und OnActionExecuting (vor dem Ausführen der Aktion). Der spezifische Code lautet 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 muss überprüft werden, ob das statische Inhalt bereits generiert wurde, wenn ja, wird das Inhalt direkt ausgegeben, die Implementierung des Logik ist wie folgt:

//Nach bestimmten Regeln wird der Name der statischen Datei generiert, hier wird nach area generiert+"-"+controller+"-"+action+Schlüssel-Regelgenerierung
string controllerName = context.RouteData.Values["controller"].ToString().ToLower();
string actionName = context.RouteData.Values["action"].ToString().ToLower();
string area = context.RouteData.Values["area"].ToString().ToLower();
//Hier entspricht der Schlüssel standardmäßig der id, natürlich können wir unterschiedliche Schlüsselnamen konfigurieren
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
//Prüfen Sie, ob die Datei existiert
if (File.Exists(filePath))
{
  //Wenn es existiert, wird die Datei direkt gelesen
  using (FileStream fs = File.Open(filePath, FileMode.Open))
  {
    using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
    {
       //Durch contentresult wird der Dateiinhalt zurückgegeben
       ContentResult contentresult = new ContentResult();
       contentresult.Content = sr.ReadToEnd();
       contentresult.ContentType = "text/html";
       context.Result = contentresult;
    }
  }
}

  In OnActionExecuted benötigen wir das Ergebnis der Aktion, prüfen Sie den Typ des Aktionsergebnisses, ob es ein ViewResult ist, und führen Sie den Code aus, um das Ergebnis abzurufen, um die Ausgabe zu generieren, wie oben beschrieben, die konkrete Implementierung ist wie folgt         

//Erhalten Sie das Ergebnis
IActionResult actionResult = context.Result;
 //Prüfen Sie, ob das Ergebnis ein ViewResult ist
    if (actionResult is ViewResult)
    {
      ViewResult viewResult = actionResult as ViewResult;
      //Das folgende Code führt diesen ViewResult aus und platziert den html-Inhalt in ein StringBuiler-Objekt.
      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();
        //Dieser Aufruf muss unbedingt aufgerufen werden, andernfalls bleibt der Inhalt leer
        writer.Flush();
      }
      //nach den Regeln generierte statische Dateinamen
      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);
      }
      //Datei schreiben
      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());
        }
      }
      //Aktuelle Ergebnisse ausgeben
      ContentResult contentresult = new ContentResult();
      contentresult.Content = builder.ToString();
      contentresult.ContentType = "text/html";
      context.Result = contentresult;
    }

  Der oben erwähnte Schlüssel, wir fügen die entsprechenden Eigenschaften hinzu

public string Key
{
  get;set;
}

  So können wir diesen Filter verwenden. Die Methode der Verwendung: Fügen Sie die Eigenschaft [StaticFileHandlerFilter] auf dem Controller oder dem Controller-Methoden hinzu. Wenn Sie verschiedene Schlüssel konfigurieren möchten, verwenden Sie [StaticFileHandlerFilter(Key = "Eingestellter Wert")]

  Die Statikalisierung ist bereits implementiert, wir müssen jedoch über Aktualisierungen nachdenken. Wenn im Hintergrund ein Artikel aktualisiert wird, müssen wir auch die statischen Seiten aktualisieren. Es gibt viele Lösungen: Eine Möglichkeit ist, die entsprechenden statischen Seiten beim同期 der Inhaltaktualisierung im Hintergrund zu löschen. Wir beschreiben hier eine andere Methode, die zeitraumgesteuerte Aktualisierung, bei der die statischen Seiten eine bestimmte Gültigkeitsdauer haben und nach Ablauf dieser Frist automatisch aktualisiert werden. Um diese Logik zu realisieren, müssen wir im OnActionExecuting-Methoden die Erstellungszeit der statischen Seite abrufen und sie mit der aktuellen Zeit vergleichen, um zu bestimmen, ob sie abgelaufen ist. Wenn sie noch nicht abgelaufen ist, wird direkt der Inhalt ausgegeben, wenn sie abgelaufen ist, wird die nachfolgende Logik fortgesetzt. Das spezifische Codebeispiel ist wie folgt:

//Dateiinformationenobjekt abrufen
FileInfo fileInfo = new FileInfo(filePath);
//Abrechnungsintervall, wenn es weniger als oder gleich zwei Minuten beträgt, wird direkt ausgegeben, natürlich können hier die Regeln geändert werden
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;
    }
  }
}

  Die Pseudo-Static-Verarbeitung ist abgeschlossen. Derzeitige Verarbeitungsmethoden können den Zugriff auf die Leistung in gewissem Maße verbessern, aber für große Portalsysteme möglicherweise nicht ausreichend sein. Nach dem oben beschriebenen Verfahren können weitere Funktionalitäten erweitert werden, z.B. können nach der Erstellung von Static-Pages diese auf einem CDN veröffentlicht oder auf einem separaten Content-Server veröffentlicht werden, etc. Unabhängig von der Methode ist der Implementierungsansatz derselbe.

Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die呐喊教程 unterstützen.

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem jeweiligen Urheber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine Haftung für rechtliche Verpflichtungen. Wenn Sie urheberrechtlich geschützte Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine E-Mail senden, und geben Sie relevante Beweise an. Sobald nachgewiesen wird, dass Inhalte urheberrechtlich geschützt sind, wird diese Website die betreffenden Inhalte sofort löschen.)

Gefällt mir