2017-08-07 32 views
0

我想調用基於查詢字符串參數的不同操作方法,例如webapi/mycontroller?action=getuser&id=10應該調用mycontroller.getuser(10)操作方法,而webapi/mycontroller?action=getallusers應該調用mycontroller.getallusers()操作方法。我試着寫下列方式路由:如何在Asp.Net WebApi中配置路徑以將操作方法​​名稱用作查詢參數?

config.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "webapi/{controller}?action={action}" 
      ); 

但是,這是不允許的,視覺工作室給我的錯誤The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character

+2

更好地創建所有api端點並使用路由屬性,以便獲取諸如webapi/getallusers,webapi/getuser/{id}之類的內容。閱讀https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 –

+0

不幸的是,這是要求,路線必須是'webapi/mycontroller?action = getallusers'而不是'webapi/mycontroller/getallusers' –

+0

獲取需求變更!看起來很奇怪的是,你的服務合同是按照你的規定處理的,通常情況下,這是另一種方式,「這裏是我的API,這就是你如何使用它」。我不明白爲什麼客戶端無法調用webapi直接使用的URL。 –

回答

1

所以我敲的東西在一起,可以幫助您開始

首先創建一個自定義的處理器路線

config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}", 
    defaults: null, 
    constraints: null, 
    handler: new CustomHttpControllerDispatcher(config) 
); 

public class CustomHttpControllerDispatcher : HttpMessageHandler 
{ 
    private IHttpControllerSelector _controllerSelector; 
    private readonly HttpConfiguration _configuration; 

    public CustomHttpControllerDispatcher(HttpConfiguration configuration) 
    { 
     _configuration = configuration; 
    } 

    public HttpConfiguration Configuration 
    { 
     get { return _configuration; } 
    } 

    private IHttpControllerSelector ControllerSelector 
    { 
     get 
     { 
      if (_controllerSelector == null) 
      { 
       _controllerSelector = _configuration.Services.GetHttpControllerSelector(); 
      } 
      return _controllerSelector; 
     } 
    } 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     return SendAsyncInternal(request, cancellationToken); 
    } 

    private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 

     IHttpRouteData routeData = request.GetRouteData(); 
     Contract.Assert(routeData != null); 

     HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request); 
     IHttpController httpController = httpControllerDescriptor.CreateController(request); 


     foreach (var queryParam in request.GetQueryNameValuePairs()) 
     { 
      routeData.Values.Add(queryParam.Key, queryParam.Value); 
     } 


     // Create context 
     HttpControllerContext controllerContext = new HttpControllerContext(_configuration, routeData, request); 
     controllerContext.Controller = httpController; 
     controllerContext.ControllerDescriptor = httpControllerDescriptor; 

     return httpController.ExecuteAsync(controllerContext, cancellationToken); 
    } 
} 

然後設置你的方法在控制器到達

public class MyController : ApiController 
{ 
    [HttpGet] 
    public IHttpActionResult GetUser([FromUri]int userId) 
    { 
     return Ok(); 
    } 

    [HttpGet] 
    public IHttpActionResult DoSomething([FromUri]string test) 
    { 
     return Ok(); 
    } 
} 

我只嘗試過使用GET方法,POST可能只是工作,但我沒有測試過。

相關問題