如何支持两种URL [英] How to support both kinds of URLs

查看:134
本文介绍了如何支持两种URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望两个人都可以调用GET:

I'd like to be able to call GET by both:

/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"起作用

This makes "/api/Test/Test?id=1" work but not "/api/Test/Test/1"

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

I tried to add the attribute routing on the action, which makes "/api/Test/Test/1" work but now "/api/Test/Test?id=1" doesn't work:

        [HttpGet]
        [Route("api/test/test/{id}")]
        public string Test(string id)
        {
            return "a";
        }

推荐答案

使用ASP.NET Web API模板,我配置了WebApi路由,如下所示:

Working with the ASP.NET Web API template, I configured the WebApi routes like this:

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:

You will need to be careful with the actions you include in your controller. For example, I have the ValuesController like this:

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

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

With the routes configured as shown above, the api will respond to the following requests:

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

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

However, things get complicated if you add a second HttpGet action in the same controller. The server, when trying to respond to the request that maps to the first route (DefaultApi), won't be able to figure out which get action to send. The DefaultApi route kind of relies on a convention that a controller will only have 1 action to service each kind of HTTP request. If you add a second HttpGet action named Try:

[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.另一个例子:

If you intend to use more than 1 method for each type of HTTP request in the same controller, I recommend removing the DefaultApi route and keeping only the ActionApi. Another example:

// 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;
    }
}

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

Now, the server will handle the following requests successfully:

/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

但是,这些将不起作用:

However, these will not work:

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

方法"Play"未将参数称为"id",服务器不知道您想要什么.响应:

Parameter isn't called "id" for the method "Play", the server doesn't know what you want. Response:

<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显然不是,因此服务器不知道如何处理该请求.

The server expects what comes after the controller name, values in this case, to be a controller action. The 3 obviously isn't so the server doesn't know how to handle the request.

<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.

I hope this post gives you enough information to configure your API however you want.

这篇关于如何支持两种URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