首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用FiveLevelsOfMediaType (5LMT)的基于内容的操作选择Web不起作用

使用FiveLevelsOfMediaType (5LMT)的基于内容的操作选择Web不起作用
EN

Stack Overflow用户
提问于 2015-05-06 00:42:19
回答 1查看 1.2K关注 0票数 0

我正在尝试实现一个CQRS,它使用命令来改变系统的状态(基于RESTful策略)。默认情况下,根据检查对象参数的类型,Web API的路由将很难与操作相匹配。为了解决这个问题,我一直在使用下面的指南:Content Based Action Selection Using Five Levels of Media Type

在遵循指令之后,它仍然会导致一个不明确的匹配异常,这是由我的控制器中重载的Put方法引起的。

我的WebApiConfig如下:

代码语言:javascript
复制
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();
    }
}

我的控制器看起来像:

代码语言:javascript
复制
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头是:

代码语言:javascript
复制
PUT /api/products HTTP/1.1
Content-Type: application/json;domain-model=ChangeProductCodeCommand

和JSON:

代码语言:javascript
复制
{
  ProductId: 758,
  ProductCode: "TEST"
}

结果如下:

代码语言:javascript
复制
{
  "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()"
}

你知道为什么这个方法行不通吗?

EN

回答 1

Stack Overflow用户

发布于 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解析为您的类型之一。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30058704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档