7

tôi có như sau:Làm thế nào để một mô hình C# Web API binder nhà cung cấp làm việc?

  • yêu cầu url: 'endpoint/1,2,3 q = foo?'
  • hành động mà yêu cầu được ràng buộc: đối tượng nào Bar ([ModelBinder] Danh sách < T> id, [FromUri] chuỗi q)

tôi muốn để lập bản đồ "1,2,3" mảnh với "id" tham số, vì vậy tôi đã tạo ra một ModelBinderProvider theo this link, mà nên gọi đúng chất kết dính mô hình.

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

Tôi đã đăng ký nhà cung cấp trong Global.asax như thế này:

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

Lý do: Tôi tạo ra cung cấp dịch vụ này bởi vì tôi muốn, bất kể những gì T là ('1,2,3 'hoặc' một, hai, ba '), ràng buộc để làm việc.

Sự cố: Giả sử T là 'int'; mỗi lần một yêu cầu được gửi, paramater 'modelType' luôn luôn là 'int' và không phải những gì tôi mong đợi - 'Danh sách < int>', vì vậy yêu cầu không được xử lý đúng cách.

Các lạ điều: Làm một cái gì đó giống như làm việc này nhưng T là chuyên ngành và do không phải những gì tôi muốn:

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

Tôi không thể nhìn thấy những gì tôi đang làm sai, tại sao là tham số của modelType ' không phải là giá trị kỳ vọng?

+0

Xin hãy giải thích lý do tại sao bạn sẽ muốn làm điều này? Kịch bản thực tế mà bạn thấy điều này hữu ích như thế nào? Như vậy nó thực sự có vẻ giống như một hack để một cái gì đó mà có thể có một giải pháp phức tạp hơn với một URI khác nhau hoàn toàn. –

Trả lời

0

Đây là một câu hỏi rất cũ nhưng tôi gặp vấn đề tương tự ở đây với mã cũ.

Dấu phẩy được dành riêng và nó nên tránh mặc dù họ làm việc trong một số trường hợp nhưng nếu bạn thực sự muốn sử dụng chúng ...

Tôi nghĩ rằng đó là một vấn đề nhiều tuyến đường hơn một chất kết dính mô hình một lần "1, 2,3 "là phần đường dẫn của url. Giả sử điều này tôi đã viết một RouteHandler nhỏ mà làm các trick (xin vui lòng tha thứ cho rất đơn giản "từ số nguyên" dịch).

CsvRouteHandler lấy mảng id từ URL và đặt nó trên RouteData dưới dạng một mảng các số nguyên. Nếu mảng ban đầu có các từ như một, hai hoặc ba thì nó dịch mỗi giá trị thành int.

MvcRouteHandler cấu hình

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

} 
} 

Route:

routes.Add(
     name: "Id Array Route", 
     item: new Route(
      url: "endpoint/{idArray}", 
      defaults: new RouteValueDictionary(new { controller = "Test", action = "Index" }), 
      routeHandler: new CsvRouteHandler()) 
    ); 
Các vấn đề liên quan