2017-10-03 2 views
1

親オブジェクト内にあるネストされたオブジェクトのプロパティをJSON逆シリアル化します。私は私がにデシリアライズするために、オブジェクトモデルを書いているJSON次ているC#

[DataContract] 
public class KeepTruckinResponse 
{ 
    [DataMember(Name = "company_webhooks", EmitDefaultValue = false)] 
    public KeepTruckinCompanyWebHook[] WebHooks { get; set; } 

    [DataMember(Name = "pagination", EmitDefaultValue = false)] 
    public KeepTruckinPagination Pagination { get; set; } 

    public string RawJSON { get; set; } 
} 

[DataContract] 
public class KeepTruckinPagination 
{ 
    [DataMember(Name = "per_page", EmitDefaultValue = false)] 
    public int PerPage { get; set; } 

    [DataMember(Name = "page_no", EmitDefaultValue = false)] 
    public int PageNumber { get; set; } 

    [DataMember(Name = "total", EmitDefaultValue = false)] 
    public int Total { get; set; } 
} 

[DataContract(Name = "company_webhook")] 
public class KeepTruckinCompanyWebHook 
{ 
    [DataMember(Name = "id", EmitDefaultValue = false)] 
    public int Id { get; set; } 

    [DataMember(Name = "url", EmitDefaultValue = false)] 
    public string Url { get; set; } 
} 

を明らかに、私はJSONをデシリアライズするとき、私はKeepTruckinCompanyWebHookを得ることはありません。ここで

{ 
    "company_webhooks": [ 
    { 
     "company_webhook": { 
     "id": 42, 
     "url": "https://keeptruckin.com/callbacktest/842b02", 
     "secret": "fe8b75de0a4e5898f0011faeb8c93654", 
     "format": "json", 
     "actions": [ 
      "vehicle_location_received", 
      "vehicle_location_updated" 
     ], 
     "enabled": false 
     } 
    }, 
    { 
     "company_webhook": { 
     "id": 43, 
     "url": "https://keeptruckin.com/callbacktest/a6a783", 
     "secret": "66a7368063cb21887f546c7af91be59c", 
     "format": "json", 
     "actions": [ 
      "vehicle_location_received", 
      "vehicle_location_updated" 
     ], 
     "enabled": false 
     } 
    }, 
    { 
     "company_webhook": { 
     "id": 44, 
     "url": "https://keeptruckin.com/callbacktest/53a52c", 
     "secret": "4451dc96513b3a67107466dd2c4d9589", 
     "format": "json", 
     "actions": [ 
      "vehicle_location_received", 
      "vehicle_location_updated" 
     ], 
     "enabled": false 
     } 
    }, 
    { 
     "company_webhook": { 
     "id": 45, 
     "url": "https://keeptruckin.com/callbacktest/6fb337", 
     "secret": "4177fbd88c30faaee03a4362648bd663", 
     "format": "json", 
     "actions": [ 
      "vehicle_location_received", 
      "vehicle_location_updated" 
     ], 
     "enabled": false 
     } 
    }, 
    { 
     "company_webhook": { 
     "id": 46, 
     "url": "https://keeptruckin.com/callbacktest/8cd6da", 
     "secret": "6e41817a048b009435e5102fca17db55", 
     "format": "json", 
     "actions": [ 
      "vehicle_location_received", 
      "vehicle_location_updated" 
     ], 
     "enabled": false 
     } 
    } 
    ], 
    "pagination": { 
    "per_page": 25, 
    "page_no": 1, 
    "total": 5 
    } 
} 

は私が持っているものですコレクションを送信する方法が「入れ子になっている」ためです。私はほとんどプロパティの中にKeepTruckinCompanyWebHookの中に別のオブジェクトを作成しなければなりません。しかし、私はオブジェクトモデルをそのまま維持したいと思います。 .NETシリアライザで可能ですか?

は、我々はそうのようなDataContractJsonSerializerを使用します。

var ser = new DataContractJsonSerializer(typeof(KeepTruckinResponse)); 
response = ser.ReadObject(ms) as KeepTruckinResponse; 

この時点で、我々はNewtonSoft.Jsonを使用したくない

+0

編集あなたの質問。 'DataContract'の使用は、より多く使われている' NewtonSoft.Json'属性の方が一般的に避けられます。 –

+0

"明らかにJSONを逆シリアル化すると、コレクションの送信方法が入れ子になっているのでKeepTruckinCompanyWebHookプロパティが得られません" その意味。 Newtonsoftを使用する人として、私はそれが非直列化されることを非常に期待しています。 –

