将JSON字符串转换为C#对象

235

尝试在C#中将JSON字符串转换为对象。使用一个非常简单的测试案例:

JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

问题在于routes_list从未被设置,它是一个未定义的对象。有任何想法吗?


1
@Greg: 我实际上建议使用 JavaScriptSerializer 而不是微软的版本,因为它只接受 WCF 的自定义 JSON 格式(例如,看起来像日期但没有用 DATE() 包围的日期字段会失败)。 - Brad Christie
此外,请看一下这篇使用JavascriptSerializer在.NET中解析JSON对象的文章,它其实是一篇非常棒的教程。 - scatmoi
你从哪里获取JavaScriptSerializer?在我的C# .NET 3.5项目中无法识别它。 - B. Clay Shannon-B. Crow Raven
1
@B. Clay Shannon 这个对我有用,解决了我的问题 https://dev59.com/bWw05IYBdhLWcg3w11Mk - Fuzzybear
你可以使用JavaScriptSerializer来完成这个任务,而且不会出现任何问题。我将在下面提供答案。 - AHAMED AAQIB
17个回答

310

或者,您可以按照以下方式使用Newtonsoft.Json库:

using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);

其中 T 是您的对象类型,与您的 JSON 字符串匹配。


你最终创建的“T”类型类可以是部分的,不需要是包含每个JSON属性的完全响应的精确副本。你可以只反序列化你需要的内容,尽管层次结构需要匹配。 - Prashanth Subramanian

139

看起来您正在尝试将内容反序列化为原始对象。您可以创建一个代表所转换对象的类。这在处理较大的对象或JSON字符串时非常有用。

例如:

  class Test {

      String test; 

      String getTest() { return test; }
      void setTest(String test) { this.test = test; }

  }

那么您的反序列化代码应该是:

   JavaScriptSerializer json_serializer = new JavaScriptSerializer();
   Test routes_list = 
          (Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

在这个教程中可以找到更多信息: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx


1
但是在这篇文章中使用了自动属性。也值得一提。 - Ivan Kochurkin
11
抱歉,但这个代码示例无法运行。DeserializeObject会抛出异常。请使用var routes_list = serializer.Deserialize<Test>("{"test":"some data"}");。此外,您不需要get/setTest(),并且String test应该是public。这看起来更像是Java而不是C#。 - dvallejo
正如Dan Vallejo所提到的,这是一个不正确的解决方案。毕竟,setTest(String test)没有返回值,这也是编译错误。 - Payam
1
可以使用以下代码: json_serializer.Deserialize<Test>("{ "test":"some data" }"); //代替 (Test)json_serializer..... - Bashar Abu Shamaa
2
如果您不确定类对象的格式,请尝试使用此链接。它可以将您的Json字符串转换为正确的类。节省了我的大量时间! - jade290

60
你可能不想将routes_list声明为对象类型。它没有.test属性,因此你不会得到一个好的对象返回。这是其中一个最好定义类或结构体的地方,或者使用dynamic关键字。
如果你真的希望这段代码按照你的方式工作,你需要知道DeserializeObject返回的对象是一个字符串和对象的通用字典。以下是以这种方式执行的代码:
var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);

如果您想使用动态关键字,可以在这里阅读相关内容
如果您声明一个类或结构体,您可以调用Deserialize而不是像这样调用DeserializeObject:
class MyProgram {
    struct MyObj {
        public string test { get; set; }
    }

    static void Main(string[] args) {
        var json_serializer = new JavaScriptSerializer();
        MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
        Console.WriteLine(routes_list.test);

        Console.WriteLine("Done...");
        Console.ReadKey(true);
    }
}

执行中:json_serializer = new JavaScriptSerializer(); object routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ "test":"some data here" }");仍然出现“routes_list在当前上下文中不存在”的错误。 - Justin
1
不要使用“object routes_list”。使用“var”或明确地重复自己并将routes_list声明为IDictionary<string,object>。 - mattmc3

36

使用JavaScriptSerializer处理动态对象。

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];

//test Result = "some data"

你将如何在类的层次结构中找到键? - FrenkyB

20

Newtonsoft比JavaScript序列化器更快。... 这个需要依赖流行且比默认序列化器更好的Newtonsoft NuGet包。

一行代码解决方案。

var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);

20
你可以通过使用Newtonsoft.Json库轻松实现你的需求。我以下面的一个示例进行了说明,请看一下。
收到对象类型的类:
public class User
{
    public int ID { get; set; }
    public string Name { get; set; }

}

