asp.net - 如何支持两种 URL

标签 asp.net asp.net-web-api asp.net-mvc-routing

我希望能够通过以下方式调用 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 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 }
);

您需要小心 Controller 中包含的操作。例如,我有这样的 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

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

[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

如果您打算在同一 Controller 中为每种类型的 HTTP 请求使用 1 个以上的方法,我建议删除 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

服务器期望 Controller 名称(在本例中为values)后面的内容是 Controller 操作。 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。

关于asp.net - 如何支持两种 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59157364/

相关文章:

.net - Try Catches 仍然有用吗?

asp.net-mvc - 还有什么更 RESTful : Recommended practice for flipping a boolean via PATCH in WebAPI

asp.net-mvc - MVC 3 无法将字符串作为 View 模型传递?

c# - MVC5 路由命名空间优先级

asp.net - Node.js 的事件驱动有什么不同?我们不能在 ASP.Net 的 HttpAsyncHandler 中做到这一点吗?

c# - ActiveRecord ISessionFactory

c# - ASP NET Web API 中的路由 - 对于不同版本的 API

asp.net-mvc - MVC-路由,为什么我不能忽略默认值,匹配的路由不包含 'controller'路由值,这是必需的

c# - System.Text.Json 序列化 Unicode 字符(如表情符号)的问题

asp.net-web-api - 如何从Azure移动应用程序中的身份提供商获取用户信息?