1

わかりました Web API ルーティングの楽しみ。

私のWeb APIルート構成は以下です。ジオコーディングと情報ルートのパフォーマンスは良好です。そして、なぜ検索がスイートに従っていないのか、私は混乱しています。

/*
    ==Geocoding Endpoints==
*/

config.Routes.MapHttpRoute(
    name: "v1_GeocodeApi",
    routeTemplate: "api/v{version}/{controller}/{street}/{zone}",
    defaults: new
    {
        action = "get",
        controller = "Geocode",
        version = "1"
    });

config.Routes.MapHttpRoute(
    name: "v1_GeocodeMultipleApi",
    routeTemplate: "api/v{version}/{controller}/multiple",
    defaults: new
    {
        action = "multiple",
        controller = "Geocode",
        version = "1"
    }); 

/*
    ==Search Endpoints==
*/

config.Routes.MapHttpRoute(
    name: "v1_SearchApi",
    routeTemplate: "api/v{version}/{controller}/{featureClass}/{returnValues}",
    defaults: new
    {
        action = "Get",
        controller = "Search",
        version = "1"
    });

/*
    ==Info Endpoints==
*/

config.Routes.MapHttpRoute(
    name: "v1_InfoApi",
    routeTemplate: "api/v{version}/{controller}/FeatureClassNames",
    defaults: new
    {
        action = "FeatureClassNames",
        controller = "Info",
        version = "1"
    });
}

のようなURLが欲しいですhttp://webapi/api/v1/search/fc/rv。この URL は、以下のスタック トレースを生成し、結果として 404 が生成されます。 get メソッドを備えたコントローラーがあれば、それがデフォルトで使用されるという慣習があると思いました。これは、最初のジオコーディング ルートで起こることのようです。

w3wp.exe Information: 0 : Request, Method=GET,
Url=http://webapi/api/v1/Search/fc/rv,
Message='http://webapi/api/v1/Search/fc/rv'
w3wp.exe Information: 0 : Message='Search',
Operation=RouteVersionedControllerSelector.SelectController w3wp.exe
Information: 0 :
Message='WebAPI.API.Controllers.API.Version1.SearchController',
Operation=DefaultHttpControllerActivator.Create w3wp.exe Information:
0 : Message='WebAPI.API.Controllers.API.Version1.SearchController',
Operation=HttpControllerDescriptor.CreateController w3wp.exe
Information: 0 : Message='Will use same 'JsonpMediaTypeFormatter'
formatter',
Operation=JsonpMediaTypeFormatter.GetPerRequestFormatterInstance
w3wp.exe Information: 0 : Message='Selected
formatter='JsonpMediaTypeFormatter', content-type='application/json;
charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate w3wp.exe
Warning: 0 : Message='UserMessage='No HTTP resource was found that
matches the request URI
'http://webapi/api/v1/Search/fc/rv'.',
MessageDetail='No action was found on the controller 'Search' that
matches the request.'',
Operation=ApiControllerActionSelector.SelectAction, Status=404
(NotFound), Exception=System.Web.Http.HttpResponseException:
Processing of the HTTP request resulted in an exception. Please see
the HTTP response returned by the 'Response' property of this
exception for details.    at
System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext
controllerContext)    at
System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()    at
System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter
traceWriter, HttpRequestMessage request, String category, TraceLevel
level, String operatorName, String operationName, Action`1 beginTrace,
Action execute, Action`1 endTrace, Action`1 errorTrace) w3wp.exe
Warning: 0 : Message='UserMessage='No HTTP resource was found that
matches the request URI
'http://webapi/api/v1/Search/fc/rv'.',
MessageDetail='No action was found on the controller 'Search' that
matches the request.'', Operation=SearchController.ExecuteAsync,
Status=404 (NotFound),
Exception=System.Web.Http.HttpResponseException: Processing of the
HTTP request resulted in an exception. Please see the HTTP response
returned by the 'Response' property of this exception for details.   
at
System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext
controllerContext)    at
System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()    at
System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter
traceWriter, HttpRequestMessage request, String category, TraceLevel
level, String operatorName, String operationName, Action`1 beginTrace,
Action execute, Action`1 endTrace, Action`1 errorTrace)    at
System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.System.Web.Http.Controllers.IHttpActionSelector.SelectAction(HttpControllerContext
controllerContext)    at
System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext
controllerContext, CancellationToken cancellationToken)    at
System.Web.Http.Tracing.Tracers.HttpControllerTracer.<>c__DisplayClass4.<System.Web.Http.Controllers.IHttpController.ExecuteAsync>b__0()
at
System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEndAsync[TResult](ITraceWriter
traceWriter, HttpRequestMessage request, String category, TraceLevel
level, String operatorName, String operationName, Action`1 beginTrace,
Func`1 execute, Action`2 endTrace, Action`1 errorTrace) w3wp.exe
Information: 0 : Response, Status=404 (NotFound), Method=GET,
Url=http://webapi/api/v1/Search/fc/rv,
Message='Content-type='application/json; charset=utf-8',
content-length=unknown'

/multiple を使用して 2 番目のジオコーディング ルートに似た別のルートを作成すると、ルート テンプレートapi/v{version}/{controller}/**for**/{featureClass}/{returnValues}が機能し、すべてが満足のいくものになります。

コントローラーの署名は

public class SearchController : ApiController
{
    [HttpGet]
    public async Task<HttpResponseMessage> Get(string featureClass, string returnValues, [FromUri] SearchOptions options)
    {
        // ...
    }
}

私の推測では、非同期タスク部分がデフォルトの get バインディングで何らかの形でそれを破棄していますが、変更されたルートで動作するため意味がありません。

4

1 に答える 1

1

リクエスト URLは、「stree」変数と「zone」変数を持つルートhttp://webapi/api/v1/search/fc/rvと一致しています。v1_GeocodeApiこれらの変数名は Search コントローラーの Get メソッドのパラメーター名と一致しないため、404 が表示されます。コントローラー名を変数として受け入れないようにルートを変更してみてくださいapi/v{version}/Geocode/{street}/{zone}api/v{version}/Search/{featureClass}/{returnValues}

于 2013-05-30T17:01:12.033 に答える