2015-05-01 5 views
3

У меня есть JSON, который обладает множеством свойств, большинство из которых являются простыми типами данных. Однако у меня есть одно свойство в JSON, которое, когда я десериализую его на класс C#, просто нужно его десериализовать как строку.Deserialize Свойство объекта JSON для строки

Пример JSON:

{"simpleProperty": "value1", "json":{"a":"a1", "b":"b1"}} 

"JSON" объект не имеет набор структуры, кроме это будет действительным объектом JSON.

Итак, в приведенном выше примере значение «json» является объектом JSON, но когда он получает десериализацию, мне нужна его как строка.

Так что, если мой C# класс:

public class MyClass 
{ 
    public string SimpleProperty { get; set; } 
    public string Json { get; set; } 
} 

И потом, если я использую:

var myClass = JsonConvert.DeserializeObject<MyClass>(jsonStr); 

Я хотел myClass.Json просто быть простой строкой.

Я смотрел на создание пользовательского JsonConverter для этого, но это кажется слишком сложным для чего-то такого простого. Мне, должно быть, что-то не хватает. Любое направление было бы высоко оценено.

Я также видел этот пост - но на самом деле не дает ответа на вопрос: JSON.Net - How to deserialize JSON to object but treating a property as a string instead of JSON?

ответ

3

Для моих потребностей, я решил пойти дальше и реализовать пользовательские JsonConverter следующим образом:

class JsonConverterObjectToString : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return (objectType == typeof(JTokenType)); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      JToken token = JToken.Load(reader); 
      if (token.Type == JTokenType.Object) 
      { 
       return token.ToString(); 
      } 
      return null; 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      //serializer.Serialize(writer, value); 

      //serialize as actual JSON and not string data 
      var token = JToken.Parse(value.ToString()); 
      writer.WriteToken(token.CreateReader()); 

     } 
    } 

Я не тщательно протестировали выше реализации, и я не совсем уверен, о методе Canconvert, как это никогда не казалось, для вызова, но он, похоже, выполняет преобразование, а затем позволяет мне сохранить десериализованный класс в MongoDB, а данные JSON хранятся в строке. Так что все хорошо. Я нашел следующее полезное в реализации: How to deserialize a JSON property that can be two different data types using Json.NET

UPDATE: модифицированный метод WriteJson для сериализации в качестве объекта JSON (а не строки).

+1

Метод 'CanConvert' не будет вызываться, если вы используете атрибут' [JsonConverter] 'для класса или свойства, потому что Json.Net уже знает, что ваш конвертер может обрабатывать этот тип. (Вы сказали это, добавив атрибут.) 'CanConvert' вызывается, если вы не используете атрибут' [JsonConverter] 'и вместо этого передаете экземпляр преобразователя в сериализатор через настройки. В этом случае Json.Net должен спросить конвертер, может ли он обрабатывать каждый тип, с которым он сталкивается. Поэтому вы хотите, чтобы метод CanConvert возвращал значение true для типа объекта, для которого ваш конвертер предназначен для обработки. –

+0

ok - спасибо за объяснение. – csheets

1

Вы можете альтернативно использовать JToken типа для свойства, чтобы указать, что любой действительный JSON может пойти туда. Хотя это не совсем то, о чем вы просили, этого может быть достаточно.

public class MyClass 
{ 
    public string SimpleProperty { get; set; } 
    public JToken Json { get; set; } 
} 

Doing myClass.Json.ToString() будет получить вам JSON как string.

+0

Спасибо, но, к сожалению, это не работает для моего случая использования из-за того, как тогда класс должен использоваться в контексте существующей структуры, которая должна потреблять этот класс и делать с ним что-нибудь. – csheets

Смежные вопросы