代码:

static void Main(string[] args)
{

      string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";

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

      Console.ReadKey();
}

这是一种非常简单的解析JSON的方法。


16
这是一个简单的类,我从各种帖子中拼凑而成...它已经测试了大约15分钟,但似乎对我的目的起作用。它使用JavascriptSerializer来完成工作,可以在您的应用程序中使用详细信息在此帖子中引用。
以下代码可以在LinqPad中运行以进行测试:
  • 右键单击LinqPad中的脚本选项卡,选择“查询属性”
  • 在“附加引用”中引用“System.Web.Extensions.dll”
  • 添加“System.Web.Script.Serialization”的“其他命名空间导入”。
希望能对您有所帮助!
void Main()
{
  string json = @"
  {
    'glossary': 
    {
      'title': 'example glossary',
        'GlossDiv': 
        {
          'title': 'S',
          'GlossList': 
          {
            'GlossEntry': 
            {
              'ID': 'SGML',
              'ItemNumber': 2,          
              'SortAs': 'SGML',
              'GlossTerm': 'Standard Generalized Markup Language',
              'Acronym': 'SGML',
              'Abbrev': 'ISO 8879:1986',
              'GlossDef': 
              {
                'para': 'A meta-markup language, used to create markup languages such as DocBook.',
                'GlossSeeAlso': ['GML', 'XML']
              },
              'GlossSee': 'markup'
            }
          }
        }
    }
  }

  ";

  var d = new JsonDeserializer(json);
  d.GetString("glossary.title").Dump();
  d.GetString("glossary.GlossDiv.title").Dump();  
  d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();  
  d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();    
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();   
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump(); 
  d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();   
}


// Define other methods and classes here

public class JsonDeserializer
{
  private IDictionary<string, object> jsonData { get; set; }

  public JsonDeserializer(string json)
  {
    var json_serializer = new JavaScriptSerializer();

    jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
  }

  public string GetString(string path)
  {
    return (string) GetObject(path);
  }

  public int? GetInt(string path)
  {
    int? result = null;

    object o = GetObject(path);
    if (o == null)
    {
      return result;
    }

    if (o is string)
    {
      result = Int32.Parse((string)o);
    }
    else
    {
      result = (Int32) o;
    }

    return result;
  }

  public object GetObject(string path)
  {
    object result = null;

    var curr = jsonData;
    var paths = path.Split('.');
    var pathCount = paths.Count();

    try
    {
      for (int i = 0; i < pathCount; i++)
      {
        var key = paths[i];
        if (i == (pathCount - 1))
        {
          result = curr[key];
        }
        else
        {
          curr = (IDictionary<string, object>)curr[key];
        }
      }
    }
    catch
    {
      // Probably means an invalid path (ie object doesn't exist)
    }

    return result;
  }
}

15

正如 tripletdad99 所说的:

var result = JsonConvert.DeserializeObject<T>(json);

但如果你不想创建额外的对象,你可以使用 字典(Dictionary) 来代替

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);

当您将参数传递给Url.Action(action,controller,result)时,这非常有用。 - Lapenkov Vladimir

10

将以下 ddl 添加到您的项目引用中:System.Web.Extensions.dll

使用以下命名空间:using System.Web.Script.Serialization;

public class IdName
{
    public int Id { get; set; }
    public string Name { get; set; }
}


   string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
   var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);

   string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
   var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);

8

另一个快速简单的半自动方法是:

  1. 复制要解析的 JSON 内容并粘贴到https://app.quicktype.io/ 。在下拉菜单中选择C#语言。
  2. 将左上角的名称更改为您的类名,默认为“Welcome”。
  3. 在 Visual Studio 中,进入“网站”->“管理包”,使用 NuGet 添加 Newtonsoft 的 Json.Net。
  4. app.quicktype.io 基于 Newtonsoft 生成了序列化方法。或者,您现在可以使用以下代码:

    WebClient client = new WebClient();

    string myJSON = client.DownloadString("https://URL_FOR_JSON.com/JSON_STUFF");

    var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject(myJSON);


链接已失效。 - Myles J
感谢Myles J,我已经更新到一个新的网站,看起来运行良好。 - Jason Hitchings
https://app.quicktype.io/ 是一个很好的参考网站。这里还有另一个类似的网站 - https://jsonformatter.org/json-to-csharp - Gangula

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接