【问题标题】:Create list of objects from Json object with objects in xamarin for Android使用 Xamarin for Android 中的对象从 Json 对象创建对象列表
【发布时间】:2016-01-05 01:41:18
【问题描述】:

我正在使用 JSON.net,我正在尝试从 JSON 中获取 Expense 对象列表,如下所示:

{"ApplicationUser": null, "Currency": 1, "Description": "Moj pierwszy portfel", "Expenses": [{"Date": "2015-10-01T00:00:00", "Description": "Opis", "ExpenseType": {"Id": 1, "IsExpense": true, "Name": "Jedzenie"}, "ExpenseTypeId": 1, "Id": 1, "Name": "Biedronka", "Value": 40.00, "WalletId": 1}], "Id": 1, "Name": "Moj portfel", "Saldo": 100.12, "UserId": "f9b94a9a-44b3-4987-8711-6c1b73a5cb0e"}

api 网址:http://homecalc.azurewebsites.net/api/wallets/2

我有从 JSON2C# 构建的课程

它们看起来像这样

public class ExpenseType
{
    public int Id { get; set; }
    public bool IsExpense { get; set; }
    public string Name { get; set; }
}

public class Expense
{
    public ExpenseType ExpenseType { get; set; }
    public int Id { get; set; }
    public string Name { get; set; }
    public double Value { get; set; }
    public string Description { get; set; }
    public string Date { get; set; }
    public int ExpenseTypeId { get; set; }
    public int WalletId { get; set; }
}

public class RootObject
{
    public List<Expense> Expenses { get; set; }
    public int Id { get; set; }
    public string Name { get; set; }
    public string UserId { get; set; }
    public double Saldo { get; set; }
    public int Currency { get; set; }
    public string Description { get; set; }
    public object ApplicationUser { get; set; }
}

获取 JSONValue 声明如下:

private async Task<JsonValue> GetApi(string url)
    {
        HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(new Uri(url));
        request.ContentType = "application/json";
        request.Method = "GET";

        using (WebResponse response = await request.GetResponseAsync())
        {
            using (Stream stream = response.GetResponseStream())
            {
                JsonValue jsconDoc = await Task.Run(() => JsonObject.Load(stream));
                Console.Out.WriteLine("Response {0}", stream);

                return jsconDoc;
            }
        }
    }

我试过反序列化

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

并将其解析为 jsonObject 或 jsonArray

var obj = JsonObject.Parse(json);

但它总是以破坏应用程序而告终。 我还尝试使用json["Expenses"] 仅获取一系列费用,但是当有两项费用时,它会全部作为一项费用返回。有人可以解释如何从中获取费用对象列表吗?

我已将代码更改为如下所示:

 private async Task<string> GetApi(string url)
    {
        HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(new Uri(url));
        request.ContentType = "application/json";
        request.Method = "GET";

        using (WebResponse response = await request.GetResponseAsync())
        {
            using (Stream stream = response.GetResponseStream())
            {
                JsonValue jsconDoc = await Task.Run(() => JsonObject.Load(stream));
                Console.Out.WriteLine("Response {0}", stream);
                StreamReader read = new StreamReader(stream,Encoding.UTF8);

                string json = read.ReadToEnd();

                return json;
            }
        }
    }

private void ParseAndDisplay(string json)
    {
        //TextView WalletName = FindViewById<TextView>(Resource.Id.PortfelName);
        //WalletName.Text = json["Name"];
        //Console.WriteLine("Exp {0}",json["Expenses"]);
        //JsonArray jsonnArray = new JsonArray(json["Expenses"]);
        try
        {
            var result = JsonConvert.DeserializeObject<RootObject>(json);
            Console.WriteLine("Nazwa: {0}",result.Name);
        }
        catch (Exception e)
        {
            Console.WriteLine("Błąd: {0}",e);
        }

    }

当我尝试运行此方法时,它返回异常:

System.NullReferenceException: Object reference not set to an instance of an object

【问题讨论】:

  • 您的 API url 在我调用它时会引发错误。而且您发布的示例 json 中只有一笔费用。最后,“破申请”是什么意思?你有例外吗?这是什么?
  • 另外,您的示例 json 是单个对象,而不是数组,因此无法反序列化为 List
  • 看起来反序列化已接近尾声,但不清楚输入 json 是如何定义或填充的。它应该只是响应的字符串内容。
  • NullReferenceException 是在哪一行触发的?可能是 ParseAndDisplay 中的 JsonConvert.DeserializeObject 调用。如果是这样,可能是因为 GetApi 中的流已经结束,因为上面的行加载了 JsonObject。 IE。当 string json = read.ReadToEnd() 被执行时,json 保持为空。
  • 谢谢马克这是问题所在,在所有这些更改之后代码运行完美!谢谢大家!

标签: android json xamarin json.net deserialization


【解决方案1】:

不用太深入细节,使用 System.Net.Http.HttpClient 和像 Newtonsoft.Json 或 ServiceStack.Text 这样的 JSON 库,这将相当简单。使用 Newtonsoft.Json,您可能正在寻找这样的东西:

using System.Net.Http;
using Newtonsoft.Json;

...

using (var client = new HttpClient())
{
    ...

    var response = await client.GetAsync(url);
    response.EnsureSuccessStatusCode();

    string json = await response.Content.ReadAsStringAsync();
    var result = JsonConvert.DeserializeObject<RootObject>(json);

    ...
}

【讨论】:

  • 我无法使用 response.Content.ReadAsStringAsync,响应似乎没有 Content 方法
  • 我的例子是使用 System.Net.Http.HttpClient。为了完整起见,我将发布更多代码。我认为您应该能够使用 HttpWebRequest 让您的代码也可以工作,因为您正在使用从流中加载的纯字符串。您可能只需要注释掉StreamReader read = ... 之前的两行。
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 2015-05-07
  • 2018-05-25
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
相关资源
最近更新 更多