JSON.NET к объектам C#

Я пытаюсь использовать платформу JSON.NET в окна Form для чтения некоторой информации из строки JSON. Но я изо всех сил пытаюсь получить Словари от 'taxonomies-> массив тем и 'кластеры'

{
    "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]]'."}

Обновление 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, и т.д. Таким образом, я заменил скобки пустого квадрата для изогнутых и этого desearialized без ошибок :)

contentSearchCriteria = contentSearchCriteria.Replace("[]", "{}");
var mydata = JsonConvert.DeserializeObject<SearchMasterSearchCriteria>(contentSearchCriteria);
7
задан Benjamin Ortuzar 16 February 2010 в 10:47
поделиться

3 ответа

Если честно, я бы вообще не стал поступать так, как вы. Вот как я могу получить данные:

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 для заполнения данных. Это также делает код намного чище и позволяет компилятору проверять опечатки.

9
ответ дан 6 December 2019 в 21:13
поделиться

Да, теперь ваша проблема заключается в том, как JSON.net десериализует объекты. В JSON.net класс C # становится объектом Json. И член этого класса становится Ключом, а значение члена становится значением.

Давайте в качестве примера возьмем путь Таксономии. Используя указанное выше определение класса, JSON.net ищет данные Json в следующем формате:

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

Это совсем не похоже на ваши входные данные.

Когда вы создаете свои объекты, думайте об этом так.

1) Базовый объект создает {} в коде json. 2) Словарь создает {} в коде json. 3) Список создает [] в json code 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;
}
2
ответ дан 6 December 2019 в 21:13
поделиться

Я согласен с ответами регулярного выражения. Однако его можно упростить до «^ [\w] + $» .\w - это любой «символ слова» (который переводится в [a-zA-Z_0-9] при использовании алфавита, отличного от юникода. Я не знаю, хотите ли вы также подчеркивать.

Дополнительные сведения о регексах в .net см. здесь: http://msdn.microsoft.com/en-us/library/ms972966.aspx#regexnet_topic8

-121--2130504-

Вы можете ознакомиться с Nullsoft Scriptable Install System (NSIS) .

Компиляция сценариев установщика NSIS может быть интегрирована в систему сборки.

(Можно даже выполнить перекрестную компиляцию установщика Windows в Linux, BSD или Mac OS X.)

Подробнее см. http://nsis.sourceforge.net/ .

NSIS позволяет создавать программы установки .exe (think setup.exe).

Если требуется создать пакеты MSI, ознакомьтесь с набором инструментов Windows Installer XML (WiX) .

Подробнее об этом здесь: http://wix.sourceforge.net/

-121--3774715-

Я бы начал с сильно типизированного класса dto, предпочтительно DataContract, который путь получить возможность сериализовать его в любой нужный формат, т.е. JSON, Xml, ProtoBuf и т. д.

Примечание: JSON на самом деле довольно медленно сериализуется/десериализуется по сравнению с большинством других форматов (см.: Тесты сериализации - JSON.NET является 'NewterSoft.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);

Edit: added ссылок

Похоже, что у вас могут быть проблемы с JSON.NET, и в этом случае вы должны попробовать другие JSON .NET serializers/de-serializers. Корпорация Майкрософт поставляет System.Runtime.Serialization.Json.DataContractJsonSerializer, включенный в .NET v3.5. Вот несколько вспомогательных классов, показывающих, как сериализовать и десериализовать JSON.

Jayrock является еще одним сериализатором JSON для .NET, но он медленнее остальных, и я нахожу, что он не имеет хорошей поддержки для Generics.

1
ответ дан 6 December 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: