冲突的MVC Web Api路由

时间:2019-04-03 02:49:44

标签: c# asp.net-web-api2

我们当前具有以下数据设置:

Task
 -> Incident
 -> ....
 -> ....

从基类Task派生出许多对象。我们已经构建了用于管理这些对象的API,但是还具有一些共享功能,我试图将这些功能放入每个要继承的单个对象api的基本api控制器中。

TaskController
 -> IncidentController
 -> ....
 -> ....

这在大多数情况下都有效。但是,我确实存在以下问题。

Incident Controller内,我有一个Get方法:

[RoutePrefix("Api/Incident")]
public class IncidentController : TaskController
{
    //Get an individual incident by ID
    [HttpGet]
    [Route("{id}")]
    public GenericIncidentGet Get(string id)
    {
        .....
    }
}

此方法工作正常。然后,我在父控制器上有了一个方法

public class TaskController : ApiController
{
    [HttpGet]
    [Route("{number}")]
    public ListResponse<TaskCiResultFlat> GetAffectedCIs(string number)
    {
        ......
    }
}

当我通过/ Api / Incident / GetAffectedCIs?number = XXXX调用上述方法时,它实际上会调用Incident Get()方法,但带有一个null id参数。

我目前正在注册以下WebApi路由:

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

            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
             "ActionIdApi", "api/{controller}/{action}/{id}/{id2}/{id3}/{id4}/{id5}/{id6}", new { id = RouteParameter.Optional, id2 = RouteParameter.Optional, id3 = RouteParameter.Optional, id4 = RouteParameter.Optional, id5 = RouteParameter.Optional, id6 = RouteParameter.Optional });


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

我不太清楚这里发生了什么。

有什么建议吗?

干杯。

3 个答案:

答案 0 :(得分:2)

您使用错误的API URL从事件控制器调用操作方法。

Action方法包含id作为参数,但是通过API URL调用时,您使用number作为参数名称。

此URL,由于Idnumber的参数类型相同,所以命中了正确的API,但是将空值传递给Id,因为您需要使用{{ 1}},而不是API URL中的number

要调用用 Task Controller 编写的Action方法,可以使用

id

要调用用事件控制器编写的操作方法,可以使用

<BaseURL>/api/Task/Get?number=XXXX

希望我的答案能解决您的问题

答案 1 :(得分:1)

@Prasad Telkikar在回答中提到了为什么会与路线发生冲突。

您可以将Route操作的GetAffectedCIs值更改为[Route("GetAffectedCIs/{number}")],然后更改。

此处/Api/Incident/GetAffectedCIs?number=XXXX将与两个API都匹配,但是按照路由顺序[Route("GetAffectedCIs/{number}")]的{​​{1}}为Literal segments,并且具有更高的优先级。

有关GetAffectedCIs的更多详细信息,您可以参考https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-order

您的完整操作如下。

Route Order

答案 2 :(得分:0)

根据Karan和Prasad的反馈,我实施了以下解决方案:

IncidentController:

[RoutePrefix("Api/Incident")]
public class IncidentController : TaskController
{
    //Get an individual incident by ID
    [HttpGet]
    public GenericIncidentGet Get(string id)
    {
        return GenericIncidentWf.GenericIncidentGet(ControllerContext.ControllerDescriptor.ControllerName, System.Threading.Thread.CurrentPrincipal.Identity.Name, id);
    }
}

TaskController:

[RoutePrefix("Api/Incident")]
public class IncidentController : TaskController
{
    //Get an individual incident by ID
    [HttpGet]
    public GenericIncidentGet Get(string id)
    {
        return GenericIncidentWf.GenericIncidentGet(ControllerContext.ControllerDescriptor.ControllerName, System.Threading.Thread.CurrentPrincipal.Identity.Name, id);
    }
}

这有效:)