如何在WEB Api 2中指向接受不同参数的两个不同控制器端点的Route

时间:2016-03-17 08:48:03

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

如何使路由指向两个不同的控制器端点,这些端点接受WEB Api 2中的不同参数 我在控制器中声明了两个不同的端点,对于REST透视图,我必须对两个端点使用alpha / {aplhaid} / beta格式,

            [Authorize]
            [HttpPost]
            [Route("alpha/{aplhaid}/beta")]
            public async Task<HttpResponseMessage> CreateAlpha(Beta beta, string projectId, [FromHeader] RevisionHeaderModel revision)

            [Authorize]
            [HttpPost]
            [Route("alpha/{aplhaid}/beta")]
            public async Task<HttpResponseMessage> CreateAlpha(List<Beta> betas, string projectId, [FromHeader] RevisionHeaderModel revision)

是否可以使用具有不同参数的相同路由器,这些参数指向Web API 2中的2个不同端点?

3 个答案:

答案 0 :(得分:2)

不支持基于参数类型的重载web api操作方法。 但是attribute based routing呢?

你可以找到一个很好的例子here

路径约束允许您限制路径模板中的参数匹配方式。一般语法是"{parameter:constraint}"。例如:

[Route("users/{id:int}"]
public User GetUserById(int id) { ... }

[Route("users/{name}"]
public User GetUserByName(string name) { ... }

我认为此链接必须是helpful

答案 1 :(得分:2)

如果您确实需要相同的路线和相同的ActionName ,则可以使用IHttpActionSelector进行此操作。

public class CustomActionSelector : ApiControllerActionSelector, IHttpActionSelector
{
    public new HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
    {
        var context = HttpContext.Current;

        // Read the content. Probably a better way of doing it?
        var stream = new StreamReader(context.Request.InputStream);
        var input = stream.ReadToEnd();

        var array = new JavaScriptSerializer().Deserialize<List<string>>(input);
        if (array != null)
        {
            // It's an array
            //TODO: Choose action.
        }
        else
        {
            // It's not an array
            //TODO: Choose action.
        }

        // Default.
        var action = base.SelectAction(controllerContext);
        return action;
    }

    public override ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor)
    {
        var lookup = base.GetActionMapping(controllerDescriptor);
        return lookup;
    }
}

在您的WebApiConfig中:

    config.Services.Replace(
        typeof(IHttpActionSelector),
        new CustomActionSelector());

您的控制器示例:

public class FooController: ApiController
{
    [HttpPost]
    public string Post(string id)
    {
        return "String";
    }

    [HttpPost]
    public string Post(List<string> id)
    {
        return "some list";
    }
}

如果你问我,解决方案有一些重大缺点。首先,您应该只在需要时寻找使用此CustomActionSelector的解决方案。不适用于所有控制器,因为它会为每个请求创建开销。

我认为你应该重新考虑为什么你真的需要两个相同的路线。我认为如果相同的路由接受不同的参数,可读性将受到影响。但那只是我的意见。

我会改用不同的路线。

答案 2 :(得分:1)

使用一条路线并从第一个控制器内部调用另一个控制器。