2016-06-21 7 views
0

Ich habe zwei HTTP-Endpunkte, wie folgt definiert:Warum wird ein falscher Endpunkt bei Verwendung eines Ansichtsmodells getroffen, funktioniert aber, wenn Parameter explizit angegeben werden?

[HttpGet] 
public IEnumerable<AdvertisementVM> GetAdsForRetailer(long userId, int page, int pageSize) 
{ 
    //.... 
} 

und

[HttpGet] 
public IEnumerable<AdvertisementVM> GetAds(AdsViewModel vm) 
{ 
    //.... 
} 

wo AdsViewModel als

public class AdsViewModel 
{ 
    public long UserId { get; set; } 
    public AppType AppType { get; set; } 
    public int Page { get; set; } 
    public int PageSize { get; set; } 
} 

mit der folgenden Route Konfiguration (Verhalten unabhängig definiert ist dasselbe in der Reihenfolge dieser):

routes.MapHttpRoute(
    name: "GetAds", 
    routeTemplate: "api/{controller}/GetAds/{appType}/{userId}/{page}/{pageSize}" 
    ); 

routes.MapHttpRoute(
    name: "GetAdsForRetailer", 
    routeTemplate: "api/{controller}/GetAdsForRetailer/{userId}/{page}/{pageSize}" 
    ); 

Das Problem, das ich habe, ist, dass der erste Endpunkt, z.B. GetAdsForRetailer bekommt immer treffen, unabhängig von der URL Ich benutze entweder

http://localhost/MyApp/api/AdsApi/GetAdsForRetailer/585290/0/3 

oder

http://localhost/MyApp/api/AdsApi/GetAds/customer/585290/0/3 // <-- note the extra customer parameter 

Allerdings, wenn ich die angeben, nicht explizit verwenden AdsViewModel, und stattdessen die einzelnen Parameter, wie folgt, die Der richtige Endpunkt wird getroffen, z

[HttpGet] 
public IEnumerable<AdvertisementVM> GetAds(AppType appType, long userId, int page, int pageSize) 
{ 
    // I get hit when params are declared, but not when AdsViewModel is used 
} 

Ich würde erwarten, dass, wenn ich die /GetAds/customer Route verwenden, der GetAds Endpunkt treffen würde, und das Modell Bindemittel würde wissen, wie die verschiedenen Routenparameter an das Objekt zu binden, in weitergegeben werden.

Warum verhält sich das anders als erwartet, und wie kann ich den Modellbinder dazu bringen, sich an das Viewmodel zu binden und dieses an den richtigen Endpunkt weiterzugeben?

+1

Haben Sie versucht, Standardwerte auf der Route setzen? –

+0

Können Sie meine Antwort überprüfen? –

+0

tat ich. Es ist nicht die Lösung. Ich hätte es als richtig markiert, wenn es war. – DaveDev

Antwort

0

Methoden mit komplexen Typen von Auswahlalgorithmus ausgenommen - Kern von hier - http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

„Komplexe Typen sind eine Ausnahme aus einem anderen Grund ein komplexer Typ nur an den URI über eine benutzerdefinierte binden Bindung Aber.. In diesem Fall kann das Framework nicht im Voraus wissen, ob der Parameter an einen bestimmten URI binden würde. Um herauszufinden, müsste er die Bindung aufrufen. Das Ziel des Auswahlalgorithmus ist es, eine Aktion aus der statischen Beschreibung auszuwählen, bevor sie aufgerufen wird Bindings. Daher werden komplexe Typen aus dem Matching-Algorithmus ausgeschlossen. "

Ich kann diese Arbeit erhalten, indem Sie mit {Aktion} Attribute

Registrieren Methode

config.Routes.MapHttpRoute(
    name: "GetAds", 
    routeTemplate: "api/{controller}/{action}/{userId}/{page}/{pageSize}" 
); 

config.Routes.MapHttpRoute(
    name: "GetAdsForRetailer", 
    routeTemplate: "api/{controller}/{action}/{appType}/{userId}/{page}/{pageSize}" 
); 

Kontroller

[HttpGet] 
[ActionName("GetAds")] 
public IEnumerable<SampleModel> GetAds(long userId, int page, int pageSize) 
{ 
    //do something here 
} 

[HttpGet] 
[ActionName("GetAdsForRetailer")] 
public IEnumerable<SampleModel> GetAdsForRetailer([FromUri]SampleModel model) 
{ 
    //do something here 
} 
Verwandte Themen