2015-05-28 21 views
5

Tôi không thể liên kết JSON với Dictionary<string,string> ở Nancy.Mô hình ràng buộc với Từ điển <string, string> trong Nancy

Tuyến đường này:

Get["testGet"] = _ => 
{ 
    var dictionary = new Dictionary<string, string> 
    { 
     {"hello", "world"}, 
     {"foo", "bar"} 
    }; 

    return Response.AsJson(dictionary); 
}; 

trả về JSON sau, như mong đợi:

{ 
    "hello": "world", 
    "foo": "bar" 
} 

Khi tôi cố gắng và gửi JSON này chính xác trở lại tuyến đường này:

Post["testPost"] = _ => 
{ 
    var data = this.Bind<Dictionary<string, string>>(); 
    return null; 
}; 

tôi nhận ngoại lệ:

Giá trị "[Hello, world]" không thuộc loại "System.String" và không thể sử dụng trong bộ sưu tập chung này.

Có thể liên kết với Dictionary<string,string> sử dụng ràng buộc mô hình mặc định của Nancys không và nếu có, tôi đang làm gì sai ở đây?

Trả lời

5

Nancy không có built-in converter cho từ điển. Vì lý do này, bạn cần phải sử dụng BindTo<T>() như vậy

var data = this.BindTo(new Dictionary<string, string>()); 

sẽ sử dụng CollectionConverter. Vấn đề với việc làm như thế này là nó sẽ chỉ thêm giá trị chuỗi, vì vậy nếu bạn gửi

{ 
    "hello": "world", 
    "foo": 123 
} 

kết quả của bạn sẽ chỉ chứa khóa hello.

Nếu bạn muốn nắm bắt tất cả các giá trị dưới dạng chuỗi, ngay cả khi chúng không được cung cấp như vậy, thì bạn sẽ cần sử dụng tùy chỉnh IModelBinder.

Điều này sẽ chuyển đổi tất cả các giá trị thành chuỗi và trả lại Dictionary<string, string>.

public class StringDictionaryBinder : IModelBinder 
{ 
    public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration, params string[] blackList) 
    { 
     var result = (instance as Dictionary<string, string>) ?? new Dictionary<string, string>(); 

     IDictionary<string, object> formData = (DynamicDictionary) context.Request.Form; 

     foreach (var item in formData) 
     { 
      var itemValue = Convert.ChangeType(item.Value, typeof (string)) as string; 

      result.Add(item.Key, itemValue); 
     } 

     return result; 
    } 

    public bool CanBind(Type modelType) 
    { 
     // http://stackoverflow.com/a/16956978/39605 
     if (modelType.IsGenericType && modelType.GetGenericTypeDefinition() == typeof (Dictionary<,>)) 
     { 
      if (modelType.GetGenericArguments()[0] == typeof (string) && 
       modelType.GetGenericArguments()[1] == typeof (string)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

Nancy sẽ tự động đăng ký cho bạn và bạn có thể ràng buộc mô hình của mình như bình thường.

var data1 = this.Bind<Dictionary<string, string>>(); 
var data2 = this.BindTo(new Dictionary<string, string>()); 
Các vấn đề liên quan