路线和可怕的405

时间:2018-03-14 20:17:41

标签: c# asp.net-web-api asp.net-web-api-routing

我有一个简单的Web API,可以在一条路线上注册。目前我有两个,因为只有其中一个做了我需要的。

我的应用程序在该Controller中只有一个控制器和一个Post方法。我已经注册了一条始终返回405 (method not allowed)

的路线

这两条路由在RouteConfig.cs中配置:

routes.MapHttpRoute(
    name: "app-events",
    routeTemplate: "events",
    defaults: new { controller = "Events" },
    handler: new GZipToJsonHandler(GlobalConfiguration.Configuration),
    constraints: null
);

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

Controller方法基本上就是这个......

public class EventsController : ApiController
{
    public EventsController()
    {
        _sender = new EventHubSender();
    }

    public async Task<HttpResponseMessage> Post(HttpRequestMessage requestMessage)
    {
        // doing fun stuff here…

       return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

如果我只配置第一条路线并将请求发送到 http://devbox/events ,我将获得405.但是,如果我添加第二条,默认路由,并发布到 http://devbox/api/events 我找回了预期的201

如果两个路由同时配置,相同的模式,显式绑定到Controller的路由收到一个post请求,并且失败了405,但另一个URL将起作用。

我已经花了很长时间环顾四周,然后才回答这个问题。我读过的大多数内容都与Webdav有很大关系,我想我已经跟着他们每个人来解决这个问题。我对这个堆栈并不是很有经验,所以没有什么对我来说非常明显。

1 个答案:

答案 0 :(得分:0)

您提到了RouteConfig文件。这用于配置MVC路由而不是Web API路由。

所以看起来你正在配置错误的文件,这可以解释为什么api/...路径可以工作,因为它可能映射到WebApiConfig.Register中的默认配置,看起来像

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

您需要使用其他所需路线更新该文件

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "app-events",
            routeTemplate: "events",
            defaults: new { controller = "Events" },
            handler: new GZipToJsonHandler(GlobalConfiguration.Configuration),
            constraints: null
        );

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

Web API路由通常在MVC路由之前注册,这解释了为什么它不能使用原始配置。

您还应该使用相应的Http{Verb}属性来装饰操作。

在这种情况下HttpPost,以便路由表知道如何处理与路由模板匹配的POST请求。

[HttpPost]
public async Task<IHttpActionResult> Post() {
    var requestMessage = this.Request;

    // async doing fun stuff here….

   return OK();
}