2012-05-25 49 views
9

我JSON這樣獲取原始的JSON字符串在Newtonsoft.Json圖書館

{ 
    "name": "somenameofevent", 
    "type": "event", 
    "data": { 
     "object": { 
      "age": "18", 
      "petName": "18" 
     }, 
     "desct": { 
     } 
    } 
} 

,我有2個對象這樣

public class CustEvent 
{ 
    [JsonProperty("name")] 
    public string Name { get; set; } 
    [JsonProperty("type")] 
    public string EventType{ get; set; } 
    [JsonProperty("data")] 
    public SomeData Data{ get; set; } 
} 

public class SomeData 
{ 
    [JsonProperty("object")] 
    public String SomeObject { get; set;} 
    [JsonProperty("dsct")] 
    public String SomeDesct { get; set; } 
} 

我用它來解析JSON反對Newtonsoft.NET庫。以及我如何可以將RAW JSON導入SomeObject,SomeDesct屬性?在JSON中,「data.object ...」是複雜的對象,我只想得到這些屬性的RAW JSON字符串。你可以幫我嗎 ?

回答

4

您必須編寫一個自定義轉換器類(從Newtonsoft.Json.JsonConverter派生),它指示反序列化器讀取整個對象並返回該對象的JSON字符串。

然後,您必須用JsonConverter屬性來修飾屬性。

[JsonConverter(typeof(YourCustomConverterClass))] 
public string SomeObject { get; set; } 

有關於如何創建自定義轉換器在網絡上很好的教程,但 - 爲了您的方便 - 您轉換器的核心可能是這樣的:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
{ 
    return JObject.Load(reader).ToString(); 
} 

此方法讀取一個完整的JSON對象,但將對象的序列化版本作爲字符串返回。由於對象被反序列化爲JObject然後再次序列化,但是對於我來說這是最簡單的方法。也許你有更好的主意。

2

如果你所擔心的開銷,因爲對象被反序列化到一個JObject,然後再序列化(溶液@fero提供的),那麼你可以嘗試以下。

方法1:創建自己的自定義JsonConverter和覆蓋ReadJson

using(var jsonReader = new JsonTextReader(myTextReader)) 
{ 
    while(jsonReader.Read()){ 
    if(jsonReader.TokenType.PropertyName=="SomeDesct") 
    { 
     //do what you want 
    } 
    } 
} 

更多細節檢查鏈接Incremental JSON Parsing in C#

方法2:閱讀JSON字符串和應用字符串函數或正則表達式函數來獲取所需的字符串。

0

在你的情況,你可以直接從JsonConvert類使用靜態方法

PopulateObject(字符串值,對象目標,JsonSerializerSettings設置);

0

我使用自定義JsonConverter的這種實現。

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var sb = new StringBuilder(); 
     JsonToken previousToken = JsonToken.None; 

     if (reader.TokenType == JsonToken.StartObject) 
     { 
      sb.Append('{'); 
      int depth = 1; 
      while (depth > 0) 
      { 
       if (!reader.Read()) 
        break; 
       switch (reader.TokenType) 
       { 
        case JsonToken.PropertyName: 
         if (previousToken == JsonToken.Boolean || previousToken == JsonToken.Integer || previousToken == JsonToken.Float) 
          sb.Append(','); 
         sb.AppendFormat("\"{0}\":", reader.Value); 
         break; 
        case JsonToken.StartArray: 
         if (previousToken == JsonToken.EndArray) 
          sb.Append(','); 
         sb.Append('['); 
         break; 
        case JsonToken.Boolean: 
        case JsonToken.Integer: 
        case JsonToken.Float: 
         if (previousToken == JsonToken.Boolean || previousToken == JsonToken.Integer || previousToken == JsonToken.Float) 
          sb.Append(','); 
         sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}", reader.Value); 
         break; 
        case JsonToken.EndArray: 
         sb.Append(']'); 
         break; 
        case JsonToken.StartObject: 
         sb.Append('{'); 
         depth++; 
         break; 
        case JsonToken.EndObject: 
         sb.Append('}'); 
         depth--; 
         break; 
       } 
       previousToken = reader.TokenType; 
      } 
     } 
     return sb.ToString(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     writer.WriteRawValue(value.ToString()); 
    } 

    public override bool CanWrite 
    { 
     get 
     { 
      return true; 
     } 
    } 
} 
11

你不需要編寫任何轉換器,只需使用JRaw類型如下:

public class SomeData 
{ 
    [JsonProperty("object")] 
    public JRaw SomeObject { get; set;} 
    [JsonProperty("dsct")] 
    public JRaw SomeDesct { get; set; } 
} 

然後你就可以通過檢查.Value屬性訪問原始值

var rawJsonDesct = (string)data.SomeDesct.Value; 

如果要保留string簽名,只需將JSON序列化爲隱藏的公鑰operty並在訪問者調用中進行字符串轉換。

+0

絕對是最簡單的解決方案。 – sroj

0

作爲chakrit suggested,你可以做這樣的事情來爲你的對象提供一個字符串簽名,同時使用JRaw來做真正的工作。

[JsonProperty("Data")] 
    public JRaw Raw { get; set; } 

    [JsonIgnore] 
    public string Data 
    { 
     get => Raw?.Value as string; 
     set => Raw = new JRaw(value); 
    }