2012-06-12 12 views
74

Tengo la siguiente acción en un ApiController:ASP.NET Web API: El recurso solicitado no soporta http método 'GET'

public string Something() 
{ 
    return "value"; 
} 

Y he configurado mis rutas de la siguiente manera:

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

en la beta, esto funcionó muy bien, pero me acaba de actualizar a la última versión Release Candidate y ahora estoy teniendo errores en llamadas así:

Th El recurso solicitado no es compatible con el método http 'GET'.

¿Por qué ya no funciona?

(supongo que podría deshacerse de {acción} y acaba de hacer una tonelada de controladores, pero que se siente desordenado.)

Respuesta

94

Si no se ha configurado ningún HTTPMethod en su acción en el controlador, se asume que ser solo HttpPost en RC. En Beta, se supone que es compatible con todos los métodos: GET, PUT, POST y Delete. Este es un pequeño cambio de beta a RC. Puede decodificar fácilmente más de un httpmethod en su acción con [AcceptVerbs ("GET", "POST")].

+0

acaba de encontrar esto, gracias por la corrección, pero curioso, ¿por qué tengo que hacer esto con mis métodos personalizados, pero no el método predeterminado "Obtener"? Tengo un método Get creado por la plantilla para el controlador, pero no está decorado. ¿Es esto solo por convención debido al nombre Get? – SelAromDotNet

+3

@Josh: ¡Sí! Cuando el nombre del método de acción comienza con "Obtener ...", no tiene que marcarlo como un método GET. Lea más aquí: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api –

+0

Hice lo sugerido en la respuesta, pero ahora ambos de mis llamadas, Get y Post, están siendo redirigidas a Get Action. ¿Alguna ayuda, por favor? –

14

Esto es sin duda un cambio de Beta a RC. En el ejemplo proporcionado en la pregunta, ahora necesita decorar su acción con [HttpGet] o [AcceptVerbs ("GET")].

Esto ocasiona un problema si desea mezclar acciones basadas en verbos (es decir, "GetSomething", "PostSomething") con acciones no basadas en verbos. Si intenta utilizar los atributos anteriores, causará un conflicto con cualquier acción basada en un verbo en su controlador. Una manera de ponerse en marcha sería definir rutas separadas para cada verbo, y establecer la acción predeterminada para el nombre del verbo. Este enfoque se puede usar para definir recursos secundarios en su API. Por ejemplo, el siguiente código es compatible con "/ resource/id/children" donde id y children son opcionales.

 context.Routes.MapHttpRoute(
      name: "Api_Get", 
      routeTemplate: "{controller}/{id}/{action}", 
      defaults: new { id = RouteParameter.Optional, action = "Get" }, 
      constraints: new { httpMethod = new HttpMethodConstraint("GET") } 
     ); 

     context.Routes.MapHttpRoute(
      name: "Api_Post", 
      routeTemplate: "{controller}/{id}/{action}", 
      defaults: new { id = RouteParameter.Optional, action = "Post" }, 
      constraints: new { httpMethod = new HttpMethodConstraint("POST") } 
     ); 

Esperemos que las versiones futuras de Web API tengan un mejor soporte para este escenario. Actualmente hay un problema registrado en el proyecto codeplex aspnetwebstack, http://aspnetwebstack.codeplex.com/workitem/184. Si esto es algo que le gustaría ver, vote sobre el tema.

51

Toda la información anterior es correcta, también me gustaría señalar que la anotación [AcceptVerbs()] existe en los espacios de nombres System.Web.Mvc y System.Web.Http.

Desea utilizar System.Web.Http si se trata de un controlador Web API.

+0

thx @Eric, me preguntaba por qué no funcionaría ... – jbl

+0

@Eric. Impresionante, esta fue la razón por la que no estaba funcionando para mí. Tenía el verbo en mi acción, pero se hizo referencia a través de Web.Mvc por lo que no estaba funcionando. – dreza

+0

Genial, me salvaste el día –

25

Aunque esta no es una respuesta al OP, tuve exactamente el mismo error de una causa raíz completamente diferente; entonces, en caso de que esto ayude a alguien más ...

El problema para mí fue un parámetro de método incorrecto que provocó que WebAPI enrutara la solicitud inesperadamente. Tengo los métodos siguientes en mi ProgrammesController:

[HttpGet] 
public Programme GetProgrammeById(int id) 
{ 
    ... 
} 

[HttpDelete] 
public bool DeleteProgramme(int programmeId) 
{ 
    ... 
} 

solicitudes de borrar para .../API/programas/3 no estaban siendo enviados a DeleteProgramme como esperaba, pero a GetProgrammeById, porque DeleteProgramme no tienen un parámetro nombre de id. GetProgrammeById estaba rechazando el DELETE, ya que está marcado como solo que acepta GET.

Así que la solución era simple:

[HttpDelete] 
public bool DeleteProgramme(int id) 
{ 
    ... 
} 

y todo está bien. Error tonto realmente pero difícil de depurar.

14

Si usted está adornando su método con HttpGet, añada el siguiente using en la parte superior del controlador:

using System.Web.Http; 

Si está utilizando System.Web.Mvc, entonces este problema se puede producir.

+1

Esto es cierto, y ridículamente .NET no muestra el mensaje claramente. –

2

Mismo problema que el anterior, pero raíz muy diferente. Para mí, fue que estaba llegando a un punto final con una regla de reescritura de https. Al presionarlo en http se produjo el error, funcionó como se esperaba con https.

2

Tienen la misma configuración que OP. Un controlador con muchas acciones ... menos "desordenado" :-)

En mi caso olvidé el "[HttpGet]" al agregar una nueva acción.

[HttpGet] 
public IEnumerable<string> TestApiCall() 
{ 
    return new string[] { "aa", "bb" }; 
} 
Cuestiones relacionadas