2009-11-23 26 views
6

Lớp sau không deserialize (nhưng không tuần tự hóa) sử dụng System.Web.Script.Serialization.JavaScriptSerializer.Không thể Deserialize một KeyValuePair Nullable từ JSON với ASP.NET AJAX

public class foo { 
    public KeyValuePair<string, string>? bar {get;set;} 
} 

Cố gắng deserialize kết quả trong một System.NullReferenceException khi System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject đạt đến bar tài sản. (Lưu ý, đó là phỏng đoán dựa trên dấu vết ngăn xếp.)

Thay đổi loại thuộc tính thành KeyValuePair<string,string> khắc phục sự cố, nhưng tôi muốn giữ loại Nullable nếu có thể.

Các JSON là chính xác những gì bạn mong đợi:

{"foo": { 
    "bar": { 
    "Key":"Jean-Luc", 
    "Value":"Picard" 
    } 
}} 

Trợ giúp?

+0

Việc deserialization cho KeyValuePair không sửa lỗi ở trên, nhưng thực sự dẫn đến hai chuỗi rỗng cho cặp. tức là, các deserialization kết quả trong mất dữ liệu. Vì vậy, JSON ở trên biến thành một KeyValuePair của [,]! – Noel

Trả lời

4

Lý do điều này xảy ra là khi JavaScriptSerializer cố gắng deserialize nó sẽ tạo ra một thể hiện mới của lớp (trong KeyValuePair) này và sau đó gán các giá trị cho các thuộc tính.

Điều này gây ra sự cố vì KeyValuePair chỉ có thể có khóa và giá trị được chỉ định như một phần của hàm tạo và không phải thông qua thuộc tính do đó dẫn đến khóa và giá trị trống.

Bạn sẽ có thể giải quyết vấn đề này và lỗi bằng cách tạo lớp học triển khai JavaScriptConverterRegistering It. Tôi đã sử dụng mã dưới đây để xử lý một KeyValuePair tiêu chuẩn nhưng tôi chắc chắn bạn có thể mở rộng nó để xử lý nulls.

public class DictionaryJavaScriptConverter<k, v> : JavaScriptConverter 
{ 

    public override object Deserialize(System.Collections.Generic.IDictionary<string, object> dictionary, System.Type type, System.Web.Script.Serialization.JavaScriptSerializer serializer) 
    { 
     return new KeyValuePair<k, v>((k)dictionary["Key"], (v)dictionary["Value"]); 
    } 

    public override System.Collections.Generic.IDictionary<string, object> Serialize(object obj, System.Web.Script.Serialization.JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override System.Collections.Generic.IEnumerable<System.Type> SupportedTypes { 
     get { return new System.Type[] { typeof(KeyValuePair<k, v>) }; } 
    } 
} 

Hoặc bạn có thể tạo một lớp đơn giản có hai khóa và giá trị thuộc tính.

+0

Cảm ơn câu trả lời. Tôi đã đấu tranh với vấn đề này trong một thời gian ngắn và tôi không thể tìm ra lý do tại sao chỉ là về tất cả các loại dữ liệu khác sẽ làm việc nhưng không phải là một KeyValuePair. Một lần nữa, cảm ơn, đó là một phản ứng đơn giản và rất hữu ích. – PetrolMan

+1

Tôi tự hỏi, trong bối cảnh MVC 3: Có cách nào để đăng ký bộ chuyển đổi này để tất cả các ràng buộc mô hình JSON có quyền truy cập vào bộ chuyển đổi này không? Việc đăng ký trình chuyển đổi với một cá thể JavaScriptSerializer cụ thể không thực sự phù hợp với mô hình MVC 3 ràng buộc. – kdawg

Các vấn đề liên quan