2010-02-15 43 views
7

Tôi đang cố gắng sử dụng khuôn khổ JSON.NET trong một cửa sổ Biểu mẫu để đọc một số thông tin từ một chuỗi JSON. Nhưng tôi đang cố gắng để có được từ điển từ mảng 'phân loại-> chủ đề' và 'các cụm'JSON.NET đối với các đối tượng C#

{ 
    "keywords": { 
     "anyString": [ 

     ], 
     "allString": { 
      "a5349f533e3aa3ccbc27de2638da38d6": "olympics" 
     }, 
     "exactString": [ 

     ], 
     "notString": [ 

     ], 
     "highlightString": [ 

     ] 
    }, 
    "dates": { 
     "startDate": "15-01-2008", 
     "endDate": "15-09-2009", 
     "useDates": true 
    }, 
    "clusters": { 
     "permission": { 
      "1": "private\/n" 
     } 
    }, 
    "taxonomies": { 
     "Topics": { 
      "2488": "Olympics 2012 (not participation)", 
      "8876": "Olympics and culture" 
     }, 
     "Keywords": { 
      "8848": "Engineering in the Olympics" 
     } 
    }, 
    "sort": { 
     "sortId": 1, 
     "sortType": 2, 
     "sort": "datetime", 
     "sortOrder": "descending" 
    } 
} 

Với mã tôi có thể đọc một số thông tin.

JObject searchCriteria = JObject.Parse(contentSearchCriteria); 
//search criteria 
IEnumerable<string> allString = searchCriteria["keywords"]["allString"].Children().Values<string>(); 
IEnumerable<string> anyString = searchCriteria["keywords"]["anyString"].Children().Values<string>(); 
IEnumerable<string> notString = searchCriteria["keywords"]["notString"].Children().Values<string>(); 
IEnumerable<string> exactString = searchCriteria["keywords"]["exactString"].Children().Values<string>(); 
IEnumerable<string> highlightString = searchCriteria["keywords"]["highlightString"].Children().Values<string>(); 
//dates 
string startDate = (string)searchCriteria["dates"]["startDate"]; 
string endDate = (string)searchCriteria["dates"]["endDate"]; 
bool useDates = (bool)searchCriteria["dates"]["useDates"]; 

//sort 
int sortId = (int)searchCriteria["sort"]["sortId"]; 
int sortType = (int)searchCriteria["sort"]["sortType"]; 
string sort = (string)searchCriteria["sort"]["sort"]; 
string sortOrder = (string)searchCriteria["sort"]["sortOrder"]; 

UPDATE:

Theo đề xuất tôi đã thêm

class SMSearchCriteria 
    { 
     public SMKeywords keywords { get; set; } 
     public SMDates dates { get; set; } 
     public SMClusters clusters { get; set; } 
     public SMTaxonomies taxonomies { get; set; } 
     public SMSort sort { get; set; } 
    } 

    class SMKeywords 
    { 
     public List<Dictionary<string, string>> AnyString {get; set;} 
     public List<Dictionary<string, string>> AllString { get; set; } 
     public List<Dictionary<string, string>> ExactString { get; set; } 
     public List<Dictionary<string, string>> NotString { get; set; } 
     public List<Dictionary<string, string>> HighlightString { get; set; } 
    } 

    class SMDates 
    { 
     public string startDate { get; set; } 
     public string endDate { get; set; } 
     public bool useDates { get; set; } 
    } 

    class SMClusters 
    { 
     List<SMCluster> cluster; 
    } 

    class SMCluster 
    { 
     public Dictionary<string, string> cluster { get; set; } 
    } 

    class SMTaxonomies 
    { 
     public List<SMTaxonomy> taxonomies { get; set; } 
    } 

    class SMTaxonomy 
    { 
     public Dictionary<string, List<SMCategory>> taxonomy { get; set; } 
    } 

    class SMCategory 
    { 
     public Dictionary<int, string> category { get; set; } 
    } 

    class SMSort 
    { 
     public int sortId { get; set; } 
     public int sortType { get; set; } 
     public string sort { get; set; } 
     public string sortOrder { get; set; } 
    } 

nhưng khi tôi thực hiện:

var mydata = JsonConvert.DeserializeObject<SMSearchCriteria>(contentSearchCriteria); 

tôi nhận được ngoại lệ:

[Newtonsoft.Json.JsonSerializationException] = {"Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[System.Collections.Generic.Dictionary`2[System.String,System.String]]'."} 

Cập nhật 2:

Như đã đề cập tôi đã gỡ bỏ tất cả các danh sách thêm và đơn giản hóa các lớp học như thế này:

