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

Implementazione della funzione di statico falso in asp.net core mvc

      In sistemi web di grandi dimensioni, per migliorare le prestazioni di accesso al sistema, spesso si pubblicano contenuti che non cambiano spesso come pagine statiche, come le pagine dettaglio dei prodotti del negozio, le pagine dettaglio delle notizie. Queste informazioni, una volta pubblicate, non cambiano spesso. Se si utilizza ancora il metodo di output dinamico, ciò会造成服务器资源的巨大浪费。Ma non possiamo creare pagine statiche indipendenti per tutti questi contenuti. Pertanto, possiamo utilizzare il metodo di pseudo-staticizzazione nel sistema. Cosa significa pseudo-staticizzazione? Potete cercare su Baidu. Ora, vi spieghiamo come implementare la pseudo-staticizzazione in asp.net core mvc.

  Nel framework mvc, view rappresenta la vista, e il risultato dell'esecuzione è il contenuto finale inviato al browser del client, inclusi html, css, js ecc. Se vogliamo implementare la staticizzazione, dobbiamo salvare il risultato dell'esecuzione della view in un file statico, salvato in una posizione specifica, come disco, cache distribuita ecc. Così, la prossima volta che accediamo, possiamo leggere direttamente il contenuto salvato senza dover eseguire di nuovo la logica del business. Allora, come fare per implementare questa funzione in asp.net core mvc? La risposta è utilizzare i filtri. Nel framework mvc, sono disponibili molti tipi di filtri, e qui useremo il filtro di azione, che offre due momenti: prima e dopo l'esecuzione dell'azione. Possiamo verificare se è stato già generato una pagina statica prima dell'esecuzione dell'azione, e se è così, leggere direttamente il contenuto del file e inviarlo. Altrimenti, possiamo procedere come di solito, catturare il risultato dopo l'esecuzione dell'azione e salvare il contenuto statico generato.

  Allora, passiamo alla realizzazione del codice specifico. Prima di tutto, definiamo un tipo di filtro, che chiamiamo StaticFileHandlerFilterAttribute, una classe che deriva dal ActionFilterAttribute fornito dalla struttura di framework. StaticFileHandlerFilterAttribute sovrascrive due metodi forniti dalla classe base: OnActionExecuted (dopo l'esecuzione dell'azione) e OnActionExecuting (prima dell'esecuzione dell'azione). Ecco il codice specifico:

[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){}
}

Nella funzione OnActionExecuting, dobbiamo verificare se il contenuto statico è già stato generato, se lo è, eseguiamo direttamente il contenuto, la logica di implementazione è la seguente:

//Genera il nome del file statico secondo determinate regole, in questo caso è secondo il modello 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();
//L'oggetto Key di default è uguale a id, naturalmente possiamo configurare diversi nomi di 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");
//Verifica se il file esiste
if (File.Exists(filePath))
{
  //Se esiste, legge direttamente il file
  using (FileStream fs = File.Open(filePath, FileMode.Open))
  {
    using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
    {
       //Restituisci il contenuto del file tramite contentresult
       ContentResult contentresult = new ContentResult();
       contentresult.Content = sr.ReadToEnd();
       contentresult.ContentType = "text/html";
       context.Result = contentresult;
    }
  }
}

  Nella funzione OnActionExecuted, abbiamo bisogno del risultato dell'azione, dobbiamo verificare se il tipo di risultato dell'azione è un ViewResult, se lo è, eseguiamo il codice per ottenere l'output del risultato, come sopra, generiamo una pagina statica, l'implementazione dettagliata è la seguente:         

// Ottieni il risultato
IActionResult actionResult = context.Result;
 //Verifica se il risultato è un ViewResult
    if (actionResult is ViewResult)
    {
      ViewResult viewResult = actionResult as ViewResult;
      //Il codice seguente esegue questo ViewResult e mette il contenuto html del risultato in un oggetto StringBuilder
      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();
        //Questa frase deve essere chiamata, altrimenti il contenuto sarà vuoto
        writer.Flush();
      }
      //Per le regole generate il nome del file statico
      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);
      }
      //Scrittura del file
      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());
        }
      }
      //Output del risultato corrente
      ContentResult contentresult = new ContentResult();
      contentresult.Content = builder.ToString();
      contentresult.ContentType = "text/html";
      context.Result = contentresult;
    }

  Aggiungiamo direttamente l'attributo corrispondente alla chiave menzionata sopra

public string Key
{
  get;set;
}

  Così possiamo utilizzare questo filtro, il metodo di utilizzo: aggiungere l'attributo [StaticFileHandlerFilter] al controller o al metodo del controller, se si desidera configurare una chiave diversa, utilizzare [StaticFileHandlerFilter(Key="valore impostato")]

  La staticizzazione è già stata implementata, dobbiamo considerare anche l'aggiornamento, se il backend aggiorna un articolo, dobbiamo aggiornare anche la pagina statica. Ci sono molti piani: uno è eliminare contemporaneamente la pagina statica corrispondente durante l'aggiornamento del contenuto nel backend. Qui presentiamo un altro metodo, l'aggiornamento periodico, che consente alla pagina statica di avere una scadenza. Passata questa scadenza, l'aggiornamento avviene automaticamente. Per implementare questa logica, dobbiamo ottenere il tempo di creazione della pagina statica nel metodo OnActionExecuting, confrontarlo con l'ora corrente e determinare se è scaduto. Se non è scaduto, viene outputto direttamente il contenuto; se è scaduto, viene eseguita la logica successiva. Ecco il codice specifico:

//Ottenere l'oggetto informazioni sul file
FileInfo fileInfo=new FileInfo(filePath);
//Intervallo di chiusura, se è inferiore o uguale a due minuti, viene outputto direttamente, ovviamente le regole possono essere modificate
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;
    }
  }
}

  La pseudo-staticizzazione è stata implementata. Il metodo attuale può migliorare la prestazione di accesso in una certa misura, ma per sistemi di portale di grandi dimensioni, potrebbe non essere sufficiente. Seguendo il metodo descritto sopra, è possibile estendere altre funzionalità, come pubblicare le pagine statiche su CDN, o pubblicarle su un server di contenuto separato, ecc. Indipendentemente dal metodo, l'idea di implementazione è la stessa.

Questo è tutto il contenuto dell'articolo, speriamo che sia utile per la tua apprendimento, e speriamo che tu sostenga fortemente il tutorial di urla.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi autori, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato sottoposto a editing umano e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare