Enrutamiento de API 404 Si el parámetro opcional se perdió
-
21-12-2019 - |
Pregunta
Tengo este enrutamiento configurado en mi 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;
}
y estos métodos dentro de /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();
}
Puedo solicitar / API / PRODUCTO / GETPRODUCT / 10000 y recuperar JSON.
Si solicito / API / PRODUCTO / GETSTEST, obtengo un 404
Si cambio GetTest to
public object GetTest(int id)
y SOLICITUD / API / PRODUCTO / GETTEST / 10000 I Get JSON.
No tengo idea de por qué está sucediendo 404.Tengo otros controladores (para solicitudes que no son API) que están manejando las solicitudes de normalidad.Soy nuevo en MVC después de algunos años de formas web, y esto me ha perplejo.Para referencia, aquí está mi rutaConfig
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 }
);
}
y mi aplicación_start
protected void Application_Start()
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
Solución
Esto se debe al pedido de sus rutas.
RouteConfig.RegisterRoutes(RouteTable.Routes);
se llama antes
GlobalConfiguration.Configure(WebApiConfig.Register);
y su método de Registriberos contiene una ruta predeterminada (y muy genérica)
url: "{controller}/{action}/{id}"
Esta regla genérica (predeterminada) coincidirá con su patrón de URL de
api/product/gettest
Antes de que su ruta de WebAPi tenga la oportunidad de coincidir con él.
Puede deshacerse de esa ruta súper genérica si no es necesario (y use rutas más específicas), o simplemente mueva la llamada a
GlobalConfiguration.Configure(WebApiConfig.Register);
para venir antes de la llamada a
RouteConfig.RegisterRoutes(RouteTable.Routes);
en su global.asax.
Construí una muestra con toda la información que dio, y en movimiento esa llamada funcionó bien. Espero que esto ayude.