class SearchMasterSearchCriteria 
    { 
     public SMKeywords keywords { get; set; } 
     public SMDates dates { get; set; } 
     public Dictionary<string, Dictionary<int, string>> clusters { get; set; } 
     public Dictionary<string, Dictionary<int, string>> taxonomies { get; set; } 
     public SMSort sort { get; set; } 
    } 

    class SMKeywords 
    { 
     public Dictionary<string, string> anyString {get; set;} 
     public Dictionary<string, string> allString { get; set; } 
     public Dictionary<string, string> exactString { get; set; } 
     public Dictionary<string, string> notString { get; set; } 
     public Dictionary<string, string> highlightString { get; set; } 
    } 

    class SMDates 
    { 
     public string startDate { get; set; } 
     public string endDate { get; set; } 
     public bool useDates { get; set; } 
    } 

    class SMSort 
    { 
     public int sortId { get; set; } 
     public int sortType { get; set; } 
     public string sort { get; set; } 
     public string sortOrder { get; set; } 
    } 

tôi mã kiểm tra cũng được bổ sung vào serialize các đối tượng như thế này:

//criteria 
      SearchMasterSearchCriteria smCriteria = new SearchMasterSearchCriteria(); 

      //keywords 
      SMKeywords smKeywords = new SMKeywords(); ; 
      Dictionary<string, string> dict = new Dictionary<string, string>(); 
      dict.Add("a5349f533e3aa3ccbc27de2638da38d6", "olympics"); 
      dict.Add("9cfa7aefcc61936b70aaec6729329eda", "games"); 
      smKeywords.allString = dict; 

      //category 
      Dictionary<int, string> categorieDict = new Dictionary<int, string>(); 
      categorieDict.Add(2488, "Olympics 2012 (not participation)"); 
      categorieDict.Add(8876, "Olympics and culture"); 

      //taxonomies 
      Dictionary<string, Dictionary<int, string>> taxonomiesDict = new Dictionary<string, Dictionary<int, string>>(); 
      taxonomiesDict.Add("Topics", categorieDict); 

      //metadata 
      Dictionary<int, string> metadataDict = new Dictionary<int, string>(); 
      metadataDict.Add(1, @"private/n"); 

      //clusters 
      Dictionary<string, Dictionary<int, string>> clustersDict = new Dictionary<string, Dictionary<int, string>>(); 
      clustersDict.Add("permission", metadataDict); 


      //dates 
      SMDates smDates = new SMDates(); 
      smDates.startDate = "15-01-2008"; 
      smDates.endDate = "15-09-2009"; 
      smDates.useDates = true; 

      //sort 
      SMSort smSort = new SMSort(); 
      smSort.sortId = 1; 
      smSort.sortType = 2; 
      smSort.sort = "datetime"; 
      smSort.sortOrder = "descending"; 

      //add to criteria. 
      smCriteria.keywords = smKeywords; 
      smCriteria.clusters = clustersDict; 
      smCriteria.taxonomies = taxonomiesDict; 
      smCriteria.dates = smDates; 
      smCriteria.sort = smSort; 

      //serialize 
      string json = JsonConvert.SerializeObject(smCriteria); 
      var mydata1 = JsonConvert.DeserializeObject<SearchMasterSearchCriteria>(json); 

Bởi thời gian đó sự khác biệt duy nhất giữa 2 chuỗi json ở đâu. các [] và null cho anyString, exactString, vv Vì vậy, tôi thay thế các dấu ngoặc vuông trống cho những người thân xoăn và nó desearialized không có lỗi :)

contentSearchCriteria = contentSearchCriteria.Replace("[]", "{}"); 
var mydata = JsonConvert.DeserializeObject<SearchMasterSearchCriteria>(contentSearchCriteria); 

Trả lời

9

Thành thật mà nói với bạn tôi sẽ không làm họ cách bạn đang làm điều đó chút nào. Đây là cách tôi muốn truy lục dữ liệu:

class Data { 
    Dictionary<string, Dictionary<string, string>> keywords; 
    DatesClass dates; 
    ....... 

} 

class DatesClass 
{ 
    string startDate; 
    string endDate; 
    bool? useDates 

} 


var mydata = JsonConvert.DeserializeObject<Data>(jsonstring); 

Tôi đã không điền vào toàn bộ lớp dữ liệu, nhưng bạn có được điểm. Tôi đã tìm thấy nó dễ dàng hơn nhiều để tạo một đối tượng trong cấu trúc dữ liệu đầu vào của bạn và sau đó sử dụng phương thức DeserializeObject để điền vào dữ liệu. Điều này cũng làm cho mã sạch hơn nhiều, và cho phép trình biên dịch kiểm tra lỗi chính tả.

+0

Hi Timothy, tôi đã cập nhật các câu hỏi với các lớp như bạn đề nghị. nhưng tôi nhận được một ngoại lệ. –

1

tôi sẽ bắt đầu với một mạnh mẽ-gõ dto hạng nhất tốt nhất là DataContract như vậy bạn sẽ có được sự lựa chọn để serialize nó vào bất kỳ định dạng mà bạn muốn, tức là JSON, XML, Protobuf vv

