Web API action not found when optional parameter n

2019-07-04 21:22发布

please help. I had to change routing for Web API to be able to use methods in URL:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // for MVC controllers
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Editions", action = "Index", id = UrlParameter.Optional }
        );

        // for Web API
        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new  {  id = RouteParameter.Optional }
        );

    }
}

I have a controller

public class PositionsController : ApiController
{
    [HttpGet]
    public JToken Approved()
    {
        // some code here
    }
}

Everything works fine for methods with parameters, but I cannot call parameterless method like http://localhost/API/Positions/Approved. Instead of calling Approved method I got 404 not found error. What I did wrong?

Funny part: Calling URL http://localhost/API/Positions/Approved/whatever works. It seems like ID is not so optional as I thought.

Thanks for any help!

1条回答
我想做一个坏孩纸
2楼-- · 2019-07-04 21:50

Your problem is that the first route (MVC) is being matched instead of the route you actually want.

So for a url like http://localhost/API/Positions/Approved the app is looking for a controller called 'APIController' with an action called 'Positions' with a string parameter 'id' which will be set to a value of "Approved".

The quick solution is to change the declaration of your routes so the API route appears before the MVC route, however as previously mentioned I would separate the routes into their respective configs (RouteConfig & WebApiConfig) and ensure that in the Global.asax.cs the routes are registered in the correct order:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Alternatively if you are using WebApi2 you could use Attribute Routing to make things easier.

查看更多
登录 后发表回答