【问题标题】:C# adding JSON string to a ListC# 将 JSON 字符串添加到列表中
【发布时间】:2013-11-14 00:42:54
【问题描述】:

所以在我的应用程序中,我必须得到一个 JSON 字符串。 它可以是一个城市或城市列表。

在 City 类中,我有这个:

public class City
{
    public string id { get; set; }
    public string country { get; set; }
    public string region { get; set; }
    public string city { get; set; }
    public string latitude { get; set; }
    public string longitude { get; set; }
    public string comment { get; set; }
    public bool wasThereAnError { get; set; }

    public class CityResponse
    {
        public string status { get; set; }
        public string message { get; set; }
        //public City result { get; set; }
        public List<City> result { get; set; }
    }

所以它使用 List 结果来存储数据。 当我得到一个 JSON 数组时,这很好用,它可以轻松地存储它们。 但是,如果我只查询 1 个城市,我会得到一个关于它需要数组的异常。 这是我的通话代码:

    async private Task<City.CityResponse> GetCityInformation(string url)
    {
        var client = new HttpClient();
        var response = await client.GetAsync(new Uri(url));
        string result = await response.Content.ReadAsStringAsync();
        var cityRoot = JsonConvert.DeserializeObject<City.CityResponse>(result);

        return cityRoot;
    }

我也可以在列表中存储 1 个城市吗?还是我需要开设一个单独的城市课程,或者我该怎么做?谢谢

【问题讨论】:

  • 见这里:stackoverflow.com/questions/11126242/…,接受后的下一个答案都会给你解决方案
  • 我不确定...如果您在 CityResponse 中添加一个额外的属性 City Result(不同的拼写),它会填充一个值吗?这样你就可以处理setter了
  • @AndyOHart 是否可以覆盖/扩展默认解串器?虽然我更愿意强制数据源发送正确的类型...
  • 对于单个城市的情况,您可以将城市格式化为一个包含一个元素的数组吗?看起来远程服务器的合同有点松散。
  • @AndyOHart 他的意思是为您提供 json 的服务器发送单个值而不是具有 1 个值的数组,因此您应该对该服务器执行一些操作:)

标签: c# json object serialization set


【解决方案1】:

这是基于 Jim 的回答的一个小解决方案。

class CityResponse
{
    public string status { get; set; }

    public object result
    {
        get { return null; }
        set 
        {
            cities = new List<City>();

            if (value.GetType() == typeof(JArray))
            {
                cities = ((JArray)value).ToObject<List<City>>();
                foreach(var city in cities) city.ParentResponse = this; // Edit
                return;
            }

            if (value.GetType() != typeof(JObject)) 
                return;

            cities.Add(((JObject)value).ToObject<City>());
            foreach(var city in cities) city.ParentResponse = this; // Edit
        }
    }

    public string message { get; set; }

    public List<City> cities { get; internal set; }
}

希望对你有帮助!

PS:我不知道提供 JSON 数据的系统是不是你创建的,但是有一个类型不一致的成员是不好的设计。

-- 编辑--

在回复对此答案的评论时,询问如何从 City 对象访问 CityResponse,我将这样做:

我将向 City 类添加一个新属性,用于保存父级 CityResponse

public class City
{
    public string id { get; set; }

    ...

    public CityResponse ParentResponse { get; set;}
}

然后对 setter 进行一些小的更改,如上面答案的原始部分所示。

【讨论】:

  • @AndyOHart 当 JSON 反序列化器尝试设置 result 属性时,cities 属性在内部设置(您会注意到该属性的设置器已明确定义)。它实际上不会出现在您收到的 JSON 对象中。
  • @AndyOHart 我将重新实现您的 ToString() 覆盖,然后使用 forforeach 循环遍历结果 (cities),同时将它们打印出来。
  • @AndyOHart 您可以从GetCityInformation() 调用的结果中访问它。
  • @AndyOHart 否。为此,您必须在新属性中添加对父类 CityResponse 的引用,最好是在 result 设置器中。
  • @AndyOHart 我编辑了最初的答案以包含更多信息。但是我应该注意,出于这样的目的从另一个 City 对象访问 City 对象的其余部分可能是不好的做法。
【解决方案2】:

代替:

public class CityResponse
    {
        public string status { get; set; }
        public string message { get; set; }
        public List<City> result { get; set; }
    }

尝试:

public class CityResponse
    {
        public string status { get; set; }
        public string message { get; set; }
        public string result { 
            get{ return null; }
            set{
                    // if 1st character is "[" then it's an array of City, otherwise a City object 
                    //depending on the above parse this string (which is like "{prop1: qqq, prop2: www}" 
                    // or like "[{prop1: qqq, prop2: www}, {prop1: eee, prop2: eee}]")
                    // by the existing serializer or other one 
                    // into City or array of cities
                    // if City, then convert in to array of cities
                    // and save result into realResult
            }
        }
        public List<City> realResult { get; set; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2011-09-10
    • 2018-08-12
    • 2014-07-05
    相关资源
    最近更新 更多