2017-05-25 68 views
0

我读过几个SO posts,它们都没有覆盖我的场景,因此我要在此处发帖。找到了与请求匹配的多个操作:WebAPI 2

给出下面的航线配置报名:

public static void Register(HttpConfiguration config) 
{ 
    // Web API configuration and services 

    // Web API routes 
    config.MapHttpAttributeRoutes(); 

    config.Routes.MapHttpRoute(
     name: "DefaultApi", 
     routeTemplate: "api/{controller}/{id}", 
     defaults: new { id = RouteParameter.Optional } 
    ); 
} 

,并从ApiController继承的控制器,这些控制器操作:

public GetDocumentsResponse Post([FromBody]GetDocumentsRequest request) 
{ 

} 

public FinishDocumentsResponse Post([FromBody] FinishDocumentsRequest request) 
{ 

} 


public class GetDocumentsRequest 
{ 
    public string CorrelationId { get; set; } 
    public int Id { get; set; } 
    public string ObjectId { get; set; } 
    public string BusinessArea { get; set; } 
    public string UserId { get; set; } 
    public string SystemName { get; set; } 
    public string SystemToken { get; set; } 
    public Letter LetterDetails { get; set; } 
    public List<KeyValuePair<string, string>> KeyValue { get; set; } 
} 

public class FinishDocumentsRequest 
{ 
    public string CorrelationId { get; set; } 
    public string[] Documents { get; set; } 
} 

我以为做这种方式就足以消除歧义的IHttpActionSelector正确选择路线,但不幸的是它不是。

所以我的问题是“有没有办法使这段代码正常工作,并保持在同一控制器?

谢谢 斯蒂芬

+0

您是否打算为两者进行相同的URL调用? – Nkosi

回答

1

您可以使用attribute routing这个。

定义为在路径字符串中的路由属性ontop的方法,因为这

[Route("api/controller/Post1")] 
[HttpPost] 
public GetDocumentsResponse Post([FromBody]GetDocumentsRequest request) 
{ 

} 
[Route("api/controller/Post2")] 
[HttpPost] 
public FinishDocumentsResponse Post([FromBody] FinishDocumentsRequest request) 
{ 

} 
0

添加路由属性装饰你的Web API函数,这将assit选择选择路线:

[Route("Post1")] 
public GetDocumentsResponse Post([FromBody]GetDocumentsRequest request) 
{ 

} 

[Route("Post2")] 
public FinishDocumentsResponse Post([FromBody] FinishDocumentsRequest request) 
{ 

} 

我还建议将HTTP方法装饰等如[HttpPost][HttpGet]

1

该请求路由管道是不够的智能,以确定该请求的主体中的参数类型相匹配(又名超载)。 (编译器足够聪明,这就是为什么这个编译和你有运行时问题。)

你有几个不同的选项。

  1. 您可以在两个帖子上添加[Route(<ActionName>)]属性。
  2. 使两个控制器,一个用于GetDocuments,一个用于FinishDocuments
  3. 使一个Post方法是不明确的。 (我会避免)

如果您选择选项1,您的API uri必须是.../api/MyController/MyActionName而不是.../api/MyController/。建议在方法中添加[HttpGet][HttpPost]属性。

样品:

public class DocumentController : ApiController 
{ 
    // POST /api/Document/GetDocuments 
    [HttpPost] 
    [Route("GetDocuments")] 
    public GetDocumentsResponse Post([FromBody]GetDocumentsRequest request) { ... } 

    // POST /api/Document/FinishDocuments 
    [HttpPost] 
    [Route("FinishDocuments")] 
    public FinishDocumentsResponse Post([FromBody] FinishDocumentsRequest request){ ...} 
} 

如果您选择选项2,您必须维护额外的代码文件。

public class GetDocumentsController : ApiController 
{ 
    // POST /api/GetDocuments 
    [HttpPost] 
    public GetDocumentsResponse Post([FromBody]GetDocumentsRequest request) { ... } 
} 

public class FinishDocumentsController : ApiController 
{ 
    // POST /api/FinishDocuments/ 
    [HttpPost] 
    public FinishDocumentsResponse Post([FromBody] FinishDocumentsRequest request){ ...} 
} 

如果您选择选项3,愿上帝怜悯你的灵魂你将有一个坏的时间来维护它。

相关问题