答えて

0

はい、これは可能ですが、あなたはそれを行うにはいくつかのカスタムコードが必要になります。

それは少し醜いですが、あなたはDictionary<string, Dictionary<string, object>>company_webhooks、配列内の各JSONオブジェクトをデシリアライズして、あなたのKeepTruckinCompanyWebHookクラスのインスタンスにネストされた辞書構造から値をコピーするカスタムIDataContractSurrogateクラスを作成することができます。ここでは、サロゲートのために必要となるコードがあります:

class MyDataContractSurrogate : IDataContractSurrogate 
{ 
    public Type GetDataContractType(Type type) 
    { 
     if (type == typeof(KeepTruckinCompanyWebHook)) 
     { 
      return typeof(Dictionary<string, Dictionary<string, object>>); 
     } 
     return type; 
    } 

    public object GetDeserializedObject(object obj, Type targetType) 
    { 
     if (obj.GetType() == typeof(Dictionary<string, Dictionary<string, object>>) && 
      targetType == typeof(KeepTruckinCompanyWebHook)) 
     { 
      var webHook = new KeepTruckinCompanyWebHook(); 
      var outerDict = (Dictionary<string, Dictionary<string, object>>)obj; 
      var innerDict = outerDict["company_webhook"]; 

      foreach (PropertyInfo prop in GetDataMemberProperties(typeof(KeepTruckinCompanyWebHook))) 
      { 
       DataMemberAttribute att = prop.GetCustomAttribute<DataMemberAttribute>(); 

       object value; 
       if (innerDict.TryGetValue(att.Name, out value)) 
       { 
        prop.SetValue(webHook, value); 
       } 
      } 

      return webHook; 
     } 
     return obj; 
    } 

    public object GetObjectToSerialize(object obj, Type targetType) 
    { 
     if (obj.GetType() == typeof(KeepTruckinCompanyWebHook) && 
      targetType == typeof(Dictionary<string, Dictionary<string, object>>)) 
     { 
      var webHook = (KeepTruckinCompanyWebHook)obj; 
      var outerDict = new Dictionary<string, Dictionary<string, object>>(); 
      var innerDict = new Dictionary<string, object>(); 
      outerDict.Add("company_webhook", innerDict); 

      foreach (PropertyInfo prop in GetDataMemberProperties(typeof(KeepTruckinCompanyWebHook))) 
      { 
       DataMemberAttribute att = prop.GetCustomAttribute<DataMemberAttribute>(); 
       innerDict.Add(att.Name, prop.GetValue(webHook)); 
      } 

      return outerDict; 
     } 
     return obj; 
    } 

    private IEnumerable<PropertyInfo> GetDataMemberProperties(Type type) 
    { 
     return type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetCustomAttribute<DataMemberAttribute>() != null); 
    } 

    // ------- The rest of these methods do not need to be implemented ------- 
    public object GetCustomDataToExport(Type clrType, Type dataContractType) 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType) 
    { 
     throw new NotImplementedException(); 
    } 

    public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes) 
    { 
     throw new NotImplementedException(); 
    } 

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData) 
    { 
     throw new NotImplementedException(); 
    } 

    public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit) 
    { 
     throw new NotImplementedException(); 
    } 
} 

サロゲートを使用するには、DataContractJsonSerializerSettingsのインスタンスを作成し、設定し、次のプロパティを持つDataContractJsonSerializerにそれを渡す必要があります。 UseSimpleDictionaryFormat設定が必要なため、このソリューションは.Net 4.5以降でのみ動作します。ここで

var settings = new DataContractJsonSerializerSettings(); 
settings.DataContractSurrogate = new MyDataContractSurrogate(); 
settings.KnownTypes = new List<Type> { typeof(Dictionary<string, Dictionary<string, object>>) }; 
settings.UseSimpleDictionaryFormat = true; 

