JSONオブジェクトをカスタムC#オブジェクトに変換する方法


247

A#を介して渡されたJSONオブジェクトをC#オブジェクトに入力する簡単な方法はありますか?

これは、JSON.stringifyを使用してページからC#WEBMETHODに渡されるJSONオブジェクトです

{
    "user": {
        "name": "asdf",
        "teamname": "b",
        "email": "c",
        "players": ["1", "2"]
    }
}

JSONオブジェクトを受け取るC#WebMetod

[WebMethod]
public static void SaveTeam(Object user)
{

}

WebMethodに渡されるJSONオブジェクトのオブジェクト構造を表すC#クラス

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

69
json2csharp.comを使用してc#クラスを生成できることを追加します。完全な開示:私はこのサイトを作成しました。
JonathanK


@JonathanKあなたは私の救世主です!
Matheno 2017年

回答:


218

C#でJSONを使用する良い方法は、JSON.NETを使用することです

JSON.NETのクイックスタートとAPIドキュメント-公式サイトJSON.NETの操作に役立ちます。

それを使用する方法の例:

public class User
{
    public User(string json)
    {
        JObject jObject = JObject.Parse(json);
        JToken jUser = jObject["user"];
        name = (string) jUser["name"];
        teamname = (string) jUser["teamname"];
        email = (string) jUser["email"];
        players = jUser["players"].ToArray();
    }

    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

// Use
private void Run()
{
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
    User user = new User(json);

    Console.WriteLine("Name : " + user.name);
    Console.WriteLine("Teamname : " + user.teamname);
    Console.WriteLine("Email : " + user.email);
    Console.WriteLine("Players:");

    foreach (var player in user.players)
        Console.WriteLine(player);
 }

5
これはチャンピオンのように機能しますが、jsonに複数のアイテムがあり、オブジェクトリストを作成したい場合はどうなりますか?
ジェローエン

@Djeroen:それには2つの方法があると思います。アイテムがグループ化されていない場合は、文字列を分割する方法を見つけて、ループでプロセスを繰り返します。グループ化されている場合は、オブジェクトのオブジェクトを作成します
user1011138

1
私は他の回答で述べられている1つのライナーを好みます。
RayLoveless 2017年

はい、これは良いアプローチではありません。以下のDeserializeObjectを使用する方がずっときれいです
Andrew

207

私たちはみんなワンライナーコードが大好きなので

Newtonsoftは、javaスクリプトシリアライザーよりも高速です。...これは、人気がありデフォルトのシリアライザよりも優れているNewtonsoft NuGetパッケージに依存しています。

クラスがある場合は、以下を使用します。

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(jsonString);

クラスは動的ではありません

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);

95

オプションを開いたままにするために、.NET 3.5以降を使用している場合は、Genericsを使用してフレームワークから直接使用できるラップされた例を次に示します。他の人が述べたように、単純なオブジェクトではない場合は、JSON.netを実際に使用する必要があります。

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

あなたは必要になるでしょう:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

@ChristianPayne ha!良い点は、はい、これらはラップする必要があります。これを後から見て、JSON.NETを使用してください!
ジャミン2013

2
DataContractJsonSerializerクラスが表示されない場合は、ソリューションの参照を右クリックしてSystem.Runtime.Serializationへの参照を追加し、.NETタブを選択してSystem.Runtime.Serialization
DanKodi

1
これが壊れる1つのシナリオ。JSONオブジェクトが単一引用符でプロパティを表す場合、この関数は失敗します。たとえば、{'Subject': 'Emailing:Web User Activity Log11'、 'EmbedAsImage':true}は解析できませんでしたが、{"Subject": "Emailing:Web User Activity Log11"、 "EmbedAsImage"は解析できました:true}
dreamerkumar 2013年

さらに、DataContract属性とDataMember属性で単純なクラスを装飾する必要がありました。それなしではパースしません。
dreamerkumar 2013年

Vishalとは異なり、POCOクラスは私にとって完璧に機能しました... +1により、JSON.NETへの依存が回避されます。
ダンク

54

コードサンプルを前提として、他に何もする必要はありません。

そのJSON文字列をWebメソッドに渡すと、JSON文字列が自動的に解析され、SaveTeamメソッドのパラメーターとして入力されたUserオブジェクトが作成されます。

一般に、JavascriptSerializer以下のようにクラスを使用するか、柔軟性を高めるために、JSONを簡単に操作するために、さまざまなJsonフレームワーク(Jayrock JSONが良いもの)のいずれかを使用します。

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse); 

1
ienumerable型を使用する必要があると思います(この例ではList <User>)
Dragouf


1
見ている人にとっては、System.Web.Extensionsアセンブリを参照し、using System.Web.Script.Serializationを取得するためにを追加する必要がありJavaScriptSerializerますが、これを行うと、json文字列をc#具象クラスに逆シリアル化する最もクリーンな方法のように思えます。
Serj Sagan

41

別の本当にシンプルなソリューションは、ライブラリNewtonsoft.Jsonを使用することです:

