2016-04-22 3 views
1

私はWebApiを使用していましたが、WebApiを使用してRoute Attributeを使用した場合とWebApiを使用する場合の違いが機能名に基づいて自動的に作成される方法を理解しようとしています。 WebApi RouteAttributeまたは暗黙的なルーティングを使用する場合のパスの違い

routingManager.RegisterVersionedHttpRoute(
       routeName: "MyController", 
       routeTemplate: "MyController/{param}", 
       defaults: new { controller = "MyController", param = RouteParameter.Optional }, 
       version: ApiVersion.Version); 

私が構築し、私のAPIをテスト

は、両方のエンドポイントが正常にアクセスできます。

public class MyController : RestControllerBase 
{ 
    public async Task<HttpResponseMessage> GetData() 
    { 
     return _data; 
    } 

    [Route(ApiVersion.Version + "/MyController/{param}/specific/route")] 
    public async Task<HttpResponseMessage> GetMoreData() 
    { 
     return _moreData; 
    } 
} 

このコントローラと他の人がすべてないルートレジストリを指定します。私は、このフォームの多くのコントローラを持っています。

また、HttpControllerSelectorを名前空間に基づいてオーバーライドしました(バージョン管理用)。

私の問題は、特定のhttpルートによって呼び出される伝統的な機能に加えて、これらの2つのルートが異なる動作をすることです。例えば、私のオーバーライドされたコントローラセレクタに私が適切にマップするためのコントローラとルートのために、このロジックを記述する必要がありました:

private string GetControllerName(IHttpRouteData routeData) 
{ 
    if (routeData.GetSubRoutes() != null) 
    { 
     // With route attribute 
     var subroute = routeData.GetSubRoutes().FirstOrDefault(); 
     var dataTokenValue = subroute.Route.DataTokens["actions"]; 
     if (dataTokenValue == null) return null; 
     var controllername = ((HttpActionDescriptor[])dataTokenValue).First().ControllerDescriptor.ControllerName.Replace("Controller", string.Empty); 
     return controllername; 
    } 
    else 
    { 
     // Try Strategy for without route attribute. 
     return (String)routeData.Values["controller"]; 
    } 
} 

private string GetVersion(IHttpRouteData routeData) 
{ 
    var routeTemplate = ""; 
    if (routeData.GetSubRoutes() != null) 
    { 
     var subRouteData = routeData.GetSubRoutes().FirstOrDefault(); 
     if (subRouteData == null) return null; 
     routeTemplate = subRouteData.Route.RouteTemplate; 
    } 
    else 
    { 
     routeTemplate = routeData.Route.RouteTemplate; 
    } 

    var index = routeTemplate.IndexOf("/"); 
    if (index == -1) 
    { 
     return Unversioned; 
    } 
    var version = routeTemplate.Substring(0, index).ToUpperInvariant(); 
    return version; 
} 

明示的な属性を持つルートが利用可能route.GetSubroutesを()がありますかのように思え一方、暗黙の経路はそうしない。 これは、正しくルーティングする前に、着信要求からバージョンとコントローラ名を抽出する2つの異なる方法を書いています。私はそれで暮らすことができますが、WebApiの内部の何かがルート間のこの区別を作り出していることは、本当に気になります。

残念なことに、私はhttps://github.com/domaindrivendev/Swashbuckleと協力して私のAPIを文書化し、同様の問題に遭遇しました。スワッガーページはRoute属性を持つルートに対しては正しく生成されますが、暗黙のルートは完全に無視されます。私はこの問題を引き起こしている問題が私の選択ロジックの分岐を引き起こすのと同じであると考えています。

私はオンラインで見つけることができるほど多くのApiExplorer、WebAPIおよびその他のドキュメントを掘り下げてきましたが、暗黙的/明示的なルートアプローチを均質化するソリューションを見つけることができませんでした。実装上のバグかもしれません。

どこから行くべきですか?

答えて

0

ここでの答えは、Web Api 2にバグまたは不一致があることです。 確認するには、このコードスニペットを実行できます。私が言及した場合、ApiExplorerは経路属性で明示的にマークされていない経路については結果を返さない。

 IApiExplorer apiExplorer = configuration.Services.GetApiExplorer(); 
     foreach (ApiDescription api in apiExplorer.ApiDescriptions) 
     { 
      Console.WriteLine("Uri path: {0}", api.RelativePath); 
      Console.WriteLine("HTTP method: {0}", api.HttpMethod); 
      foreach (ApiParameterDescription parameter in api.ParameterDescriptions) 
      { 
       Console.WriteLine("Parameter: {0} - {1}", parameter.Name, parameter.Source); 
      } 
      Console.WriteLine(); 
     } 
関連する問題