デシリアライズ後のオブジェクトから値を取る際に null チェックをするコードが冗長になるのを防ぐため、IDictionary にメソッドを生やしておく。
using System.Collections.Generic;
namespace ExampleJsonDotNet
{
public static class DictionaryExtensions
{
public static TValue GetOrDefault<TKey, TValue>(
this IDictionary<TKey, TValue> self,
TKey key,
TValue defaultValue = default(TValue))
{
// 本来は自身の null チェックなんかやるべきじゃないが、これで検証してしまったのでこのままにする
if (self == null)
{
return defaultValue;
}
return self.TryGetValue(key, out TValue value) ? value : defaultValue;
}
}
}using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
{
""drinks"": [
{
""name"": ""Dr.Pepper"",
""price"": 100
},
{
""name"": ""Cocacola"",
""price"": 160
},
{
""name"": ""Pepsi"",
""price"": 120
}
]
}
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value[0].GetOrDefault("name"));
}
}
}上記のコードを実行すると次のログが出力される。
[0:] Dr.Pepper
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
System.Diagnostics.Debug.WriteLine(deserializedObject == null);
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value.Length);
}
}
}[0:] True
[0:] 0
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
{
""drinks"": null
}
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value.Length);
}
}
}[0:] 0
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
{
""drinks"": []
}
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value.Length);
}
}
}[0:] 0
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
""""
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value.Length);
}
}
}[0:] 0
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using Xamarin.Forms;
namespace ExampleJsonDotNet
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var json = @"
?
";
var deserializedObject = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(),
},
});
var value = ((JArray)deserializedObject.GetOrDefault("drinks"))?.ToObject<IDictionary<string, object>[]>() ?? new Dictionary<string, object>[0];
System.Diagnostics.Debug.WriteLine(value.Length);
}
}
}06-01 06:15:15.280 I/MonoDroid( 8467): UNHANDLED EXCEPTION:
06-01 06:15:15.298 I/MonoDroid( 8467): Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: ?. Path '', line 2, position 16.
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonTextReader.ParseValue () [0x002b3] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonTextReader.Read () [0x0004c] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonReader.ReadAndMoveToContent () [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonReader.ReadForType (Newtonsoft.Json.Serialization.JsonContract contract, System.Boolean hasConverter) [0x00043] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00053] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x0002d] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at ExampleJsonDotNet.MainPage..ctor () [0x00015] in D:\json.net\ExampleJsonDotNet\ExampleJsonDotNet\MainPage.xaml.cs:19
06-01 06:15:15.298 I/MonoDroid( 8467): at ExampleJsonDotNet.App..ctor () [0x0000f] in D:\json.net\ExampleJsonDotNet\ExampleJsonDotNet\App.xaml.cs:14
06-01 06:15:15.298 I/MonoDroid( 8467): at ExampleJsonDotNet.Droid.MainActivity.OnCreate (Android.OS.Bundle bundle) [0x00027] in D:\json.net\ExampleJsonDotNet\ExampleJsonDotNet.Android\MainActivity.cs:23
06-01 06:15:15.298 I/MonoDroid( 8467): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <25661073a35344a89f215a4cf81af37c>:0
06-01 06:15:15.298 I/MonoDroid( 8467): at (wrapper dynamic-method) System.Object.9d328e96-a934-4c37-b5b4-d68404209c0e(intptr,intptr,intptr)
06-01 06:15:15.323 W/art ( 8467): JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable
06-01 06:15:15.329 D/Mono ( 8467): DllImport searching in: '__Internal' ('(null)').
06-01 06:15:15.329 D/Mono ( 8467): Searching for 'java_interop_jnienv_throw'.
06-01 06:15:15.329 D/Mono ( 8467): Probing 'java_interop_jnienv_throw'.
06-01 06:15:15.329 D/Mono ( 8467): Found as 'java_interop_jnienv_throw'.
An unhandled exception occured.
referenceTable GDEF length=814 1
referenceTable GSUB length=11364 1
referenceTable GPOS length=47302 106-01 06:15:16.143 E/mono ( 8467):
06-01 06:15:16.143 E/mono ( 8467): Unhandled Exception:
06-01 06:15:16.143 E/mono ( 8467): Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: ?. Path '', line 2, position 16.
06-01 06:15:16.143 E/mono ( 8467): at (wrapper dynamic-method) System.Object.9d328e96-a934-4c37-b5b4-d68404209c0e(intptr,intptr,intptr)
06-01 06:15:16.144 E/mono-rt ( 8467): [ERROR] FATAL UNHANDLED EXCEPTION: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: ?. Path '', line 2, position 16.
06-01 06:15:16.144 E/mono-rt ( 8467): at (wrapper dynamic-method) System.Object.9d328e96-a934-4c37-b5b4-d68404209c0e(intptr,intptr,intptr)