User user = JsonConvert.DeserializeObject<User>(jsonString);

ただし、Userオブジェクトのプロパティに別のJSonデータがある場合、これは失敗します...
gumuruh

@gumuruh私はあなたの発言を理解できなかったと思います。ウィッチプロパティが別の複雑なオブジェクトである複雑なオブジェクトがある場合、Json文字列がデータを正しく持っている限り、それらも変換されます。
ダニエル

33

次の2つの例では、どちらかを使用しています。

  1. System.Web.Script.Serializationの下のJavaScriptSerializerまたは
  2. System.Web.Helpersの下のJson.Decode

例1: System.Web.Script.Serializationの使用

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void Test()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            dynamic jsonObject = serializer.Deserialize<dynamic>(json);

            dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values
            x = jsonObject["user"]["name"]; // result is asdf
            x = jsonObject["user"]["players"]; // result is object[] players with its values
        }
    }
}

使用法: JSONオブジェクトからカスタムC#オブジェクトへ

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJavaScriptSerializer()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<dynamic>(json);
            name = (string)jsonObject["user"]["name"];
            teamname = (string)jsonObject["user"]["teamname"];
            email = (string)jsonObject["user"]["email"];
            players = jsonObject["user"]["players"];
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

例2: System.Web.Helpersを使用する

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            dynamic jsonObject = Json.Decode(json);

            dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values
            x = jsonObject.user.name; // result is asdf
            x = jsonObject.user.players; // result is dynamic json array players with its values
        }
    }
}

使用法: JSONオブジェクトからカスタムC#オブジェクトへ

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            var jsonObject = Json.Decode(json);
            name = (string)jsonObject.user.name;
            teamname = (string)jsonObject.user.teamname;
            email = (string)jsonObject.user.email;
            players = (DynamicJsonArray) jsonObject.user.players;
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

このコードでは、System.Web.Helpers名前空間を追加する必要があります。

%ProgramFiles%\ Microsoft ASP.NET \ ASP.NET Web Pages {VERSION} \ Assemblies \ System.Web.Helpers.dll

または

%ProgramFiles(x86)%\ Microsoft ASP.NET \ ASP.NET Web Pages {VERSION} \ Assemblies \ System.Web.Helpers.dll

お役に立てれば!


これは非常に良い答えですが、dynamic注意が必要なのは、型を使用すると、真の型チェックが行われないことです。たとえば、JSONに"Name" : "Ahmed"C#コードで「名前」を誤って入力した場合、それはランタイムエラーです(ブレ)。
Jess

ありがとう!例1の場合はSystem.Web.Extensions.dllを参照する必要があると回答を更新してください
Valamas '19年

1
すばらしい回答です。動的タイピングはjson.net v6.0.6でも機能します。
stackuser83 14年

7
public static class Utilities
{
    public static T Deserialize<T>(string jsonString)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {    
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

詳細については、次のリンクhttp://ishareidea.blogspot.in/2012/05/json-conversion.htmlにアクセスしてください

こちらについてDataContractJsonSerializer Classこちらをご覧ください


5

JavaScriptSerializer()の使用は、提供されている一般的なソリューションほど厳密ではありません。public static T Deserialize(string json)

これは、変換しようとしているオブジェクト定義と完全に一致しないjsonをサーバーに渡すときに便利です。



1

JSON.Netが最善の策ですが、オブジェクトの形状と循環依存関係があるかどうかに応じて、JavaScriptSerializerまたはDataContractSerializerを使用できます。



1

JavaScriptシリアライザー:必要 using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T>
{
    private readonly JavaScriptSerializer serializer;

    public JavaScriptSerializerDeSerializer()
    {
        this.serializer = new JavaScriptSerializer();
    }

    public string Serialize(T t)
    {
        return this.serializer.Serialize(t);
    }

    public T Deseralize(string stringObject)
    {
        return this.serializer.Deserialize<T>(stringObject);
    }
}

データコントラクトシリアライザー:必須using System.Runtime.Serialization.Json; -ジェネリック型Tはデータコントラクトでよりシリアライズ可能である必要があります

public class JsonSerializerDeserializer<T> where T : class
{
    private readonly DataContractJsonSerializer jsonSerializer;

    public JsonSerializerDeserializer()
    {
        this.jsonSerializer = new DataContractJsonSerializer(typeof(T));
    }

    public string Serialize(T t)
    {
        using (var memoryStream = new MemoryStream())
        {
            this.jsonSerializer.WriteObject(memoryStream, t);
            memoryStream.Position = 0;
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }

    public T Deserialize(string objectString)
    {
        using (var ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes((objectString))))
        {
            return (T)this.jsonSerializer.ReadObject(ms);
        }
    }
}

0

単なるオブジェクトとして送信するのではなく。

アクセス可能なプロパティのパブリッククラスを作成し、データをWebメソッドに送信します。

[WebMethod]
public static void SaveTeam(useSomeClassHere user)
{
}

ajax呼び出しで同じパラメーター名を使用してデータを送信します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.