ホームページ  >  記事  >  バックエンド開発  >  asp.net core mvcは擬似静的関数を実装します

asp.net core mvcは擬似静的関数を実装します

高洛峰
高洛峰オリジナル
2017-02-20 17:00:221404ブラウズ

この記事では、主に疑似静的関数を実装するための asp.net core mvc の関連情報を詳しく紹介します。興味のある方は参考にしてください。

大規模な Web サイト システムでは、システム アクセスを向上させるため。モールの商品詳細ページやニュース詳細ページなど、まれなコンテンツは静的ページとして公開されることが多く、動的出力も処理に使用される場合、変更の頻度はそれほど高くありません。それは間違いなくサーバー上のリソースを大量に浪費することになります。ただし、これらのコンテンツに対して独自に静的ページを作成することはできないため、システム内で擬似静的処理を使用できます。擬似静的とは何かについては、Baidu で検索できます。ここではasp.net core mvcで擬似静的を実装する方法を紹介しましょう。

MVCフレームワークでは、viewはビューを表し、その実行結果が最終的にクライアントのブラウザに出力されるhtml、css、jsなどのコンテンツとなります。静的化を実現したい場合は、ビューの実行結果を静的ファイルとして保存し、ディスクや分散キャッシュなどの指定された場所に保存する必要があります。これにより、保存された内容を次回実行するときに直接読み取ることができます。ビジネス ロジックを再度実行する必要はありません。では、そのような機能を実現するには、asp.net core mvc は何をすべきでしょうか?答えは、フィルターを使用することです。MVC フレームワークでは、複数のフィルター タイプが提供されています。ここでは、アクション フィルターによって、アクションの実行前とアクションの実行後の 2 つの時点が提供されます。アクションが実行される前に、まず静的ページが生成されているかどうかを判断できます。生成されている場合は、ファイルの内容を直接読み取って出力することができ、後続のロジックはスキップされます。プロダクションがない場合は、ダウンを続け、アクションの実行後のこの段階で結果をキャプチャし、結果によって生成された静的コンテンツを保存します。

次に、具体的な実装コードに移りましょう。まず、StaticFileHandlerFilterAttribute と呼ばれるフィルター タイプを定義します。このクラスは、フレームワークで提供される 2 つのメソッド OnActionExecuted をオーバーライドします。

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

OnActionExecutingでは、直接出力コンテンツが生成されているかどうかを判定する必要があります。

//按照一定的规则生成静态文件的名称,这里是按照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;
    }
  }
}

OnActionExecuted では、アクション結果のタイプが ViewResult であるかどうかを判断するためにアクション結果が必要です。結果がコードを通じて実行された場合、結果出力を取得して生成します。上記と同じルールに従った静的ページの具体的な実装は次のとおりです

//获取结果
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;
    }

上記のキーに対して、対応する属性を直接追加します

public string Key
{
  get;set;
}

そのため、このフィルターを使用できます。使用方法: [StaticFileHandlerFilter] 機能をコントローラーまたはコントローラー メソッドに追加します。 異なるキーを設定したい場合は、[StaticFileHandlerFilter(Key="set value")] を使用できます

静的化は実装されていますが、まだです。記事がバックグラウンドで更新される場合、静的ページも更新する必要があります。解決策は多数あります。1 つは、コンテンツがバックグラウンドで更新されるときに、対応する静的ページを同期的に削除することです。ここでは、もう 1 つのスケジュールされた更新を紹介します。これは、静的ページには一定の有効期間があり、この有効期間の後に自動的に更新されることを意味します。このロジックを実装するには、OnActionExecuting メソッドで静的ページの作成時刻を取得し、それを現在の時刻と比較して、有効期限が切れていないかどうかを判断する必要があります。有効期限が切れていない場合は、コンテンツが直接出力されます。有効期限が切れている場合は、次のロジックの実行を続けます。具体的なコードは次のとおりです:

//获取文件信息对象
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;
    }
  }
}

この時点で、擬似静的が実現されます。現在の処理方法ではアクセス性能をある程度向上させることしかできませんが、大規模なポータルシステムでは十分ではない可能性があります。上記で紹介した方法によれば、静的ページを生成した後にCDNに公開したり、別のコンテンツサーバーに公開したりするなど、他の機能拡張も行うことができます。どのような方法であっても実装の考え方は同じです。

以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。

疑似静的関数を実装する asp.net core mvc に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。