現在ログインしていません。
新規アカウント作成
ログイン

JSONのシリアライズとデシリアライズ

DataContractJsonSerializerを使うと、簡単にオブジェクトをJSONにシリアライズしたり、逆にJSONをデシリアライズしてオブジェクトにすることができます。

シリアライズ

次のようなメソッドを記述すれば、引数に渡したオブジェクトをJSONで表現した文字列が取得できます。DataContractJsonSerializerクラスを使用するにはSystem.Runtime.Serializationへ参照設定が必要ですのでご注意ください。

参照設定の方法については Visual Studioで参照設定を追加する方法 を参照して下さい。

Public Function Serialize(target As ObjectAs String

    Using stream As New IO.MemoryStream

        '▼シリアライズ実行
        Dim serializer As New Runtime.Serialization.Json.DataContractJsonSerializer(target.GetType)
        serializer.WriteObject(stream, target)

        '▼結果を取得
        Dim result As String = System.Text.Encoding.UTF8.GetString(stream.ToArray())
        Return result

    End Using

End Function
■リスト1:VB版 オブジェクトをJSONにシリアライズする

public string Serialize(object target)
{
    using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
    {

        //▼シリアライズ実行
        System.Runtime.Serialization.Json.DataContractJsonSerializer serializer 
            = new System.Runtime.Serialization.Json.DataContractJsonSerializer(target.GetType());

        serializer.WriteObject(stream, target);

        //▼結果を取得
        string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
        return result;
    }
}
■リスト2:C#版 オブジェクトをJSONにシリアライズする

念のため使用例も紹介します。次のクラスを想定します。

Public Class Person
    Public Property Name As String
    Public Property Age As Integer
End Class

Public Class Parents
    Public FamilyName As String
    Public Father As Person
    Public Mother As Person
End Class
■リスト3:

このクラスに値を設定して、JSONにシリアライズするには次のようにします。

Dim parents As New Parents
parents.FamilyName = "フグ田"
parents.Father = New Person With {.Name = "フグ田マスオ", .Age = 28}
parents.Mother = New Person With {.Name = "フグ田サザエ", .Age = 24}

Dim json As String = Serialize(parents)
■リスト4:VB版 JSONへのシリアライズ

この例を実行すると変数jsonの値は次のとおりになります。

{"FamilyName":"フグ田","Father":{"Age":28,"Name":"フグ田マスオ"},"Mother":{"Age":24,"Name":"フグ田サザエ"}}
■リスト5:生成されたJSON

デシリアライズ1 DataContractJsonSerializer

DataContractJsonSerializerクラスを使ってデシリアライズする場合には、あらかじめそのJSONに合致する定義のクラスが必要です。つまり、未知のJSONをデシリアライズすることはできません。

未知のJSONをデシリアライズするにはJson.NETを使用します。この方法は後で説明します。

以下のメソッドはDataContractJsonSerializerクラスを使ってJSONをデシリアライズします。 型引数Tにはデシリアライズされるクラスまたは構造体を指定します。

Public Function Deserialize(Of T)(json As StringAs T

    Dim result As T
    Dim serializer As New Runtime.Serialization.Json.DataContractJsonSerializer(GetType(T))

    Using stream As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json))
        result = DirectCast(serializer.ReadObject(stream), T)
    End Using

    Return result

End Function
■リスト6:VB版 JSONをオブジェクトにデシリアライズする

public T Deserialize<T>(string json)
{
    T result;

    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer
                = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));

    using (System.IO.MemoryStream stream 
        = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)))
    {
        result = (T)serializer.ReadObject(stream);
    }

    return result;

}
■リスト7:C#版 JSONをオブジェクトにデシリアライズする

念のため、このメソッドを呼び出す例も紹介します。シリアライズの例とおなじくParentsクラスとPersonクラスが存在する前提です。

Dim json As String = "{""FamilyName"":""フグ田"",""Father"":{""Age"":28,""Name"":""フグ田マスオ""},""Mother"":{""Age"":24,""Name"":""フグ田サザエ""}}"
Dim parents As Parents

parents = Deserialize(Of Parents)(json)
■リスト8:VB版 JSONからのデシリアライズ

この例を実行するとparentsにはJSONで表現された値が設定されます。Parents, PersonとJSONの定義はVBまたはC#のクラスの定義とそれぞれ一致している必要があります。一致している保証がない場合、この手法は使用できません。その場合は、次に紹介するJson.NETの例を使用してください。

デシリアライズ2 Json.NET

Json.NETの準備

Json.NETを使ってJSONをデシリアライズすることもできます。Json.NETは非常にポピュラーなJSON操作用のライブラリでデシリアライズ以外にもいろいろな機能があります。