Lưu ý: JSON là thực sự khá chậm để serialize/de-serialize so với hầu hết các định dạng khác (xem: serialization benchmarks - JSON.NET là 'NewtonSoft.Json') Nếu bạn đang làm một ứng dụng khách phong phú thay vì ứng dụng web hơn bạn có thể muốn chọn một định dạng tuần tự khác. Bất kể định dạng nào bạn kết thúc, bạn vẫn có thể sử dụng lại cùng một DTO, ví dụ: mã của bạn sẽ ở trên trông giống như sau:

[DataContract] 
public class MyDto 
{ 
    [DataMember] 
    public Keywords keywords { get; set; } 
} 

[DataContract] 
public class Keywords 
{ 
    [DataMember] 
    public List<string> anyString { get; set; } 

    [DataMember] 
    public Dictionary<string,string> allString { get; set; } 

    [DataMember] 
    public List<string> exactString { get; set; } 

    [DataMember] 
    public List<string> notString { get; set; } 

    [DataMember] 
    public List<string> highlightString { get; set; } 
} 

var dto = new MyDto { Keywords = { allString = {{"a5349f533e3aa3ccbc27de2638da38d6", "olympics"}} }; 

var json = JsonConvert.SerializeObject(dto); 
var fromJson = JsonConvert.DeserializeObject<MyDto>(json); 

Edit: liên kết thêm

Dường như bạn có thể gặp phải vấn đề với JSON.NET trong trường hợp này bạn nên thử serializers khác JSON .NET/de -serializers. Microsoft vận chuyển một hệ thống.Runtime.Serialization.Json.DataContractJsonSerializer có trong .NET v3.5. Dưới đây là một số lớp trợ giúp cho bạn biết cách thực hiện serializede-serialize JSON.

Jayrock là một trình nối tiếp JSON khác cho .NET nhưng chậm hơn phần còn lại và tôi thấy nó không có hỗ trợ tốt cho Generics.

+0

Tôi nhận được JSON từ một hệ thống mà tôi không có quyền kiểm soát. Tôi đã cập nhật câu hỏi với các lớp học mới nhưng tôi nhận được một ngoại lệ. –

+0

ok, sau đó bạn có thể tạo một mô hình DTO được nhập lỏng lẻo chỉ với các thuộc tính của Dictionary và List 's? – mythz

+0

Bạn có thể cho tôi một ví dụ không? json.net sẽ biết những thuộc tính nào để ánh xạ tới? –

2

Vâng, vấn đề của bạn bây giờ là cách thức JSON.net deserializes đối tượng. Trong JSON.net, một lớp C# trở thành một đối tượng Json. Và một thành viên của lớp đó trở thành một Khóa với giá trị của thành viên trở thành giá trị.

Hãy lấy ví dụ về đường dẫn Phân loại làm ví dụ. Sử dụng định nghĩa lớp trên của bạn JSON.net đang tìm kiếm dữ liệu Json theo định dạng sau:

{"taxonomies": {"taxonomies":[{"taxonomy": {"Topics": {1212, "foo"}}}]} 

Điều này có vẻ không giống như dữ liệu đầu vào của bạn.

Khi bạn đang tạo đối tượng của mình nghĩ về nó theo cách này.

1) Đối tượng cơ sở tạo {} trong mã json. 2) Từ điển tạo một {} trong mã json. 3) Danh sách tạo [] trong mã json 4) mỗi thành viên của một lớp tạo mục nhập trong {} của mã json

Điều gì có thể giúp gỡ lỗi điều này cho bạn là tạo cấu trúc, điền vào một số dữ liệu tạm thời sau đó sử dụng JsonConvert.Serialize (myobj) để cho bạn thấy những gì JSON nghĩ rằng cấu trúc sẽ trông như thế nào.

Tôi nghĩ ngoại lệ của bạn xuất phát từ việc có nhiều cách.

Đây có lẽ là những gì bạn muốn taxominies phần của mã của bạn để trông giống như:

class SMSearchCriteria 
{ 
     public SMKeywords keywords { get; set; } 
     public SMDates dates { get; set; } 
     public SMClusters clusters { get; set; } 
     public SMTaxominies taxonomies { get; set; } 
     public SMSort sort { get; set; } 
} 

class SMTaxominies 
{ 
    public Dictionary<string, string> Topics; 
    public Keywords<string, string> Keywords; 
} 
0

Tại sao bạn không sử dụng LINQ to Json?

Ví dụ, việc "sắp xếp" của bạn nút ánh xạ tới lớp học của bạn

var jsonResult = JObject.Parse(jsonString); 

var sortItem = from s in jsonResult["sort"] 
select new MySortObject{ 
          SortId = s.Value<int>("sortId") 
         }; 

http://www.newtonsoft.com/json/help/html/QueryJsonLinq.htm

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