はい、これは可能ですが、あなたはそれを行うにはいくつかのカスタムコードが必要になります。
それは少し醜いですが、あなたは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
編集あなたの質問。 'DataContract'の使用は、より多く使われている' NewtonSoft.Json'属性の方が一般的に避けられます。 –
"明らかにJSONを逆シリアル化すると、コレクションの送信方法が入れ子になっているのでKeepTruckinCompanyWebHookプロパティが得られません" その意味。 Newtonsoftを使用する人として、私はそれが非直列化されることを非常に期待しています。 –