ASP.NETのプロジェクトの場合、既定でJson.NETが使用できるようになっています。その他の場合は、まずNuGetを使ってJson.NETをインストールする必要があります。

参照設定にNewtonsoft.Jsonが表示されていればJson.NETはすぐに利用可能です。 そうでない場合は、プロジェクトを右クリックして[NuGetパッケージの管理]から、Newtonsoft.Jsonを探してインストールしてください。 このライブラリは非常にメジャーなので、わざわざ検索しなくてもインストール可能なパッケージのトップに表示されているかもしれません。

C#の場合

C#の場合、Newtonsoft.Jsonの準備ができれば次のようにプログラムすれば未知のJSONをデシリアライズできます。

string json = "{\"FamilyName\":\"フグ田\",\"Father\":{\"Age\":28,\"Name\":\"フグ田マスオ\"},\"Mother\":{\"Age\":24,\"Name\":\"フグ田サザエ\"}}";
dynamic d = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

//デシリアライズした値を読み取る
Console.WriteLine(d.FamilyName);
Console.WriteLine(d.Father.Name);
■リスト9:C#版 未知のJSONをデシリアライズする

値を読み取るには、そのオブジェクトが既知であるかのようにプロパティ(のようなもの)にアクセスするだけです。

このように簡易的に未知の属性にアクセスできるのは動的ランタイムがうまく使われているからです。Json.NETはC#のdynamicととても相性がよいように作られています。

VBの場合

VBでも同様のことができるのですが、少し背景が異なります。Json.NETの作者は残念ながらVBとC#との動的ランタイムの背景の差を考慮に入れてくれなかったようです。そのためVBで同じことをするには少し手順が必要です。

まず、Option Strict を Offにする必要があります。これは必須です。

その上で、VB + Json.NETで単純にデシリアライズして値にアクセスするには次のようにします。

Dim json As String = "{""FamilyName"":""フグ田"",""Father"":{""Age"":28,""Name"":""フグ田マスオ""},""Mother"":{""Age"":24,""Name"":""フグ田サザエ""}}"
Dim d As Object = Newtonsoft.Json.JsonConvert.DeserializeObject(json)

'デシリアライズした値を読み取る
Console.WriteLine(d("FamilyName"))
Console.WriteLine(d("Father")("Name"))
■リスト10:VB版 未知のJSONをデシリアライズする

JSONのデシリアライズについてはC#と同じですが、その後、デシリアライズした値を読み取るプログラムは少し見慣れないものになっています。

これで満足できるならば話は終わりです。どうしても d.FamilyNamed.Father.Name という記述で値にアクセスしたい場合はJson.NETの作者がやってくれなかったVB用の配慮を自分で行います。

それにはまず次のようなクラスを定義します。

Public Class DynamicAdapter
    Inherits System.Dynamic.DynamicObject

    Protected Property JSource As Newtonsoft.Json.Linq.JObject

    Public Sub New(jsource As Newtonsoft.Json.Linq.JObject)
        Me.JSource = jsource
    End Sub

    Public Overrides Function TryGetMember(binder As GetMemberBinderByRef result As ObjectAs Boolean

        If JSource.ContainsKey(binder.Name) Then
            Dim value As Object = JSource(binder.Name)
            If TypeOf value Is Newtonsoft.Json.Linq.JObject Then
                result = New DynamicAdapter(value)
            Else
                result = value
            End If

            Return True
        Else
            Return False
        End If

    End Function

End Class
■リスト11:VB版 .演算子で未知のJSONの属性にアクセスするアダプター

このクラスについてはここでは説明しません。興味がある人はDynamicObjectをキーワードに情報を調べてみてください。

このDynamicAdapterクラスが利用できる前提で、次のようにプログラムすることが可能になります。

Dim json As String = "{""FamilyName"":""フグ田"",""Father"":{""Age"":28,""Name"":""フグ田マスオ""},""Mother"":{""Age"":24,""Name"":""フグ田サザエ""}}"
Dim d As Object = New DynamicAdapter(Newtonsoft.Json.JsonConvert.DeserializeObject(json))

Console.WriteLine(d.FamilyName)
Console.WriteLine(d.Father.Name)
■リスト12:VB版 未知のJSONをデシリアライズして.でアクセスする

バージョン

バージョン
Visual Basic 6.0不可
Visual Basic.NET(2002)不可
Visual Basic.NET 2003不可
Visual Basic 2005不可
Visual Basic 2008不可
Visual Basic 2010不可。技術的にはOKですがこの記事では一部対応していないAPIを使用しています。
Visual Basic 2012OK
Visual Basic 2013OK
Visual Basic 2015OK
Visual Basic 2017OK