Skip to content

Instantly share code, notes, and snippets.

@caramelopardalis
Last active June 1, 2018 06:19
Show Gist options
  • Select an option

  • Save caramelopardalis/e93278f074a4b81f266a05e8bd7af035 to your computer and use it in GitHub Desktop.

Select an option

Save caramelopardalis/e93278f074a4b81f266a05e8bd7af035 to your computer and use it in GitHub Desktop.

デシリアライズ後のオブジェクトから値を取る際に 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment