7

I sahiptirler:C# Web API model binder sağlayıcısı nasıl çalışır?

  • isteğe URL: 'son nokta/1,2,3 q = FON?' Isteği bağlı olduğu
  • hareket: ortak nesne Bar ([ModelBinder] listesi < uygun çağırmalıdır T> kimlikleri, [FromUri] dize q)

I "kimlikleri" parametresine "1,2,3" fragmanı eşlemek istediğiniz yüzden this link uygun bir ModelBinderProvider oluşturulur, model bağlayıcı.

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

nedeni:

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; 
    } 
} 

böyle Global.asax sağlayıcı kayıtlı ben istediğim için bu sağlayıcıyı yarattı, ne olursa olsun T ('1,2,3 olduğunu 'ya da' bir, iki, üç '), işe yaradı.

10 Sorun: T, 'int' diyelim; Her zaman bir istek gönderilir, 'modelType' paramater her zaman 'int' ve beklediğim değil - 'List < int>', bu nedenle istek düzgün bir şekilde ele alınmadı.

garip şey:

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

ben yanlış yapıyorum göremiyorum, neden 'modelType' parametredir: bu işleri ama T ne istiyorum uzman ve bunun değil gibi bir şey yapmak beklenen değer değil mi?

+0

hakkında detaylı bilgi veriniz? Bunu yararlı olarak gördüğünüz gerçek senaryo nedir? Bu nedenle, tamamen farklı bir URI ile daha ayrıntılı bir çözüme sahip olabilecek bir şeye hack gibi görünüyor. –

cevap

0

Bu çok eski bir soru ama burada eski bir kodla benzer bir sorunum vardı. ,

virgüller ayrılmıştır ve bunlar bazı durumlarda işe rağmen kaçınılmalıdır ama gerçekten ...

bunları kullanmak istiyorsanız bunu "1 kez modeli ciltteki daha rota sorunu daha olduğunu düşünüyorum 2,3 "URL'nin yolun bir parçasıdır. Bunu farz edersek, hile yapan küçük bir RouteHandler yazdım (lütfen "basit" kelimeyi tamsayıya çevir "çevirisini).

CsvRouteHandler, id dizisini URL'den alır ve bir dizi tamsayı olarak RouteData'ya yerleştirir. Orijinal dizinin bir, iki veya üç gibi kelimeleri varsa, her değeri int.

MvcRouteHandler

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); 

} 
} 

Rota yapılandırma: Bunu neden isteyeyim

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