문제

json 문자열에서 일부 정보를 읽기 위해 Windows 양식에서 json.net 프레임 워크를 사용하려고합니다. 그러나 나는 '분류-> 주제'배열과 '클러스터'에서 사전을 얻기 위해 고군분투하고 있습니다.

{
    "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"
    }
}

코드가 벨로우어로 일부 정보를 읽을 수있었습니다.

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"];

업데이트:

추천대로 추가했습니다

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; }
    }

하지만 실행할 때 :

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

나는 예외를 얻는다 :

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

Update 2:

제안 된 바와 같이 모든 추가 목록을 제거하고 클래스를 단순화했습니다.

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; }
    }

또한 다음과 같은 개체를 직렬화하기 위해 테스트 코드를 추가했습니다.

//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);

그때까지 2 개의 JSON 줄 사이의 유일한 차이점. anystring, exactstring 등의 []와 널.

contentSearchCriteria = contentSearchCriteria.Replace("[]", "{}");
var mydata = JsonConvert.DeserializeObject<SearchMasterSearchCriteria>(contentSearchCriteria);
도움이 되었습니까?

해결책

당신에게 솔직히 말해서 나는 그들이 당신이 그렇게하는 방식을 전혀하지 않을 것입니다. 데이터를 검색하는 방법은 다음과 같습니다.

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

}

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

}


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

전체 데이터 클래스를 작성하지는 않았지만 요점을 얻습니다. 입력 데이터의 구조에서 객체를 만들고 DeserializeObject 메소드를 사용하여 데이터를 채우는 것이 훨씬 쉽다는 것을 알았습니다. 또한 코드를 훨씬 더 깨끗하게 만들고 컴파일러가 오타를 확인할 수 있습니다.

다른 팁

예, 지금 당신의 문제는 JSON.NET이 객체를 버리는 방식입니다. JSON.NET에서 C# 클래스는 JSON 객체가됩니다. 그리고 그 클래스의 구성원은 멤버의 가치가 가치가되는 핵심이됩니다.

분류 경로의 예를 예로 들어 봅시다. 위의 클래스 정의 사용 json.net 은이 형식의 JSON 데이터를 찾고 있습니다.

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

이것은 입력 데이터만큼 전혀 보이지 않습니다.

객체를 만들 때 이런 식으로 생각하십시오.

1) 기본 객체는 JSON 코드에서 {}을 만듭니다. 2) 사전은 JSON 코드에서 {}를 만듭니다. 3) 목록은 JSON 코드 4)에서 []를 생성합니다. 클래스의 모든 구성원은 JSON 코드의 {}에 항목을 만듭니다.

이것을 디버깅하는 데 도움이 될 수있는 것은 구조를 만들고, 온도 데이터를 채우고, jsonconvert.serialize (myobj)를 사용하여 JSON이 구조가 어떻게 보일지 생각하는 것을 보여주는 것입니다.

당신의 예외는 많은 수업에 대한 방법에서 비롯된 것 같습니다.

이것은 아마도 코드의 분류 부분이 다음과 같은 모양을 원하는 것일 것입니다.

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;
}

나는 강력하게 유형 된 DTO 클래스 먼저 먼저 원하는 데이터 콘텐츠로 시작하여 원하는 모든 형식 (예 : JSON, XML, Protobuf 등)으로 선택할 수 있습니다.

참고 : JSON은 실제로 대부분의 다른 형식에 비해 직렬화/디시 리얼 화에 매우 느립니다 (참조 : 참조 : 참조 : 직렬화 벤치 마크 - json.net은 'newtonsoft.json'입니다.) 웹 앱 대신 풍부한 클라이언트 앱을 수행하는 경우 다른 직렬화 형식을 선택하려는 것보다. 어떤 형식을 사용하든 관계없이 동일한 DTO를 재사용 할 수 있습니다. 예를 들어 위의 코드는 다음과 같은 것 같습니다.

[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);

편집하다: 추가 링크

JSON.NET에 문제가있는 것 같습니다.이 경우 다른 JSON .NET SERIALIZERS/DE-SERIALIZERS를 사용해야합니다. Microsoft는 System.runtime.serialization.json.datacontractjsonserializer를 .net v3.5에 포함시킵니다. 다음은 방법을 보여주는 몇 가지 도우미 수업입니다 직렬화 그리고 해제 JSON.

제이 록 .NET의 또 다른 JSON 시리얼 라이저이지만 나머지보다 느립니다. 제네릭을 잘 지원하지 않습니다.

LINQ에서 JSON을 사용하지 않는 이유는 무엇입니까?

예를 들어, "정렬"노드를 클래스에 매핑하는 것

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top