繁体   English   中英

如何使一个路由指向两个不同的控制器端点,该端点在WEB Api 2中接受不同的参数

[英]How to have a Route which points to two different controller end points which accepts different arguments in WEB Api 2

如何拥有一个指向两个不同的控制器端点的路由,该路由在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个不同端点?

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

您可以在这里找到一个很好的例子

路由约束使您可以限制路由模板中参数的匹配方式。 通用语法是"{parameter:constraint}" 例如:

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

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

而且我认为此链接必须有所帮助

如果确实需要相同的路由和相同的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的解决方案。 并非适用于所有控制器,因为它将为每个请求增加开销。

我认为您应该重新考虑为什么您真正需要两条必须相同的路线。 我认为,如果同一条路线接受不同的论点,则可读性将受到影响。 但那只是我的个人意见。

我会改用其他路线。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM