2016-11-10 4 views
2

JSONをオブジェクトに逆シリアル化したいが、ネストされたJSONを逆シリアル化したくないJSONは、私はJSONデータの下に、ここで私は、「住所」エンティティプロセス内のJSONをエスケープせずに、「生の」JSONを含む文字列メンバーをシリアル化および逆シリアル化する方法

String jsonEmployees = 
"{"Employees": 
[{"EmpId":1, "EmpName":"ABC", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]}, 
{"EmpId":2, "EmpName":"XYZ", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]}] 
}" 

public class Employee 
{ 
    public int EmpId { get; set; } 
    public string EmpName { get; set; } 
    // **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string 
    public string Address { get; set; } 
} 

public class RootObject 
{ 
    public List<Employee> Employees { get; set; } 
} 

var Employees = JsonConvert.DeserializeObject<RootObject>(jsonEmployees); 
のためのJSONを入れ子になってきていると仮定//

...(明確なアイデアのために、「 私の予想出力」をご確認ください)JSONリストに変換する必要があります

//私の期待される出力

Employees[0].EmpId = 1; 
Employees[0].EmpName = "ABC"; 
Employees[0].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]"; 

Employees[1].EmpId = 2; 
Employees[1].EmpName = "XYZ"; 
Employees[1].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]"; 

私にこの問題を解決するための最良の方法を提案してください...

答えて

5

ご質問はがどのように私はstringメンバーでシリアル化と型をデシリアライズすることができ、ありますそのプロセスでJSONをエスケープしないで、 "生の" JSONを含んでいますか?

これはJsonWriter.WriteRawValue()JRaw.Create()を使用して、生のJSONを読み取り、書き込み、そのcustom JsonConverterを介して行うことができます。

public class RawConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var raw = JRaw.Create(reader); 
     return raw.ToString(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var s = (string)value; 
     writer.WriteRawValue(s); 
    } 
} 

そして、次のようにあなたのタイプに適用します:

public class Employee 
{ 
    public int EmpId { get; set; } 
    public string EmpName { get; set; } 
    // **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string 
    [JsonConverter(typeof(RawConverter))] 
    public string Address { get; set; } 
} 

public class RootObject 
{ 
    public List<Employee> Employees { get; set; } 
} 

サンプルfiddleを。

生のJSON文字列は、有効なJSONを表すである必要があります。そうでなければ、作成されたJSONは読めなくなります。リテラルJSONが有効であることを保証したい場合は、内部的に解析された状態でJSONを保つことができます。

public class Employee 
{ 
    public int EmpId { get; set; } 
    public string EmpName { get; set; } 

    [JsonProperty("Address")] 
    JToken AddressToken { get; set; } 

    [JsonIgnore] 
    public string Address 
    { 
     get 
     { 
      if (AddressToken == null) 
       return null; 
      return AddressToken.ToString(Formatting.Indented); // Or Formatting.None if you prefer 
     } 
     set 
     { 
      if (value == null) 
       AddressToken = null; 
      else 
       // Throw an exception if value is not valid JSON. 
       AddressToken = JToken.Parse(value); 
     } 
    } 
} 

コンバータは、この実装では必要ありませんが。

+0

ありがとうございます** @ dbc ** ... **解決した**私の問題は両方のソリューションが完璧に働いています...もう一度ありがとうあなたの貴重な解決策... – Shri

0

JSON中括弧{}内のオブジェクトの表記法、および配列のためのものである[]角括弧です。

あなたの配列がそのような中括弧でカプセル化されている限り、別のオブジェクトを使用する必要があります。 {"Employees":接頭辞と}接尾辞を取り除くことができれば、JSONを従業員のリストに直接変換することができます。

編集:申し訳ありませんが、私はその質問を理解しませんでした。

JSONを制御できるかどうかによって、実際には単純か本当に難しいことができます。

あなたはJSONを制御することができた場合、あなたがする必要があるすべては、それは次のようになりますので、アドレス値の周りの単一引用符を追加します:

[{"EmpId":1, "EmpName":"ABC", "Address":'[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]'}, 

そして、それはそれです!シリアライザはこれを文字列に変換します。

自分でJSONを逆シリアル化しなければならない場合は、トークンでトークンします。あるいは、回避策を行い、対応するアドレスクラスを作成し、シリアライザに変換させることができます。次に、計算されたプロパティを追加し、シリアライザを使用してアドレスを逆シリアル化してJSONに戻します。
(醜いですが、実装するほうがはるかに高速です)

+0

返信ありがとうございますCKY ... – Shri

+0

私は従業員のリストにJSONの上に変換することができます..しかし、私の質問は私の住所エンティティデータがなるように従業員オブジェクトにJSONの上に逆変換(変換)リスト

の代わりにJSON形式で入力します。私の予想される出力を確認してください...私は可能ではないか、あなたの解決策が同じものであるかどうかを知っていれば訂正します... – Shri

1

私はあなたが従業員のリストを再構築する必要がありますと思う:

 RootObject Employees = JsonConvert.DeserializeObject<RootObject>(jsonEmployees); 

     List<Employee> EmployeesNew = new List<Employee>(); 

     foreach (var item in Employees.Employees) 
     { 
      string StringAddress = JsonConvert.SerializeObject(item.Address, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); 
      EmployeesNew.Add(new Employee { EmpId = item.EmpId, EmpName = item.EmpName, AddressString = StringAddress }); 

     } 

あなたのクラス:

public class Employee 
    { 
     public int EmpId { get; set; } 
     public string EmpName { get; set; } 
     // **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string 
     public List<AddressItems> Address { get; set; } 
     public string AddressString { get; set; } 
    } 

    public class RootObject 
    { 
     public List<Employee> Employees { get; set; } 
    } 

    public class AddressItems 
    { 
     public int AddressId { get; set; } 
     public string Address { get; set; } 
    } 
+0

ヤンガ - これは私にとってはうまくいくと思いますが、私の問題は** dbc **によって解決されています...貴重な時間をありがとう... – Shri

関連する問題