2013-07-29 16 views
14

Khi tôi cấu hình WCF để sử dụng tuần tự jSON, và bao gồm một DataTable trong một DataContracts của tôi, nó tuần tự hóa DataTable thành XML trước khi tuần tự hóa toàn bộ DataContract thành jSON. Tôi muốn DataTable được tuần tự hóa như jSON, chứ không phải XML.Cách tốt nhất để jSON tuần tự hóa một .NET DataTable trong WCF là gì?

Câu hỏi của tôi là:

  1. Tại sao nó serialize DataTable to XML đầu tiên?
  2. Làm cách nào để chuyển nó thành serialize sang jSON?
+0

Chào mừng bạn đến với S.O. Bạn đã thử làm gì để sắp xếp lại thành json? –

+0

Hãy xem xét điều này và chuyển đổi dữ liệu của bạn thành JSON http: // stackoverflow.com/questions/17398019/cách chuyển đổi-datatable-to-json-in-c-sharp –

Trả lời

13
  1. DataTable là cấu trúc .NET thuần túy mà không thể (dễ dàng) được biểu diễn theo cách không bị mất bởi JSON. DataTables chứa rất nhiều thông tin bổ sung mà JSON không thể lưu trữ: Các khóa chính, autoincs, cho phép null, chú thích, kiểu dữ liệu, chỉ mục, vv Việc tuần tự hóa thành XML/nhị phân là những cách duy nhất mà một DataTable có thể được tuần tự hóa bằng .NET. Sau đó, DataTable được tuần tự hóa XML này được tuần tự hóa thành JSON.

  2. Sử dụng JSON.NET hoặc FastJSON để chuyển đổi DataTable sang phiên bản DataTable tương thích, trơn tru, rõ ràng, có thể được sử dụng bởi bất kỳ ứng dụng JSON nào, không chỉ các máy khách .NET WCF. Bạn sẽ mất tất cả các thuộc tính tùy chỉnh DataTable được đề cập trong (1) ở trên và chỉ nhận cặp cặp tên/giá trị JSON. Lưu trữ trong thời trang này là không hiệu quả do trùng lắp tên trường trong mỗi hàng.

Không sử dụng DataTable trong DataContract. Nếu bạn muốn các lợi ích của một DataTable và các máy khách của bạn sẽ luôn là .NET, hãy tuần tự hóa DataTable thành một mảng byte thông qua Serialization nhị phân và sau đó tùy chọn nén luồng byte tuần tự kết quả. Hiển thị một mảng byte trong DataContract của bạn. Điều này sẽ cung cấp cho bạn một phiên bản hiệu quả, hoàn toàn không mất dữ liệu của DataTable ở phía máy khách (sau khi giải nén và giải mã nhị phân), không phải phiên bản JSON của một DataTable (được cung cấp bởi (2)) ...

+0

Câu trả lời hay. Cảm ơn bạn. Khách hàng của tôi không phải là tất cả .NET, và tôi nhanh chóng phát hiện ra sự thiếu hiệu quả mà bạn đã đề cập. Tôi sẽ cố gắng sửa đổi phương pháp này để tôi không phải bao gồm các tên cột/trường với mỗi hàng. – rhyno

+0

tôi biết đây là một chủ đề cũ, nhưng fastjson hỗ trợ serialization/deserialization datatable từ phiên bản 1.7.7 được phát hành trước tháng sáu năm 2011. và định dạng xml là không hiệu quả, nó bao gồm thẻ cồng kềnh cho mỗi lĩnh vực và hàng. –

+0

@Keith Blows, làm thế nào về serializing một Danh sách DataTables? Làm thế nào để bạn đề nghị để làm điều đó? – Xegara

2

Theo biểu đồ trên trang chủ, Json.NET thực sự là lựa chọn duy nhất của bạn - bạn có thể nhanh chóng lấy nó từ NuGet. May mắn thay đó là một thư viện tuyệt vời và rất dễ sử dụng.

string json = JsonConvert.SerializeObject(myDataSet, new DataSetConverter()); 

Lưu ý rằng Rich Strahl có một bài tuyệt vời với biết thêm chi tiết, và ông cũng bao gồm một số tùy chỉnh làm việc ông đã sử dụng JavaScriptSerializer với (khá rộng) bộ chuyển đổi tùy chỉnh vì lợi ích của so sánh.

+1

Điều này làm việc, nhưng sau đó tôi nhanh chóng nhận ra rằng các cột dữ liệu/tên trường đang được bao gồm với hàng MỌI, làm cho nó rất kém hiệu quả , như đã đề cập bởi Keith. Tôi sẽ thử sửa đổi DataTableConverter và DataRowConverter để tôi không lặp lại tất cả các tên cột/trường này. – rhyno

+0

@ rhyno giải pháp cuối cùng của bạn cho việc không lặp lại tất cả các tên cột/trường là gì? Tôi có một ý tưởng về những gì tôi sẽ làm, nhưng nếu bạn đã hoàn thành nó sẽ giúp tôi tiết kiệm thời gian. – DeadlyChambers

5

Hãy thử điều này:

public string ConvertDataTabletoString(System.Data.DataTable dt) 
{ 
    System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); 
    Dictionary<string, object> row; 
    foreach (System.Data.DataRow dr in dt.Rows) 
    { 
     row = new Dictionary<string, object>(); 
     foreach (System.Data.DataColumn col in dt.Columns) 
     { 
      row.Add(col.ColumnName, dr[col]); 
     } 
     rows.Add(row); 
    } 
    return serializer.Serialize(rows); 
} 
1

tôi đã cùng một vấn đề, dịch vụ WCF của tôi đã không được định dạng json đúng cách trong khi chuyển đổi nó từ Dataset để json. tôi nhận nó làm việc bằng cách sử dụng các giải pháp sau đây:

using System.ServiceModel.Channels; 
using System.ServiceModel.Web; 

dsData là Dataset tôi

string json = Newtonsoft.Json.JsonConvert.SerializeObject(dsData); 
return WebOperationContext.Current.CreateTextResponse(json, "application/json;charset=utf-8", System.Text.Encoding.UTF8); 

và "Message" sẽ là kiểu trả về.