デモです:

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""company_webhooks"": [ 
      { 
       ""company_webhook"": { 
       ""id"": 42, 
       ""url"": ""https://keeptruckin.com/callbacktest/842b02"", 
       ""secret"": ""fe8b75de0a4e5898f0011faeb8c93654"", 
       ""format"": ""json"", 
       ""actions"": [ 
        ""vehicle_location_received"", 
        ""vehicle_location_updated"" 
       ], 
       ""enabled"": false 
       } 
      }, 
      { 
       ""company_webhook"": { 
       ""id"": 43, 
       ""url"": ""https://keeptruckin.com/callbacktest/a6a783"", 
       ""secret"": ""66a7368063cb21887f546c7af91be59c"", 
       ""format"": ""json"", 
       ""actions"": [ 
        ""vehicle_location_received"", 
        ""vehicle_location_updated"" 
       ], 
       ""enabled"": false 
       } 
      }, 
      { 
       ""company_webhook"": { 
       ""id"": 44, 
       ""url"": ""https://keeptruckin.com/callbacktest/53a52c"", 
       ""secret"": ""4451dc96513b3a67107466dd2c4d9589"", 
       ""format"": ""json"", 
       ""actions"": [ 
        ""vehicle_location_received"", 
        ""vehicle_location_updated"" 
       ], 
       ""enabled"": false 
       } 
      }, 
      { 
       ""company_webhook"": { 
       ""id"": 45, 
       ""url"": ""https://keeptruckin.com/callbacktest/6fb337"", 
       ""secret"": ""4177fbd88c30faaee03a4362648bd663"", 
       ""format"": ""json"", 
       ""actions"": [ 
        ""vehicle_location_received"", 
        ""vehicle_location_updated"" 
       ], 
       ""enabled"": false 
       } 
      }, 
      { 
       ""company_webhook"": { 
       ""id"": 46, 
       ""url"": ""https://keeptruckin.com/callbacktest/8cd6da"", 
       ""secret"": ""6e41817a048b009435e5102fca17db55"", 
       ""format"": ""json"", 
       ""actions"": [ 
        ""vehicle_location_received"", 
        ""vehicle_location_updated"" 
       ], 
       ""enabled"": false 
       } 
      } 
      ], 
      ""pagination"": { 
      ""per_page"": 25, 
      ""page_no"": 1, 
      ""total"": 5 
      } 
     }"; 

     var settings = new DataContractJsonSerializerSettings(); 
     settings.DataContractSurrogate = new MyDataContractSurrogate(); 
     settings.KnownTypes = new List<Type> { typeof(Dictionary<string, Dictionary<string, object>>) }; 
     settings.UseSimpleDictionaryFormat = true; 

     KeepTruckinResponse response = Deserialize<KeepTruckinResponse>(json, settings); 

     foreach (KeepTruckinCompanyWebHook wh in response.WebHooks) 
     { 
      Console.WriteLine("Id: " + wh.Id + ", Url: " + wh.Url); 
     } 
    } 

    public static T Deserialize<T>(string json, DataContractJsonSerializerSettings settings) 
    { 
     using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) 
     { 
      var ser = new DataContractJsonSerializer(typeof(T), settings); 
      return (T)ser.ReadObject(ms); 
     } 
    } 

    public static string Serialize(object obj, DataContractJsonSerializerSettings settings) 
    { 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      var ser = new DataContractJsonSerializer(obj.GetType(), settings); 
      ser.WriteObject(ms, obj); 
      return Encoding.UTF8.GetString(ms.ToArray()); 
     } 
    } 
} 

[DataContract] 
public class KeepTruckinResponse 
{ 
    [DataMember(Name = "company_webhooks", EmitDefaultValue = false)] 
    public KeepTruckinCompanyWebHook[] WebHooks { get; set; } 

    [DataMember(Name = "pagination", EmitDefaultValue = false)] 
    public KeepTruckinPagination Pagination { get; set; } 

    public string RawJSON { get; set; } 
} 

[DataContract] 
public class KeepTruckinPagination 
{ 
    [DataMember(Name = "per_page", EmitDefaultValue = false)] 
    public int PerPage { get; set; } 

    [DataMember(Name = "page_no", EmitDefaultValue = false)] 
    public int PageNumber { get; set; } 

    [DataMember(Name = "total", EmitDefaultValue = false)] 
    public int Total { get; set; } 
} 

[DataContract(Name = "company_webhook")] 
public class KeepTruckinCompanyWebHook 
{ 
    [DataMember(Name = "id", EmitDefaultValue = false)] 
    public int Id { get; set; } 

    [DataMember(Name = "url", EmitDefaultValue = false)] 
    public string Url { get; set; } 
} 

出力:あなたはデータをシリアライズされホイを表示する

Id: 42, Url: https://keeptruckin.com/callbacktest/842b02 
Id: 43, Url: https://keeptruckin.com/callbacktest/a6a783 
Id: 44, Url: https://keeptruckin.com/callbacktest/53a52c 
Id: 45, Url: https://keeptruckin.com/callbacktest/6fb337 
Id: 46, Url: https://keeptruckin.com/callbacktest/8cd6da 
関連する問題