【问题标题】:How to Convert JSON object to Custom C# object?如何将 JSON 对象转换为自定义 C# 对象?
【发布时间】:2011-01-15 20:15:47
【问题描述】:

有没有一种简单的方法可以使用通过 AJAX 传递的 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 Object的对象结构的C#类

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

【问题讨论】:

标签: c# asp.net .net ajax json


【解决方案1】:

既然我们都喜欢单行代码

Newtonsoft 比 java 脚本序列化器更快。 ...这个依赖于 Newtonsoft NuGet 包,它比默认的序列化程序更受欢迎并且更好。

如果我们有课,那么在下面使用。

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

没有类然后使用动态

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

【讨论】:

    【解决方案2】:

    在 C# 中使用 JSON 的一个好方法是使用 JSON.NET

    来自JSON.NET - Official siteQuick Starts & API Documentation 帮助您使用它。

    如何使用它的示例:

    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);
     }
    

    【讨论】:

    • 这就像一个冠军,但如果我的 json 中有多个项目并且我想创建一个对象列表怎么办?
    • @Djeroen:我看到了两种方法。如果项目未分组,请尝试找到拆分字符串的方法,并在循环中重复该过程。如果将它们分组,则创建对象的对象
    • 我更喜欢其他答案中提到的一种衬里.. 恕我直言。
    • 是的,这不是一个好方法,下面使用 DeserializeObject 的方法更干净
    【解决方案3】:

    为了让您的选择保持开放,如果您使用的是 .NET 3.5 或更高版本,这里有一个完整的示例,您可以使用泛型直接从框架中使用。正如其他人所提到的,如果不仅仅是简单的对象,您应该真正使用 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 哈!好点,是的,这些应该被包裹起来。事后看来,只需使用 JSON.NET!
    • 如果 DataContractJsonSerializer 类不可见,您必须通过右键单击解决方案中的引用来添加对 System.Runtime.Serialization 的引用,选择 .NET 选项卡并选择 System.Runtime.Serialization
    • 这种情况会中断。如果您的 JSON 对象用单引号表示属性,则此函数将失败。例如它无法解析 {'Subject': 'Emailing: Web User Activity Log11', 'EmbedAsImage': true} 但它能够解析 {"Subject": "Emailing: Web User Activity Log11", "EmbedAsImage":真的}
    • 另外我需要用 DataContract 和 DataMember 属性装饰我的简单类。没有它就无法解析。
    • 与 Vishal 不同,POCO 类对我来说非常有效...... +1 因为这避免了对 JSON.NET 的依赖。
    【解决方案4】:

    鉴于您的代码示例,您无需执行任何其他操作。

    如果您将该 JSON 字符串传递给您的 Web 方法,它将自动解析 JSON 字符串并创建一个填充的 User 对象作为您的 SaveTeam 方法的参数。

    不过,一般而言,您可以使用下面的 JavascriptSerializer 类,或者为了获得更大的灵活性,可以使用任何各种 Json 框架(Jayrock JSON 是一个很好的框架)来轻松处理 JSON。

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

    【讨论】:

    • 我认为你必须使用一个可枚举的类型(所以在这个例子中是 List
    • 如果包含子视图模型我们如何反序列化
    • 对于那些寻找你需要引用System.Web.Extensions 程序集并添加using System.Web.Script.Serialization 以获取JavaScriptSerializer 的人,但是一旦你这样做,这似乎是反序列化你的@987654326 的最干净的方法@strings 到 c# 具体类中。
    【解决方案5】:

    另一个非常简单的解决方案是使用库 Newtonsoft.Json:

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

    【讨论】:

    • 但是如果 User 对象的属性中有另一个 JSon 数据,这将失败...
    • @gumuruh 我想我不明白你的说法。如果您有一个复杂对象,其属性是另一个复杂对象,它们也会被转换,只要您的 Json 字符串具有正确的数据。
    【解决方案6】:

    以下 2 个示例使用了两者中的任何一个

    1. JavaScriptSerializerSystem.Web.Script.Serialization
    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 页面{VERSION}\Assemblies\System.Web.Helpers.dll

    或者

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

    希望这会有所帮助!

    【讨论】:

    • 这是一个很好的答案,但棘手的是,对于dynamic 类型,您不会得到任何真正的类型检查。例如,如果您的 JSON 包含 "Name" : "Ahmed" 并且您在 C# 代码中输入错误的“名称”,这是一个运行时错误 (bleh)。
    • 谢谢!请更新答案以说明对于示例 1,您需要引用 System.Web.Extensions.dll
    • 超级棒的答案,动态打字也适用于 json.net v6.0.6!
    【解决方案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你可以阅读here

    【讨论】:

      【解决方案8】:

      使用 JavaScriptSerializer() 没有提供的通用解决方案那么严格:public static T Deserialize(string json)

      当将 json 传递到与您尝试转换到的对象定义不完全匹配的服务器时,这可能会派上用场。

      【讨论】:

        【解决方案9】:

        在性能方面,我发现 ServiceStack 的序列化器比其他序列化器快一点。它是 ServiceStack.Text 命名空间中的 JsonSerializer 类。

        https://github.com/ServiceStack/ServiceStack.Text

        ServiceStack 可通过 NuGet 包获得: https://www.nuget.org/packages/ServiceStack/

        【讨论】:

          【解决方案10】:

          JSON.Net 是您最好的选择,但根据对象的形状以及是否存在循环依赖关系,您可以使用 JavaScriptSerializer 或 DataContractSerializer。

          【讨论】:

            【解决方案11】:

            JSON C# class generator on codeplex 生成与 NewtonSoftJS 配合良好的类。

            【讨论】:

              【解决方案12】:

              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 应该是可序列化的more on Data Contract

              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);
                      }
                  }
              }
              

              【讨论】:

                【解决方案13】:

                而不是仅仅作为一个对象发送。

                创建一个可访问的公共属性类并将数据发送到 Web 方法。

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

                在 ajax 调用中使用相同的参数名称来发送数据。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-07-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-10-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多