6

Im a mí mismo una API web asp.net mvc 4edificio reparador MVC Web Api Herencia

he estado a través de la Microsoft videos y creo que son buenos. Se usan los verbos de Http. Los recursos son sustantivos, es Dandy con los repositorios, etc.

pero una cosa realmente me molesta

estoy bajo la impresión de que este GET http://www.myurl.com/api/sellers/{id}/products es reparador y GET http://www.myurl.com/api/products?$filter = sellerID eq {id} no lo es.

Todo lo que veo en lo que he leído sobre la nueva API web es anterior última.

¿Hay soporte nativo para el último anterior? Si no, ¿hay alguna manera de hacerlo sin enrutar todo?


Editar-
Im que busca algo que le permitirá GET http://www.myurl.com/api/sellers/{id}/products y GET http://www.myurl.com/api/products etc


Actualización:
Esta pregunta no tiene sentido por un tiempo, me lo he solucionado, pero es por eso que la primera respuesta no está marcada como correcta.


Actualización:
Después de charlar con MilkyWayJoe hablamos de convertir a /Seller/2/Products/Products?$filter = sellerID eq 2. ¿Alguien tiene alguna idea de cómo uno puede hacer esto?

Respuesta

3

La url http://www.myurl.com/api/products?$filter= sellerID eq {id} está utilizando los filtros OData, que en la API web se consumen de fábrica cuando el controlador devuelve la colección como IQuerable. El valor predeterminado en VS 2012 está actualmente establecido en IEnumerable, que no es compatible con OData.

Puede encontrar más a cerca de esto here y here.

+0

Lo siento, accidentalmente dije esto último cuando me refería al anterior. He editado y reparado la pregunta. – MrJD

+0

@MrJD Mira la respuesta de Programming Hero. Básicamente es un patrón de enrutamiento diferente que se asemeja a las rutas de los raíles. Comprueba [this] (http://microformats.org/wiki/rest/urls) también, verás que hay otras rutas similares, p. 'GET/people/1/edit' que es esencialmente un OBTENER – MilkyWayJoe

+0

Estoy anteponiendo simplemente a definir explícitamente un verbo. No está necesariamente relacionado con la pregunta. Ese método me obligaría a enrutar cada situación anidada para cada punto final. Quiero una manera de abstraerme de eso. – MrJD

3

Es posible tener recursos anidados (al menos en la construcción de URL), pero no hay una gran cantidad de soporte para en MVC; tendrás que hacer la mayor parte del trabajo tú mismo.

En primer lugar, tendrá que crear una ruta para hacer frente a su estructura:

url: "sellers/{sellerId}/products", 
defaults: new { controller = "sellers", action = "GetProducts" } 

A continuación, tendrá que crear la acción GetProducts en su "vendedores" controlador, que esta ruta debe dirigir las personas que llaman a:

[HttpGet] 
public IEnumerable<Product> GetProducts(int sellerId) 
{ 
    //TODO: Add query to return results. 
} 

el parámetro sellerId se pasará a través de la ruta y se debe utilizar para conducir su consulta.

El principal inconveniente de este enfoque es que la ruta personalizada hace que sea más difícil generar URL para los enlaces entre los recursos, y cuando se vuelven más complicados, pueden comenzar a coincidir URL que no esperabas.

+0

Buena respuesta, +1 – MilkyWayJoe

+0

Mi pregunta especificó 'sin enrutar todo'. Esto funciona, sin embargo, no quiero tener que crear 4 rutas para la anidación profunda para un solo punto final. Simplemente no es eficiente. – MrJD

+1

Por desgracia, como ya he dicho, MVC4 no es compatible de forma natural con lo que intenta hacer.Puede hacer que sus rutas sean reutilizables definiendo más parámetros en ellas, pero finalmente, si desea que una URL particular se resuelva en una acción y controlador en particular, ** el sistema de enrutamiento fue diseñado para resolver este problema. ** –

2

Estoy buscando una solución a su mismo problema. Actualmente estoy probando esta solución.

En primer lugar, cambiar la ruta:

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

Entonces, si quieres un SellersController, escribir como normal, pero el nombre de toda la acción `Índice' y utilizar anotaciones para encaminar el verbo HTTP correctamente. Por ejemplo:

 [HttpGet] 
    public List<Seller> Index() 
    {} 

Luego, en SellersController, crear acciones nombrarlos como su objeto "interno" (Products).

 [HttpGet] 
    public List<Product> Products(int id) 
    {} 

    [HttpGet] 
    public Product Products(int id, int id2) 
    {} 

De esta manera se puede llamar

 GET /api/sellers 
    or GET /api/sellers/99/products 
    or GET /api/sellers/99/products/2 

En realidad estoy probando este enfoque, por lo que cualquier información sería apreciada!

+0

Eso es inteligente. Sin embargo, no escala como yo quiero. Por ejemplo. Supongamos que los productos pueden tener opiniones y desea solicitar todas las revisiones para el vendedor 142. La solicitud sería similar a/vendlers/142/products/reviews. Esa es una solicitud de 3 niveles. Lamentablemente, parece que su ejemplo puede manejar hasta dos – MrJD

Cuestiones relacionadas