【问题标题】:Can I create multiple API endpoints with the same HTTP method and non-variable URIs?我可以使用相同的 HTTP 方法和非可变 URI 创建多个 API 端点吗?
【发布时间】:2014-09-11 01:37:44
【问题描述】:

我有两个这样定义的 API 端点:

[Route("create")]
[HttpPost]
[ResponseType(typeof(User))]
public async Task<IHttpActionResult> CreateUser(User user)

[Route("login")]
[HttpPost]
[ResponseType(typeof (User))]
public async Task<IHttpActionResult> Login(string email, string password)

而控制器定义为

[RoutePrefix("api/users")]
public class UserController : ApiController

当我使用此信息调用它时(在纯 chrome、我的应用程序和 Postman 应用程序中)

POST /api/users/login HTTP/1.1
Host: mysite.azurewebsites.net
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

email=somemail&password=somepw

我收到 404:

{
    "Message": "No HTTP resource was found that matches the request URI 'http://mysite.azurewebsites.net/api/users/login'.",
    "MessageDetail": "No action was found on the controller 'User' that matches the request."
}

它确实适用于我可以使用/api/users/1 调用的另一条路线:

[Route("{id:int}")]
[HttpGet]
[ResponseType(typeof(User))]
public async Task<IHttpActionResult> GetUser(int? id)

我不能明确定义这样的端点吗?我尝试创建一个自定义路由,但这没有任何区别(我将它放在默认路由之前和调用config.MapHttpAttributeRoutes() 之后)。

config.Routes.MapHttpRoute(
      name: "Login",
      routeTemplate: "api/users/login",
      defaults: new { controller = "User", action = "Login" }
);

请注意,将路由明确定义为 [Route("~api/users/login")] 也不起作用。

我还注意到我的另一个控制器中的路由似乎不再起作用了。更具体地说,我有这些定义:

[RoutePrefix("api/movies")]
public class MovieController : BaseController

[Route("~api/genres")]
[HttpGet]
[ResponseType(typeof(IEnumerable<Genre>))]
public IHttpActionResult GetGenres()

[Route("~api/genres/{id:int}")]
[HttpGet]
[ResponseType(typeof(IEnumerable<MovieResult>))]
public IHttpActionResult GetMoviesForGenre(int id)

[Route("{id:int}")]
[HttpGet]
[ResponseType(typeof(Movie))]
public IHttpActionResult GetMovieDetails(int id)

在这些选项中,只有对/api/movies/16 的调用成功,其他选项返回

找不到与名为“流派”的控制器匹配的类型。

我忽略了一些基本的东西吗?

我已将流派路线更改为genresgenres/{id:int} 并添加此路线,从而使它们再次可用

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

但我认为这不是必需的。由于某种原因,对/api/movies/genres 的请求有效,而/api/users/login 无效。我确实注意到使用 URI /api/users/genres DOES 创建一个 GET 方法是可行的,所以我相信它一定与此有关。为什么它找不到我的 POST 方法?

【问题讨论】:

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


    【解决方案1】:

    看起来这里有很多移动的部分,所以很难弄清楚究竟什么可以解决所有问题。但这里有几个问题需要解决......

    Web API(与 MVC 不同)只能从请求正文中读取一个参数。因此,要使您的 Login 操作起作用,请尝试创建一个 LoginInfo 类...

    public class LoginInfo
    {
        public string email { get; set; }
        public string password { get; set; }
    }
    

    并将登录方法更改为...

    public async Task<IHttpActionResult> Login([FromBody]LoginInfo loginInfo)
    

    流派的问题似乎是属性路由中~ 的错误使用(应该是~/)。试试……

    [Route("~/api/genres")]
    

    [Route("~/api/genres/{id:int}")]
    

    【讨论】:

    • 感谢您的回复!实际上,我自己很早就解决了这个问题,当我不得不离开办公桌一段时间时,我即将完成我的答案。实际上,带有单个参数的[FromBody] 注释是解决方案(请参阅here),所以我将接受您的答案。我还要看看那个波浪号;我通过简单地使用标准路线暂时解决了这个问题。
    猜你喜欢
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2019-05-18
    • 2019-10-11
    相关资源
    最近更新 更多