2013-04-02 50 views
10

Tôi hiện đang làm việc trên một chứng minh-of-khái niệm và chạy vào một vấn đề liên quan đến việc sử dụng JSON để serialize một HttpRequest.Serializing một đối tượng yêu cầu bằng cách sử dụng JSON

nền

Tôi ban đầu nghĩ rằng tôi sẽ có thể dễ dàng thực hiện nó bằng cách sử dụng phương pháp JSON.Encode() như bên dưới:

JSON.Encode(HttpContext.Request) 

Tuy nhiên, tôi nhanh chóng phát hiện ra rằng điều này gây ra tất cả các loại hình tròn tài liệu tham khảo được ném (chủ yếu là do cấu trúc thực tế và độ phức tạp của đối tượng Yêu cầu). Điều này chỉ xảy ra khi thực sự gặp phải các thuộc tính có chứa tham chiếu vòng tròn, vì trước đây tôi đã sử dụng mã sau để chỉ lấy các phần tử cụ thể mà tôi cần:

JSON.Encode(new {HttpContext.Request.Cookies,HttpContext.Request.Headers, ... }); 

.

Tôi chỉ tò mò nếu có phương pháp xử lý tốt hơn (hoặc phương pháp xử lý tốt nhất có thể là). Tôi sẽ trình bày chi tiết một vài cách tiếp cận mà tôi đã thực hiện cho đến nay dưới đây để có thể tìm thấy bất kỳ khu vực nào mà tôi có thể đã đi sai.

trước pháp tiếp cận

  • Sử dụng Reflection để lặp qua từng khách sạn thuộc Yêu cầu và cố gắng xây dựng một chuỗi JSON "bất động sản-by-bất động sản". (này thất bại khi gặp phải một hình tròn tham khảo)

  • Cố gắng để lưu trữ mỗi Properties trong một đối tượng từ điển và sau đó sử dụng JSON để serialize toàn bộ từ điển (với hy vọng rằng nó sẽ "san bằng" đối tượng ra và làm cho nó dễ dàng hơn để serialize)

  • Sử dụng JSON.NET library và cố gắng để serialize nó thông qua các phương pháp (JsonConvert.SerializeObject() tôi đã cố gắng để vượt qua trong một vài cài đặt thêm để tránh một tham chiếu vòng tròn, nhưng có không có bất kỳ may mắn nào)

cách tiếp cận mới nhất của tôi (sử dụng thư viện JSON.NET) Tôi nghĩ sẽ đến gần làm việc, tuy nhiên tôi gặp phải một lỗi mà liên quan đến một "Timeout" tài sản trên Suối đối tượng trong phạm vi yêu cầu.

Tôi không phản đối đơn giản là tránh tuần tự hóa các đối tượng Stream và Tham khảo thông tư. Tôi chỉ cố gắng lấy càng nhiều đối tượng Yêu cầu càng tốt trong khi tránh bất kỳ loại rủi ro nào trong số này.

Trả lời

3

Bất kỳ lý do cụ thể nào khiến bạn không sử dụng JSON.Net? Nó có một cài đặt trên nó được gọi là PreserveReferencesHandling, gắn thẻ các đối tượng với một thuộc tính bổ sung ("$ id": "##"). Nếu đối tượng đó xuất hiện trong tuần tự hóa nhiều hơn một lần, thay vì viết lại đối tượng, nó sẽ thay thế nó bằng "$ ref": "##" trỏ đến json đã tồn tại cho đối tượng. Điều này làm tròn tham chiếu vòng tròn.

Tôi chưa bao giờ thử trả lại JSON ở định dạng đó thành cuộc gọi $ .ajax nên tôi không biết điều gì sẽ liên quan đến việc phân tích cú pháp phía web.

+0

Cảm ơn gợi ý Malcolm. Tôi đã thử sử dụng nó một vài cách khác nhau kể từ khi đọc đề xuất của bạn và áp dụng một số cài đặt nhưng tôi vẫn gặp sự cố có vẻ (chủ yếu liên quan đến Luồng?) "Luồng không được hỗ trợ trên luồng này". Ý tưởng nào? –

+0

Điều đó khiến tôi nghĩ rằng bạn không thể JSON Chuyển đổi một đối tượng có Thuộc tính luồng. –

+0

Tôi cũng bắt đầu nghiêng về hướng đó. Nó dường như gây ra một thời gian chờ khi serializing một dòng và sau đó nó kết quả đầu ra đã đề cập trước đó. Tôi cho rằng tôi sẽ phải tìm ra một cách để bỏ qua các Tham chiếu Streams/Circular. –

2

Tôi đã sử dụng JsonConvert.SerializeObject trong dự án của mình và hoạt động tốt. Có vẻ như nó có thể giải quyết vấn đề của bạn.

JsonConvert.SerializeObject(reqObject) 
2

Tôi chỉ cố gắng làm điều tương tự, bây giờ tôi đã được quản lý để có được một cái gì đó serializing sử dụng JsonConvert với một trình giải quyết hợp đồng để bỏ qua tất cả các thuộc tính vấn đề - Tôi sử dụng dòng này để làm serialization:

string reqStr = JsonConvert.SerializeObject(context.Request, 
    Formatting.Indented, new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
     ContractResolver = new IgnoreErrorPropertiesResolver() 
}); 

và đây là mã hợp đồng resolver tôi đã sử dụng:

public class IgnoreErrorPropertiesResolver : DefaultContractResolver 
{ 

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 

     if ({"InputStream", 
      "Filter", 
      "Length", 
      "Position", 
      "ReadTimeout", 
      "WriteTimeout", 
      "LastActivityDate", 
      "LastUpdatedDate", 
      "Session" 
     }.Contains(property.PropertyName)) { 
      property.Ignored = true; 
     } 
     return property; 
    } 
} 

này sẽ cần Newtonsoft.Json.Serialization và System.Reflection usings.

Điều đó xảy ra tôi không thể bao gồm đối tượng Phiên mà tôi đang ở, vì vậy trong danh sách thuộc tính bị bỏ qua của tôi - rõ ràng là xóa thuộc tính đó nếu bạn có thể bao gồm nó!

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