使用多个控制器将PUT方法添加到子路由时,Web API路由发生冲突

时间:2016-11-10 14:35:50

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

我不确定如何命名这个问题。出于这个原因,我也很难找到这个特殊问题。我找到的最匹配的问题是Web Api Routing conflict for two different controllers?

就像那个问题中的提问者一样,我也有两个不同的控制器部分匹配:

public class JobsController : ApiController
{
    [ResponseType(typeof(DTJob[]))]
    public async Task<HttpResponseMessage> Get()
    {
        //...
    }

    [Route("v1/Jobs/Group"), ResponseType(typeof(DTJob[]))]
    public async Task<HttpResponseMessage> GetFromGroup()
    {
        //...
    }

    [HttpGet, Route("v1/Jobs/{jobId}/Status"), ResponseType(typeof(string))]
    public async Task<HttpResponseMessage> GetStatus(long jobId)
    {
        //...
    }

    [HttpPut, Route("v1/Jobs/{jobId}/Status"), ResponseType(typeof(void))]
    public async Task<HttpResponseMessage> UpdateStatus(long jobId, string status)
    {
        //...
    }

    //This method messes up all other controllers
    [HttpPut, Route("v1/Jobs/{jobId}"), ResponseType(typeof(void))]
    public async Task<HttpResponseMessage> Put(long jobId, DTJob job)
    {
        //...
    }

    //But it works if I replace the above method with the default routing pattern:
    //[ResponseType(typeof(void))]
    //public async Task<HttpResponseMessage> Put(long id, DTJob job)
    //{
    //    //...
    //}
}

另一个具有类似前缀的控制器:

[RoutePrefix("v1/Jobs/Materials")]
public class MaterialsController : ApiController
{
    [Route, ResponseType(typeof(DTMaterial[]))]
    public async Task<HttpResponseMessage> Get()
    {
        //...
    }
}

我的路由配置:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapMvcAttributeRoutes();
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //...
        // Web API routes
        config.MapHttpAttributeRoutes();
        //...
        config.Routes.MapHttpRoute(
            name: "Newest",
            routeTemplate: "v1/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

这里发生了什么?

1 个答案:

答案 0 :(得分:0)

我想我再次发现了这个问题。由于{jobId}未在类型中指定,因此它可能是一个字符串,表示&#34;材料&#34;,从而产生冲突。要解决此问题,我只需在参数({jobId:long})中指定类型:

    [HttpPut, Route("v1/Jobs/{jobId:long}"), ResponseType(typeof(void))]
    public async Task<HttpResponseMessage> Put(long jobId, DTJob job)
    {
        //...
    }