7

mam następujące:Jak powinien działać dostawca powiązań modelu interfejsu Web API interfejsu C#?

  • URL żądania: "punkt końcowy/1,2,3 q = foo?
  • działanie, do którego wniosek jest zobowiązany: obiekt publiczny bar ([ModelBinder] Lista < T> id [FromUri] q ciąg)

chcę mapować „1,2,3” fragment z „id” parametru, więc stworzyłem ModelBinderProvider według this link, które powinny wywołać właściwy model spoiwa.

public class MyModelBinderProvider: ModelBinderProvider 
{ 
    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType) 
    { 
     IModelBinder modelBinder = null; 

     if (modelType.IsGenericType && (modelType.GetGenericTypeDefinition() == typeof(List<>))) 
     { 
      modelBinder = new ListModelBinder(); 
     } 

     return modelBinder; 
    } 
} 

Zarejestrowałem się z dostawcą w Global.asax takiego:

GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new MyModelBinderProvider()); 

Powodem: Stworzyłem tego dostawcę, bo chcę, bez względu na to, co jest T ('1,2,3 "lub" jeden, dwa, trzy "), wiązanie do pracy.

Problem: Powiedzmy, że T to "int"; za każdym razem, gdy wysyłane jest żądanie, parametr "modelType" jest zawsze "int", a nie tym, czego się spodziewam - "List < int>", więc żądanie nie jest poprawnie obsługiwane.

Najdziwniejsze: Uprawiając jak to działa, ale T jest wyspecjalizowanym i do nich nie to, co chcę:

var simpleProvider = new SimpleModelBinderProvider(typeof(List<int>), new ListModelBinder()); 
GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, simpleProvider); 

nie widzę, co robię źle, dlaczego jest parametrem „modelType” nie oczekiwana wartość?

+0

Proszę rozwinąć dlaczego chcesz to zrobić? Jaki jest rzeczywisty scenariusz, który uważasz za przydatny? W związku z tym wydaje się, że jest to hack do czegoś, co może mieć bardziej skomplikowane rozwiązanie z innym URI w ogóle. –

Odpowiedz

0

To jest bardzo stare pytanie, ale miałem podobny problem tutaj ze starszym kodem.

Przecinki są zastrzeżone i należy go unikać, chociaż działają one w niektórych przypadkach, ale jeśli naprawdę chcesz z nich korzystać ...

myślę, że to bardziej kwestia trasa niż model spoiwa raz na „1, 2,3 "jest ścieżką do adresu URL. Zakładając, że napisałem mały RouteHandler, który robi lewę (proszę wybaczyć bardzo prostemu tłumaczeniu "word to integer").

CsvRouteHandler pobiera tablicę id z adresu URL i umieszcza ją w RouteData jako tablicę liczb całkowitych. Jeśli oryginalna tablica ma słowa takie jak jeden, dwa lub trzy, tłumaczy każdą wartość na int.

MvcRouteHandler konfiguracja

protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext) 
{ 
    var idArrayParameter = requestContext.RouteData.Values["idArray"] != null ? requestContext.RouteData.Values["idArray"].ToString() : null; 
    if (string.IsNullOrEmpty(idArrayParameter)) 
    { 
     return base.GetHttpHandler(requestContext); 
    } 

    requestContext.RouteData.Values.Remove("idArray"); // remove the old array from routedata 

    // Note: it is horrible and bugged but and you probably have your own translation method :) 
    string[] idArray = idArrayParameter.Split(','); 
    int[] ids = new int[idArray.Length]; 

    for(int i = 0; i < idArray.Length; i++) 
    { 
     if (!int.TryParse(idArray[i], out ids[i])) 
     { 
      switch (idArray[i]) 
      { 
       case "one": 
        ids[i] = 1; 
        break; 
       case "two": 
        ids[i] = 2; 
        break; 
       case "three": 
        ids[i] = 3; 
        break; 
      } 
     } 
    } 

    requestContext.RouteData.Values.Add("Id", ids); 

    return base.GetHttpHandler(requestContext); 

} 
} 

Trasa:

routes.Add(
     name: "Id Array Route", 
     item: new Route(
      url: "endpoint/{idArray}", 
      defaults: new RouteValueDictionary(new { controller = "Test", action = "Index" }), 
      routeHandler: new CsvRouteHandler()) 
    ); 
Powiązane problemy