【问题标题】:Returning Array of response from Web API C#从 Web API C# 返回响应数组
【发布时间】:2017-10-19 17:41:52
【问题描述】:

我正在尝试创建一个调用其他服务并返回响应数组的 Web API。被调用的服务返回响应。我能够从被调用的服务中获取单个项目。但不确定如何构建项目数组并作为我正在创建的 API 的响应返回。

从服务返回的 JSON 看起来像

{
"cr_response": {
    "details": [{
        "name": "Req",
        "fields": [{
                "value": "Prj0\r\nPrj1",
                "name": "Project"
            },
            {
                "value": "October 13, 2017 14:18",
                "name": "Submitted"
            },
            {
                "value": "John",
                "name": "Rec Name"
            }
        ]
    }],
    "cr_metadata": {}
}
}

POCO 类看起来像

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

public class Detail
{
    public string name { get; set; }
    public List<Field> fields { get; set; }
}

public class CrMetadata
{
}

public class CrResponse
{
    public List<Detail> details { get; set; }
    public CrMetadata cr_metadata { get; set; }
}

 public class RootObject
 {
      public CrResponse cr_response { get; set; }
 }

以下是调用服务并从服务中检索响应的代码

var response = await iLab_client.GetAsync(uri);
var datafile = await response.Content.ReadAsStringAsync();
var returnDataObj = JsonConvert.DeserializeObject<DTO.RootObject>(datafile);

foreach (var form in returnDataObj.cr_response.details)
{
    name_response = form.name;
    return Ok(name_response);
}

在这里,我可以从详细信息中访问名称,但不确定如何从字段中访问所有名称和值并将其构造在数组中。并将其作为 JSON 响应发送。 我试过了

            foreach (var form in returnDataObj.cr_response.details)
            {
                var id_response = form.fields;
                return Ok(id_response);
            }

但它会抛出类似

的错误
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content 
type 'application/xml; charset=utf-8'.
</ExceptionMessage>

System.InvalidOperationException

【问题讨论】:

  • 我注意到错误消息特别提到了内容类型application/xml。有效的 XML 要求有一个根节点。返回的对象可能不能是集合。如果您可以将客户端更改为请求 JSON,则可能会解决问题。否则,您最好返回一个将数组作为其属性之一的对象,而不是直接返回数组。
  • @StriplingWarrior 你要求改变而不是 HttpClient 吗?
  • 没有。您的代码既使用 Web 服务 (ilab_client.GetAsync(...)) 也 客户端使用 (return Ok(...);)。使用您的 Web API 端点的客户端正在发送 HTTP 请求。 Web API 正在查看请求并认为它需要将响应序列化为 XML 而不是 JSON。这可能是由于 Web 请求中的标头(或没有标头)所致。或者可能是由于the way your Web API application is configured。或者这两者的某种组合。

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


【解决方案1】:

要从 Web API 返回数组,您需要填充数组并将其返回到 foreach 循环之外:

var list = new List<string>();
foreach (...){
    var name = ... 
    list.Add(name);
}
 return Ok(list.ToArray()); // or just   return Ok(list); 

这是将JSON反序列化为POCO并获取名称列表的方法:

[TestMethod]
public void TestJsonToPocoAndGetNames()
{
    const string Json = @"
        {
        ""cr_response"": {
            ""details"": [{
                ""name"": ""Req"",
                ""fields"": [{
                        ""value"": ""Prj0\r\nPrj1"",
                        ""name"": ""Project""
                    },
                    {
                        ""value"": ""October 13, 2017 14:18"",
                        ""name"": ""Submitted""
                    },
                    {
                        ""value"": ""John"",
                        ""name"": ""Rec Name""
                    }
                ]
            }],
            ""cr_metadata"": {}
        }
    }
    ";

    var settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
    };
    var response = JsonConvert.DeserializeObject<RootJsonObject>(Json, settings);

    var names = new List<string>();
    foreach (var detail in response.CrResponse.Details)
    {
        names.Add(detail.Name);

        foreach (var field in detail.Fields)
        {
            names.Add(field.Name);
        }
    }

    Assert.AreEqual(
        "Req, Project, Submitted, Rec Name",
        string.Join(", ", names.ToArray()));
}

POCO 课程:

public class RootJsonObject
{
    [JsonProperty("cr_response")]
    public CrResponse CrResponse { get; set; }
}

public class CrResponse
{
    [JsonProperty("cr_metadata")]
    public CrMetadata CrMetadata { get; set; }

    [JsonProperty("details")]
    public Detail[] Details { get; set; }
}

public class CrMetadata
{
}

public class Detail
{
    [JsonProperty("fields")]
    public Field[] Fields { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

public class Field
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("value")]
    public string Value { get; set; }
}

【讨论】:

  • 我们在详细信息和字段中都有名称。我想从字段中获取名称和值。
  • 要访问 JSON 数据(不将它们反序列化为 POCO 类),您可能需要检查此stackoverflow.com/questions/6620165/how-can-i-parse-json-with-c/…
  • 使用 POCO 无法访问字段下的名称和值?
  • 我试过 form.fields.Children() it throws error like 不包含“儿童”的定义`
  • 我也试过names.Add(form.fields.name),即使那不起作用
猜你喜欢
  • 2020-02-05
  • 2019-03-16
  • 2019-02-13
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多