Route not recognised in MVC 4 WebAPI

谁说胖子不能爱 提交于 2019-12-12 10:26:08

问题


I haven't used the ASP.NET WebAPI much although I have used routes in straight MVC. Obviously I'm doing something wrong, perhaps someone can help? I have one controller called UsersController and two methods on it, Register and Details, both take two string parameters and return a string, both marked as HttpGet. Originally I started with two route mappings in WebApiConfig.cs:

config.Routes.MapHttpRoute(
      name: "TestApi",
      routeTemplate: "api/{controller}/{action}/{userId}/{key}"
  );
  config.Routes.MapHttpRoute(
      name: "Test2Api",
      routeTemplate: "api/{controller}/{action}/{userId}/{class}"
  );

With this set up only the first route is found for a URL such as:

http://<domain>/api/users/register/a123/b456/

If I call:

http://<domain>/api/users/details/a123/b456/

I get a 404. If I swap the two routes around then I can call the Details method but not the Register method, again getting a 404. The workaround I have in place is to be more specific with the routes:

config.Routes.MapHttpRoute(
      name: "TestApi",
      routeTemplate: "api/{controller}/register/{userId}/{key}"
  );
  config.Routes.MapHttpRoute(
      name: "Test2Api",
      routeTemplate: "api/{controller}/details/{userId}/{class}/"
  );

The UsersController looks like:

namespace HelloWebAPI.Controllers
{
  using System;
  using System.Web.Http;
  using HelloWebAPI.Models;

    public class UsersController : ApiController
    {
      [HttpGet]
      public string Register(string userId, string key)
      {
        return userId + "-" + key;
      }

      [HttpGet]
      public string Enrolments(string userId, string @class)
      {
        return userId + "-" + @class
      }
    }
}

So what I don't understand is why the {action} component of the route registered second is not being associated with the correct method.

Thanks

Joe


回答1:


The routing in ASP.NET Web API works in three steps:

  1. Matching the URI to a route template.
  2. Selecting a controller.
  3. Selecting an action.

The framework selects the first route in the route table that matches the URI, there is no "second guessing" in case when 2nd or 3rd step fails - just 404. In your case both URI are always matching the first route so the second is never used.

For further analysis let's assume that the first route is:

api/{controller}/{action}/{userId}/{key}

And you call it with following URI:

http://<domain>/api/users/enrolments/a123/b456/

In order to choose action framework is checking three things:

  • The HTTP method of the request.
  • The {action} placeholder in the route template, if present.
  • The parameters of the actions on the controller.

In this case the {action} part will be resolved correctly to enrolments, but framework will be looking for Enrolments method with userId and key parameters. Your method has a class parameter which is no match. This will result in 404.

To avoid the issue you have to make more specific routes (like you did) or unify parameters names.




回答2:


You only need to define the one route:

config.Routes.MapHttpRoute(
    name: "TestApi",
    routeTemplate: "api/{controller}/{action}/{userId}/{key}"
);

Then change your controller methods to the following:

[HttpGet]
public string Register(string userId, string key)
{
  return userId + "-" + key;
}

[HttpGet]
public string Details(string userId, string key)
{
  return userId + "-" + key
}


来源:https://stackoverflow.com/questions/15553620/route-not-recognised-in-mvc-4-webapi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!