将Json字符串转换为C#对象列表

51

我希望能够将一个json字符串转换为对象列表。请帮我。如果使用NewtonJson进行转换会更有帮助。

我已经尝试过,但并没有成功。我只想获取MatrixModel中提到的值,而不是所有的值。

这是一个对象。

public class MatrixModel
{
    public string S1 { get; set; }
    public string S2 { get; set; }
    public string S3 { get; set; }
    public string S4 { get; set; }
    public string S5 { get; set; }
    public string S6 { get; set; }
    public string S7 { get; set; }
    public string S8 { get; set; }
    public string S9 { get; set; }
    public string S10 { get; set; }
    public int ScoreIfNoMatch { get; set; }
}

这是JSON字符串

    "[
      {
        "Question": {
          "QuestionId": 49,
          "QuestionText": "Whats your name?",
          "TypeId": 1,
          "TypeName": "MCQ",
          "Model": {
            "options": [
              {
                "text": "Rahul",
                "selectedMarks": "0"
              },
              {
                "text": "Pratik",
                "selectedMarks": "9"
              },
              {
                "text": "Rohit",
                "selectedMarks": "0"
              }
            ],
            "maxOptions": 10,
            "minOptions": 0,
            "isAnswerRequired": true,
            "selectedOption": "1",
            "answerText": "",
            "isRangeType": false,
            "from": "",
            "to": "",
            "mins": "02",
            "secs": "04"
          }
        },
        "CheckType": "",
        "S1": "",
        "S2": "",
        "S3": "",
        "S4": "",
        "S5": "",
        "S6": "",
        "S7": "",
        "S8": "",
        "S9": "Pratik",
        "S10": "",
        "ScoreIfNoMatch": "2"
      },
      {
        "Question": {
          "QuestionId": 51,
          "QuestionText": "Are you smart?",
          "TypeId": 3,
          "TypeName": "True-False",
          "Model": {
            "options": [
              {
                "text": "True",
                "selectedMarks": "7"
              },
              {
                "text": "False",
                "selectedMarks": "0"
              }
            ],
            "maxOptions": 10,
            "minOptions": 0,
            "isAnswerRequired": false,
            "selectedOption": "3",
            "answerText": "",
            "isRangeType": false,
            "from": "",
            "to": "",
            "mins": "01",
            "secs": "04"
          }
        },
        "CheckType": "",
        "S1": "",
        "S2": "",
        "S3": "",
        "S4": "",
        "S5": "",
        "S6": "",
        "S7": "True",
        "S8": "",
        "S9": "",
        "S10": "",
        "ScoreIfNoMatch": "2"
      }
    ]"

1
你如何将字符串反序列化为对象? - SpiderCode
可能是将JSON字符串转换为C#对象的重复问题。 - Liam
7个回答

117

你可以使用json2csharp.com将JSON转换为对象模型。

  • 进入json2csharp.com
  • 在框中粘贴你的JSON。
  • 点击生成。
  • 你将得到一个用于你的对象模型的C#代码。
  • 使用NewtonJsonvar model = JsonConvert.DeserializeObject<RootObject>(json);进行反序列化。

在这里,它会生成类似于以下内容:

public class MatrixModel
{
    public class Option
    {
        public string text { get; set; }
        public string selectedMarks { get; set; }
    }

    public class Model
    {
        public List<Option> options { get; set; }
        public int maxOptions { get; set; }
        public int minOptions { get; set; }
        public bool isAnswerRequired { get; set; }
        public string selectedOption { get; set; }
        public string answerText { get; set; }
        public bool isRangeType { get; set; }
        public string from { get; set; }
        public string to { get; set; }
        public string mins { get; set; }
        public string secs { get; set; }
    }

    public class Question
    {
        public int QuestionId { get; set; }
        public string QuestionText { get; set; }
        public int TypeId { get; set; }
        public string TypeName { get; set; }
        public Model Model { get; set; }
    }

    public class RootObject
    {
        public Question Question { get; set; }
        public string CheckType { get; set; }
        public string S1 { get; set; }
        public string S2 { get; set; }
        public string S3 { get; set; }
        public string S4 { get; set; }
        public string S5 { get; set; }
        public string S6 { get; set; }
        public string S7 { get; set; }
        public string S8 { get; set; }
        public string S9 { get; set; }
        public string S10 { get; set; }
        public string ScoreIfNoMatch { get; set; }
    }
}

然后你可以进行反序列化操作:

var model = JsonConvert.DeserializeObject<List<MatrixModel.RootObject>>(json);

