如何同时支持两种URL

问题描述 投票:2回答:1

我希望能够通过以下方式致电GET:

/ api / Test / Test / 1

/ api / Test / Test?id = 1

public class TestController : ApiController
{
    [HttpGet]
    public string Test(int id)
    {
        return "Test";
    }
}

如何配置路由?

我有默认值:

            config.MapHttpAttributeRoutes();

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

这将使“ / api / Test / Test?id = 1”起作用,但不能使“ / api / Test / Test / 1”起作用

我尝试在操作上添加属性路由,这使“ / api / Test / Test / 1”工作,但现在“ / api / Test / Test?id = 1”不起作用:

        [HttpGet]
        [Route("api/test/test/{id}")]
        public string Test(string id)
        {
            return "a";
        }
asp.net asp.net-web-api asp.net-mvc-routing
1个回答
0
投票

使用ASP.NET Web API模板,我像这样配置了WebApi路由:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}"
);

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

您需要谨慎对待控制器中包含的操作。例如,我有这样的ValuesController

public class ValuesController : ApiController
{
    [HttpGet]
    public string Test(string id = "")
    {
        return "test " + id;
    }
}

使用上述配置的路由,api将响应以下请求:

/api/values/2
/api/values/test/2
/api/values/test?id=2

但是,如果在同一控制器中添加第二个HttpGet动作,事情就会变得复杂。当尝试响应映射到第一条路由(DefaultApi)的请求时,服务器将无法确定要发送哪个get动作。 DefaultApi路由类型依赖于一个约定,即控制器将只有1个操作来服务每种HTTP请求。如果添加另一个名为HttpGetTry操作:

[HttpGet]
public string Try(int id)
{
    return "try " + id;
}

服务器将响应如下:

/api/values/test/2    -> WORKS
/api/values/test?id=2 -> WORKS
/api/values/try/2     -> WORKS
/api/values/try?id=2  -> WORKS
/api/values/2         -> DOES NOT WORK, Multiple GET methods. server can't decide which to use

如果您打算在同一控制器中对每种类型的HTTP请求使用不止一种方法,我建议删除DefaultApi路由并仅保留ActionApi。另一个例子:

// Removed "DefaultApi"
config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
public class ValuesController : ApiController
{
    [HttpGet]
    public string Test(int id)
    {
        return "test " + id;
    }

    [HttpGet]
    public string Try(int id)
    {
        return "try " + id;
    }

    [HttpGet]
    public string Play(string str)
    {
        return "play " + str;
    }
}

现在,服务器将成功处理以下请求:

/api/values/test/3       -> WORKS
/api/values/test?id=3    -> WORKS
/api/values/try/3        -> WORKS
/api/values/try?id=3     -> WORKS
/api/values/play?str=3   -> WORKS

但是,这些将不起作用:

/api/values/play/3       -> DOES NOT WORK
/api/values/play?id=3    -> DOES NOT WORK

方法“ Play”的参数未称为“ id”,服务器不知道您想要什么。回应:

<Error>
    <Message>
        No HTTP resource was found that matches the request URI 'https://localhost:44327/api/values/play/3'.
    </Message>
    <MessageDetail>
        No action was found on the controller 'Values' that matches the request.
    </MessageDetail>
</Error>
/api/values/3

服务器希望控制器名称(在这种情况下为values之后)是控制器动作。 3显然不是,因此服务器不知道如何处理该请求。

<Error>
    <Message>
        No HTTP resource was found that matches the request URI 'https://localhost:44327/api/values/3'.
    </Message>
    <MessageDetail>
        No action was found on the controller 'Values' that matches the name '3'.
    </MessageDetail>
</Error>

我希望这篇文章为您提供足够的信息来配置您想要的API。

© www.soinside.com 2019 - 2024. All rights reserved.