2012-05-18 19 views
7

Estoy viendo el siguiente tutorial de Microsoft. Según este tutorial,¿Cómo maneja ASP.NET Web.api dos métodos con nombres que comienzan con GET?

En el primer ejemplo, "productos" coincide con el controlador llamado ProductsController. La solicitud es una solicitud GET, por lo que el marco busca un método en ProductsController cuyo nombre comienza con "Obtener ...". Además, el URI no contiene el segmento {id} opcional, por lo que el marco busca un método sin parámetros. El método ProductsController :: GetAllProducts cumple con todos estos requisitos de .

¿Qué sucede si hay dos métodos como GetAllProducts() y GetSoldProducts()? Ambos no tienen parámetros.

Your First Web API Tutorial

Respuesta

8

Suponiendo que está usando las rutas por defecto la respuesta corta es: el método definido en primer lugar (en la parte superior) de su clase, será llamado. el otro método es inaccesible

NOTA: el beta se comportó como se describió anteriormente para 'emparejar múltiples métodos' - la versión de lanzamiento de RC & es un poco más OCD. Lanza un error si hay múltiples coincidencias potenciales. Este cambio elimina la confusión de múltiples coincidencias ambiguas. Al mismo tiempo, reduce nuestra capacidad para mezclar las interfaces de estilo REST y RPC en el mismo controlador, dependiendo de la orden de las rutas superpuestas &.

Stealing liberalmente de another post I wrote on the topic:

WebAPI a juego Semántica

la coincidencia semántica utilizado por WebAPI es bastante simple.

  1. coincida con el nombre de la acción con el verbo (verbo = llegar? Busque método comenzando con "get")
  2. si se pasa un parámetro, la API busca una acción con un parámetro

Por lo tanto, en el ejemplo del código, una solicitud GET sin un parámetro coincide con la función Get*() sin parámetros. A Obtener contenido e ID busca un Get***(int id).

Ejemplos

Mientras que la semántica juego es simple, se crea una cierta confusión para los desarrolladores MVC (bueno, al menos este desarrollador). Veamos algunos ejemplos:

Nombres impares - Tu método get puede llamarse cualquier cosa, siempre que comience con "get". Por lo tanto, en el caso de un controlador de widgets, puede asignarle un nombre a sus funciones GetStrawberry() y seguirá coincidiendo. Piense en el juego como algo parecido a: methodname.StartsWith("Get")

métodos de emparejamiento múltiples - ¿Qué pasa si usted tiene dos consigue métodos sin parámetros?GetStrawberry() y GetOrange(). Lo mejor que puedo decir es que la función definida primero (la parte superior del archivo) en tu código gana ... extraño. Esto tiene el efecto secundario de hacer que algunos métodos en su controlador sean inalcanzables (al menos con las rutas predeterminadas) ... extraño.

ACTUALIZACIÓN

@WinFXGuy - Este fue un poco largo para poner en un comentario, pero ...

no saltar a conclusiones! Traté de responder a la pregunta que planteaste, pero eso es solo la mitad de la historia. Hay mucho que puede hacer para cambiar el comportamiento predeterminado.

Primero, WebAPI admite gran parte de las especificaciones oData. Si realiza una burbuja de IQueryable hasta su controlador, los parámetros oData se integran automáticamente con el objeto de consulta. Toma parámetros como $filter, $top y $skip. Entonces, en su caso, puede escribir un método y pasar algo como $filter=sale_date neq null.

Además, puede aplicar el atributo [ResultLimit] para evitar que las personas soliciten 15 mil millones de registros.

Segundo puede modificar las rutas. Las rutas predeterminadas apuntan hacia una API REST, donde generalmente se tiene 1 controlador por entidad. Puede cambiar las rutas y hacerlo de estilo RPC.

Si miran mi publicación vinculada, explico cómo mantuve el enlace de ruta predeterminado, agregué 'subcarpetas' y también permití llamadas de métodos adicionales para escenarios donde necesitaba GetAllProducts() y GetSoldProducts().

+0

no me gusta lo que estoy leyendo! Ese tipo de limitaciones asp.net web api capabilites. – WinFXGuy

+0

@WinFXGuy: demasiado tiempo para comentarios ... ver la actualización – EBarr

+0

Encontré que mira los nombres de los parámetros para resolver las sobrecargas. Entonces api/food? Name = orange llamado GetFoodByName (nombre de cadena), y api/food? Category = fruit llamado GetFoodByCategory (categoría de cadena). –

11

Hay dos posibles soluciones a este problema específico:

  1. Alter MapHttpRoute llama a exigir que especifica el nombre de la acción. (Estoy usando la sintaxis autoalojamiento):

    config.Routes.MapHttpRoute(
          "API Route 1", 
          "api/{controller}/{action}"); 
    
        config.Routes.MapHttpRoute(
          "API Route 2", 
          "api/{action}", 
          new { controller = "products" }); 
    

    Así que su cliente http llamarían:

    api/products/GetAllProducts O api/GetAllProducts api/products/GetSoldProducts O api/GetSoldProducts

    Ver: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

  2. Place cada método en un controlador separado (ProductsController, SoldProductsController). Entonces, debe llamar al api/products y api/soldproducts para obtener sus resultados.


Temas relacionados ... en la situación en la que usted tiene un múltiplo Obtener acciones que tienen un solo argumento primitiva del mismo tipo, API Web ASP.NET se verá en el nombre del argumento resolver qué acción sobrecargada llamar

Por ejemplo, si tiene dos acciones:

GetProductByName(string name) 
GetProductByCategory(string category) 

su cliente HTTP puede llamar

api/products?name=hammer 
api/products?category=toys 

y el motor de enrutamiento llamará a la acción correcta.

4

Adición de una respuesta para reflejar que la última versión del API de Web es compatible de forma nativa [Route] atributo

[Route("api/products")] 
public IEnumerable<Product> GetAllProducts(){} 

[Route("api/products/sold")] 
public IEnumerable<Product> GetSoldProducts(){} 
+1

Esto para mí es la mejor solución –

Cuestiones relacionadas