真是太棒了。感谢您的帮助。 - Junaid
+1 给这个网站,非常有帮助!有件事,我得到了一个错误,但我无法弄清楚问题出在哪里:Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type System.Collections.Generic.List 1[Library.BL.Unidade+RootObject] because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer. CODE - Ariel
4
很可能你的 JSON 是一个数组,而不是单个对象。尝试使用 JsonConvert.DeserializeObject<List<RootObject>>(json); - L.B
非常棒 很棒的网站 - Nithin Veer Reddy Kankanti
我该如何访问“selectedMarks”的值? - Rapsoulis
链接已损坏 :( - lachs

7
public static class Helper
{
    public static string AsJsonList<T>(List<T> tt)
    {
        return new JavaScriptSerializer().Serialize(tt);
    }
    public static string AsJson<T>(T t)
    {
        return new JavaScriptSerializer().Serialize(t);
    }
    public static List<T> AsObjectList<T>(string tt)
    {
        return new JavaScriptSerializer().Deserialize<List<T>>(tt);
    }
    public static T AsObject<T>(string t)
    {
        return new JavaScriptSerializer().Deserialize<T>(t);
    }
}

3

C#中使用动态变量是最简单的。

Newtonsoft.Json.Linq有一个JValue类可供使用。以下是一个示例代码,可以从你拥有的JSON字符串中显示问题ID和文本。

        string jsonString = "[{\"Question\":{\"QuestionId\":49,\"QuestionText\":\"Whats your name?\",\"TypeId\":1,\"TypeName\":\"MCQ\",\"Model\":{\"options\":[{\"text\":\"Rahul\",\"selectedMarks\":\"0\"},{\"text\":\"Pratik\",\"selectedMarks\":\"9\"},{\"text\":\"Rohit\",\"selectedMarks\":\"0\"}],\"maxOptions\":10,\"minOptions\":0,\"isAnswerRequired\":true,\"selectedOption\":\"1\",\"answerText\":\"\",\"isRangeType\":false,\"from\":\"\",\"to\":\"\",\"mins\":\"02\",\"secs\":\"04\"}},\"CheckType\":\"\",\"S1\":\"\",\"S2\":\"\",\"S3\":\"\",\"S4\":\"\",\"S5\":\"\",\"S6\":\"\",\"S7\":\"\",\"S8\":\"\",\"S9\":\"Pratik\",\"S10\":\"\",\"ScoreIfNoMatch\":\"2\"},{\"Question\":{\"QuestionId\":51,\"QuestionText\":\"Are you smart?\",\"TypeId\":3,\"TypeName\":\"True-False\",\"Model\":{\"options\":[{\"text\":\"True\",\"selectedMarks\":\"7\"},{\"text\":\"False\",\"selectedMarks\":\"0\"}],\"maxOptions\":10,\"minOptions\":0,\"isAnswerRequired\":false,\"selectedOption\":\"3\",\"answerText\":\"\",\"isRangeType\":false,\"from\":\"\",\"to\":\"\",\"mins\":\"01\",\"secs\":\"04\"}},\"CheckType\":\"\",\"S1\":\"\",\"S2\":\"\",\"S3\":\"\",\"S4\":\"\",\"S5\":\"\",\"S6\":\"\",\"S7\":\"True\",\"S8\":\"\",\"S9\":\"\",\"S10\":\"\",\"ScoreIfNoMatch\":\"2\"}]";
        dynamic myObject = JValue.Parse(jsonString);
        foreach (dynamic questions in myObject)
        {
            Console.WriteLine(questions.Question.QuestionId + "." + questions.Question.QuestionText.ToString());
        }
        Console.Read();

代码的输出 => 代码的输出


2
如果没有明确需要一个类(模型),你也可以使用动态的方式。
List<dynamic> models = JsonConvert.DeserializeObject<List<dynamic>>(jsonString);

然后使用点号来访问您需要的任何字段

models[0].MyField

1
请确保所有属性都有getter和setter。如果任何属性只有getter,则会导致将List还原为原始数据,因为JSON字符串已被键入。
请参考以下代码片段: 模型:
 public class Person
{
    public int ID { get; set; }
    // following 2 lines are cause of error
    //public string Name { get { return string.Format("{0} {1}", First, Last); } }
    //public string Country { get { return Countries[CountryID]; } }
    public int CountryID { get; set; }
    public bool Active { get; set; }
    public string First { get; set; }
    public string Last { get; set; }
    public DateTime Hired { get; set; }
}
public class ModelObj
    {
        public string Str { get; set; }
        public List<Person> Persons { get; set; }
    }

控制器:

 [HttpPost]
    public ActionResult Index(FormCollection collection)
    {
        var data = new ModelObj();
        data.Str = (string)collection.GetValue("Str").ConvertTo(typeof(string));
        var personsString = (string)collection.GetValue("Persons").ConvertTo(typeof(string));
        using (var textReader = new StringReader(personsString))
        {
            using (var reader = new JsonTextReader(textReader))
            {
                data.Persons = new JsonSerializer().Deserialize(reader, typeof(List<Person>)) as List<Person>; 
            }
        }

        return View(data);
    }

0

尝试更改ScoreIfNoMatch的类型,像这样:

   public class MatrixModel
        {
            public string S1 { get; set; }
            public string S2 { get; set; }
            public string S3 { get; set; }
            public string S4 { get; set; }
            public string S5 { get; set; }
            public string S6 { get; set; }
            public string S7 { get; set; }
            public string S8 { get; set; }
            public string S9 { get; set; }
            public string S10 { get; set; }
            // the type should be string
            public string ScoreIfNoMatch { get; set; }
        }

0

class 定义中的变量/参数需要 { get; set; }。 我之前像变量声明一样使用它(这很愚蠢,因为它在其他情况下可以工作),但没有加上


{ get; set; }

因此,无论我从JavaScript发送什么,都没有在Action方法中接收到。它总是获取空模型或null。
引用:一旦添加了{get;set;},它就像魔术般地工作。 我希望它能帮助那些来自VB6编程行的人。

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