ホームページ  >  記事  >  バックエンド開発  >  ASP.NET Core MVC グローバル ルーティング プレフィックスを構成する

ASP.NET Core MVC グローバル ルーティング プレフィックスを構成する

高洛峰
高洛峰オリジナル
2017-02-07 11:29:401614ブラウズ

ASP.NET Core MVC はグローバル ルーティング プレフィックスを構成します

はじめに

皆さんこんにちは。今日は、グローバル ルーティングに統一プレフィックスを追加する ASP.NET Core MVC の新機能を紹介します。厳密に言えば、これは新しい機能ではありませんが、Core MVC に固有の機能です。

アプリケーションの背景

Web API アプリケーションを作成しているときに、このシナリオに遭遇したことがあるかどうかはわかりません。つまり、すべてのインターフェイスが /api で始まり、API インターフェイスのリクエスト アドレスは次のようになります。

http://www.example.com/api/order/333

またはそのような要件

http://www.example.com/api/v2/order/333

以前は、この要件を達成したい場合は、[Route("/api/order")] のようなルーティング属性をコントローラーに追加すると、MVC フレームワークがルーティング テーブルをスキャンして /api/ order のようなリクエストと一致します。

しかし、2 番目の要件はバージョン番号を持つことです。元のコントローラーのルート定義は [Route("/api/v1/order")] であり、v2 にアップグレードする必要があります。 1 つの変更が必要です。混乱を引き起こす可能性があります。

これを行うための、よりシンプルで洗練された方法があります。以下を見てみましょう。

IApplicationModelConvention インターフェイス

まず、Microsoft.AspNetCore.Mvc.ApplicationModels 名前空間にある IApplicationModelConvention インターフェイスを使用する必要があります。インターフェイスの定義を見てみましょう。

public interface IApplicationModelConvention
{
 void Apply(ApplicationModel application);
}

MVC フレームワークにはいくつかの規則があることがわかっているため、このインターフェイスは主に、いくつかの MVC 規則をカスタマイズするために使用されます。ApplicationModel オブジェクトを指定することで、いくつかの規則を追加または変更できます。インターフェイスが ApplicationModel オブジェクトを持った apply メソッドを提供していることがわかります。このオブジェクトを使用して必要なものを変更できます。MVC フレームワーク自体がサービスの開始時にこのインターフェイスを挿入するため、このインターフェイスを実装するだけで済みます。わずかに設定できます。

次に、ApplicationModel オブジェクトが持つものを見てみましょう:

public class ApplicationModel : IPropertyModel, IFilterModel, IApiExplorerModel
{
 public ApiExplorerModel ApiExplorer { get; set; }
 public IList<ControllerModel> Controllers { get; }
 public IList<IFilterMetadata> Filters { get; }
 
 public IDictionary<object, object> Properties { get; }
}

ApiExplorer、Controllers、Filters、Properties などのプロパティがあることがわかります。

ApiExplorerModel: 主に、API 説明情報、グループ情報、可視性など、デフォルトの MVC API エクスプローラーの一部を構成します。

ControllerModel: 主に Comtroller のデフォルトの規則に関連するものです。これには多くのものが含まれるため、後でその中の 1 つを設定します。

IFilterMetadata: 空のインターフェイス。主にマーカーとして使用されます。

もう 1 つお伝えしなければならないことは、上記の Controllers プロパティが IList260f4f23b72e59e1deffd15c9afd20b6 であることがわかります。つまり、このリストにはプログラム内のすべてのコントローラーの情報が記録されており、メソッドが設定されていることがわかります。コントローラー内のアクションの情報も含めて、この機能を使用して MVC フレームワークを柔軟に変更できます。

次に、この機能を使用して今日のテーマを実装します。高評価ありがとうございます~ :)

グローバルルーティングに統一プレフィックスを追加してください

これ以上ナンセンスは必要ありません。コードに直接アクセスしてください。言いたいことはすべてコードの中にあります:

//定义个类RouteConvention,来实现 IApplicationModelConvention 接口
public class RouteConvention : IApplicationModelConvention
{
 private readonly AttributeRouteModel _centralPrefix;
 
 public RouteConvention(IRouteTemplateProvider routeTemplateProvider)
 {
  _centralPrefix = new AttributeRouteModel(routeTemplateProvider);
 }
 
 //接口的Apply方法
 public void Apply(ApplicationModel application)
 {
  //遍历所有的 Controller
  foreach (var controller in application.Controllers)
  {
   // 已经标记了 RouteAttribute 的 Controller
   var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
   if (matchedSelectors.Any())
   {
    foreach (var selectorModel in matchedSelectors)
    {
     // 在 当前路由上 再 添加一个 路由前缀
     selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_centralPrefix,
      selectorModel.AttributeRouteModel);
    }
   }
 
   // 没有标记 RouteAttribute 的 Controller
   var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
   if (unmatchedSelectors.Any())
   {
    foreach (var selectorModel in unmatchedSelectors)
    {
     // 添加一个 路由前缀
     selectorModel.AttributeRouteModel = _centralPrefix;
    }
   }
  }
 }
}


それから、このクラスは自分たちで定義しました。

public static class MvcOptionsExtensions
{
 public static void UseCentralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
 {
  // 添加我们自定义 实现IApplicationModelConvention的RouteConvention
  opts.Conventions.Insert(0, new RouteConvention(routeAttribute));
 }
}

最後に、Startup.cs ファイルに上記の拡張メソッドを追加するだけです。

public class Startup
{
 public Startup(IHostingEnvironment env)
 {
  //...
 }
 
 public void ConfigureServices(IServiceCollection services)
 {
  //...
   
  services.AddMvc(opt =>
  {
   // 路由参数在此处仍然是有效的,比如添加一个版本号
   opt.UseCentralRoutePrefix(new RouteAttribute("api/v{version}"));
  });
 }
 
 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
  //...
   
  app.UseMvc();
 }
}

このうち、opt.UseCentralRoutePrefix は上記で定義した拡張メソッドであり、ルーティング パラメーターはここでも利用できるため、たとえば、インターフェイスのバージョン番号を指定できます。この後、すべてのコントローラの RoteAttribute にこのプレフィックスが追加され、元のバージョン番号の要件が完全に解決されます。それらは次のようになります:

[Route("order")]
public class OrderController : Controller
{
 // 路由地址 : /api/v{version}/order/details/{id}
 [Route("details/{id}")]
 public string GetById(int id, int version)
 {
  //上面是可以接收到版本号的,返回 version 和 id
  return $"other resource: {id}, version: {version}";
 }
}
 
public class ItemController : Controller
{
 // 路由地址: /api/v{version}/item/{id}
 [Route("item/{id}")]
 public string GetById(int id, int version)
 {
  //上面是可以接收到版本号的,返回 version 和 id
  return $"item: {id}, version: {version}";
 }
}

概要

上記の太字の言葉は、誰もがそれを理解して適用できることを願っています。この例は実際のニーズにおける非常に小さなシナリオにすぎず、特定のプロジェクトにもいくつか存在するでしょう。実際、MVC フレームワークについては、設計上の考え方やスケーラビリティなど、理解する必要があることがたくさんあります。 ASP.NET Core に興味がある場合は、学習結果の一部をブログで定期的に共有しますので、フォローしてください。

この記事が皆さんのお役に立てれば幸いです。このサイトを応援していただきありがとうございます!

ASP.NET Core MVC のグローバル ルーティング プレフィックスの構成に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。


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