我正在尝试实现一个CQRS,它使用命令来改变系统的状态(基于RESTful策略)。默认情况下,根据检查对象参数的类型,Web API的路由将很难与操作相匹配。为了解决这个问题,我一直在使用下面的指南:Content Based Action Selection Using Five Levels of Media Type
在遵循指令之后,它仍然会导致一个不明确的匹配异常,这是由我的控制器中重载的Put方法引起的。
我的WebApiConfig如下:
public static class WebApiConfig
{
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 }
);
config.AddFiveLevelsOfMediaType();
}
}我的控制器看起来像:
public class ProductsController : ApiController
{
public ProductDTO Get(int id)
{
var query = new ProductByIdQuery { Id = id };
ProductDTO product = _queryBus.Dispatch(query);
return product;
}
public void Put(ChangeProductCodeCommand command)
{
_commandBus.Dispatch(command);
}
public void Put(SetProductParentCommand command)
{
_commandBus.Dispatch(command);
}
public ProductsController(IQueryBus queryBus, ICommandBus commandBus)
{
_queryBus = queryBus;
_commandBus = commandBus;
}
IQueryBus _queryBus;
ICommandBus _commandBus;
}在客户端,我发送的http头是:
PUT /api/products HTTP/1.1
Content-Type: application/json;domain-model=ChangeProductCodeCommand和JSON:
{
ProductId: 758,
ProductCode: "TEST"
}结果如下:
{
"Message": "An error has occurred.",
"ExceptionMessage": "Ambiguous Match",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at ApiActionSelection.System.Web.Http.Controllers.ApiActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n at ApiActionSelection.System.Web.Http.Controllers.ApiActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}你知道为什么这个方法行不通吗?
发布于 2015-05-22 03:37:36
对于仅参数类型不同的两个Put方法,Web API尝试根据传入参数的类型解析为正确的操作。
除非默认的模型绑定器可以将传入的JSON映射到您已经实现的复杂类型,并且该类型与您的某个Put方法的参数类型相匹配,否则Web API将使用您看到的"Ambiguous Match"异常进行响应,因为它无法确定要调用哪个方法。请注意,默认情况下,Web不会在操作解析中使用Content-Type标头。
我建议您阅读Routing and Action Selection in ASP.NET Web API,这样您就可以了解路由是如何在内部工作的。然后,您可能希望创建自己的IHttpActionSelector实现,在其中检查您的Content-Type,并可以将请求路由到您选择的操作。您可以找到一个示例实现here。
您还可以阅读有关模型绑定here的更多信息,以了解如何将传入的JSON解析为您的类型之一。
https://stackoverflow.com/questions/30058704
复制相似问题