API маршрутизация 404 Если дополнительный параметр пропускается

StackOverflow https://stackoverflow.com//questions/23010866

  •  21-12-2019
  •  | 
  •  

Вопрос

У меня есть эта маршрутизация настроек в моем webapiconfig

    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

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

        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    }
.

и эти методы внутри /api/productcontroller.cs

    public object GetProduct(int id)
    {
        var productRepo = new ProductRepository(db);
        var product = productRepo.GetItem(id);
        return product.ToAnonymousType();
    }

    public object GetTest()
    {
        var productRepo = new ProductRepository(this.db);
        var product = productRepo.GetItem(10000);
        return product.ToAnonymousType();
    }
.

Я могу запросить / API / Product / GetProduct / 10000 и вернуть JSON.

Если я запрошу / API / Product / Gettest, я получаю 404

Если я изменим точку зрения на

public object GetTest(int id)
.

и запрос / API / Product / Gettest / 10000 Я получаю JSON.

Я понятия не имею, почему происходит 404.У меня есть другие контроллеры (для запросов без API), которые обрабатывают запросы, как обычно.Я новичок в MVC после нескольких лет вебфофортов, и это у меня в тупик.Для справки, вот мой routeConfig

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

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

и мое приложение_start

    protected void Application_Start()
    {
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
.

Это было полезно?

Решение

Это связано с заказом ваших маршрутов.

RouteConfig.RegisterRoutes(RouteTable.Routes);
.

вызывается до

GlobalConfiguration.Configure(WebApiConfig.Register);
.

и метод ваших регистров, содержит по умолчанию (и очень общему) маршруту

url: "{controller}/{action}/{id}"
.

Это правило общего (по умолчанию) сопоставит вашу структуру URL из

api/product/gettest
.

Перед маршрутом webapi получит шанс сопутствовать это.

Вы можете либо избавиться от этого супер-общего маршрута, если не нужно (и использовать более конкретные маршруты), или просто переместите вызов на

GlobalConfiguration.Configure(WebApiConfig.Register);
.

, чтобы прийти до вызова

RouteConfig.RegisterRoutes(RouteTable.Routes);
.

в вашем Global.Asax.

Я построил образец со всей информацией, которую вы дали, и переместив этот звонок, работал просто отлично. Я надеюсь, что это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top