2017-09-11 4 views
1

WebApi 2コントローラは、同じプロジェクト内の単一のODataコントローラと並行して動作します。私がしようとするとは 他のすべての要求は、通常のWeb APIをコントローラに向けられるべきこのODataController ODataメソッドを単一コントローラに限定する適切な方法は何ですか?

  • にマッピングする必要があり/API

    • すべての要求を

    を:必要なルーティング設定を設定しようとすると、このようのOData contollerに/APIルートをマップします

    class WebApiConfig 
    { 
        public static void Register(HttpConfiguration configuration) 
        { 
        configuration.Routes.MapHttpRoute("API Default", "api/{action}/{id}", 
         new { controller = "ApiOdata", id = RouteParameter.Optional }); 
    
        ODataModelBuilder builder = new ODataConventionModelBuilder(); 
        builder.EntitySet<Organization>("Organizations"); 
        configuration.Routes.MapODataServiceRoute(
         routeName: "ODataRoute", 
         routePrefix: "Api", 
         model: builder.GetEdmModel()); 
        } 
    } 
    

    すべてのメソッド呼び出しはWeb ApiとODataコントローラの両方に問題なく動作しますが、/api/$ metadataなどのリクエストは機能しません。

    私は、 "APIのデフォルトの" ルート削除 - (404を返す)動作を停止したが、/API/$メタデータがに始まるのODataコントローラ方法など/API /団体への要求を。

    詳細404エラーメッセージ:

    <Error> 
    <Message> 
        No HTTP resource was found that matches the request URI 'http://localhost:53576/api/Organizations'. 
    </Message> 
    <MessageDetail> 
        No type was found that matches the controller named 'Organizations'. 
    </MessageDetail> 
    </Error> 
    

    単一のコントローラのアクションにすべてのODataの呼び出しをマップする適切な方法は何ですか?

  • 答えて

    0

    最終的にカスタムルーティングの慣習に終わった。そのために追加されたクラス:

    public class CustomControllerRoutingConvention : IODataRoutingConvention 
    { 
        public string SelectAction(System.Web.OData.Routing.ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) 
        { 
         if (odataPath.PathTemplate.StartsWith("~/entityset") 
          || odataPath.PathTemplate.StartsWith("~/unboundfunction")) 
         { 
          return odataPath.Segments[0].Identifier; 
         } 
         // Not a match. 
         return null;  
        } 
    
        public string SelectController(System.Web.OData.Routing.ODataPath odataPath, HttpRequestMessage request) 
        { 
         if (!odataPath.PathTemplate.Contains("$metadata")) 
         { 
          if (odataPath.PathTemplate != "~") 
          { 
           return "ApiOdata"; 
          } 
         } 
         return null; 
        } 
    } 
    

    とWebApiConfig.csの登録方法でそれを使用します。

    public static void Register(HttpConfiguration configuration) 
    { 
        ... 
        IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault(); 
        routingConventions.Insert(0, new CustomControllerRoutingConvention()); 
    
        configuration.MapODataServiceRoute(
         routeName: "ODataRoute", 
         routePrefix: "Api", 
         pathHandler: new DefaultODataPathHandler(), 
         routingConventions: routingConventions, 
         model: builder.GetEdmModel()); 
    } 
    

    それは完璧なソリューションではありませんし、すべてのOData要求(メタデータのみ、entitysetsと結合していない機能を果たしていません、 "api/Organizations"のように)、o.jsやSimple.Odata.Clientのようなクライアントで作業するには十分です。 また、私のプロジェクトでは、コントローラーの混乱や膨張を避けることができました。

    関連する問題