【问题标题】:Deserializing the JSON in the C# console application在 C# 控制台应用程序中反序列化 JSON
【发布时间】:2017-10-18 17:00:52
【问题描述】:

我想反序列化来自 C# 控制台应用程序中 Web 服务调用的 JSON 响应。JSON 看起来像

{
"il_response": {
    "custom_forms": [
        {
            "id": 84,
            "name": "Request",
            "note": "Notes",
            "fields": [
                {
                    "label": "Prj",
                    "value": [
                        "ABC",
                        "DEF"
                    ],
                    "name": "Projects"
                },
                {
                    "label": "Submit Date",
                    "value": "October 16, 2017 ",
                    "name": "Submit Date"
                },
                {
                    "label": "Name",
                    "value": "Dhana",
                    "name": "Name"
                }
            ]
        }
    ],
    "il_metadata": {}
}
}

我在名为 iDTO.cs 的单独类文件中拥有所有 POCO

public class iResponse
{
    public iResponse(){   }
    public List<iDTO> data { get; set; }
}

public class iDTO
{
    public iDTO() { }
}

public class Field
{
    public string label { get; set; }
    public object value { get; set; }
    public string name { get; set; }
}

public class C_Form
{
    public int id { get; set; }
    public string name { get; set; }
    public string note { get; set; }
    public List<Field> fields { get; set; }
}

public class IlMetadata
{
}

public class IlResponse
{
    public List<C_Form> c_forms { get; set; }
    public IlMetadata il_metadata { get; set; }
}

public class RootObject
{
    public IlResponse il_response { get; set; }
}

下面是我调用服务的代码

public class APICall
{
    string BaseUR = ConfigurationManager.AppSettings["BaseURL"];
    string accessToken = ConfigurationManager.AppSettings["AccessToken"];

    public async Task<IHttpActionResult> Get()
    {
        using (var client = new HttpClient())
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
            Uri uri = new Uri(BaseURL);
            client.BaseAddress = uri;
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            var response = await client.GetAsync(uri);
            var datafile = await response.Content.ReadAsStringAsync();
            var  returnDataObj = JsonConvert.DeserializeObject<iLabDTO.RootObject>(datafile);
        }
    }
}

这里我不确定如何从 JSON 中的字段中获取每个名称和值属性。我看到我们可以将 for each 与字段一起使用,但不确定如何同时获取值和名称

【问题讨论】:

  • 你在 returnDataObj 中获取数据吗?
  • 我无法调试,因为我不确定要返回什么

标签: c# json web-services json-deserialization


【解决方案1】:

在修改卢克提到的问题后,这使用您的 json 有效。但是我使用的是iDTO.RootObject,而你的 api 说的是iLabDTO.RootObject

string datafile = File.ReadAllText(@"json.txt");
var returnDataObj = JsonConvert.DeserializeObject<iDTO.RootObject>(datafile);
foreach (var form in returnDataObj.il_response.c_forms)
{
    Console.WriteLine(form.id);
    Console.WriteLine(form.name);
    Console.WriteLine(form.note);
    foreach(var field in form.fields)
    {
        Console.WriteLine(field.name);
        Console.WriteLine(field.label);
        Console.WriteLine(field.value);
    }
}

【讨论】:

    【解决方案2】:

    IlResponse 对象上的 c_forms 属性需要与 JSON 对象上的相应属性同名:

    {
    "il_response": {
        "custom_forms": [
    

    从上面的代码 sn-p 中,您应该将 c_forms 属性重命名为 custom_forms

    这是我看到的唯一出现的该问题,但您需要确保所有 C# 属性名称与正在接收的 JSON 对象名称相匹配。然后,这将为您提供属性名称,就像它在您的 C# 模型对象中一样,以及将在运行时保存在命名属性中的值。

    【讨论】:

    • 谢谢卢克,是的,这是一个错字。但我不确定如何获取应用程序中每个属性的值。你能举一个例子吗
    • 根据 OP 发布的代码,他使用的是 iLabDTO 而不是 iDTO
    • @user4912134 一旦这行代码执行:var returnDataObj = JsonConvert.DeserializeObject&lt;iLabDTO.RootObject&gt;(datafile); 您的 JSON 对象将转换为 C# 对象。要访问 C# 对象中的属性,它看起来类似于:returnDataObj.il_response.c_forms.First().id .First() 函数是一个 linq 函数,它只是从 List&lt;C_Form&gt; 对象中提取第一项。
    • 非常感谢,但如果我在 returnDataObj.ilab_response.custom_forms.fields.First().name; 之类的字段中访问名称,则会引发类似 'List&lt;iLabDTO.C_Form&gt;' does not contain a definition for 'fields' and no extension method 'fields' accepting a first argument of type 'List&lt;iLabDTO.C_Form&gt;' could be found (are you missing a using directive or an assembly reference?) 的错误,但是 C_Fo​​rms 在类中有字段
    • @user4912134 正如您问题的另一个答案所述,您可能在某处使用了错误的对象。查看 iDTO.RootObjectiLabDTO 对象。
    猜你喜欢
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多