我是C#和Xamarin的初学者。我试图用newtonsoft反序列化json数组? 这是我的json文件:
{
"next": {
"$ref": "http://192.168.0.100:8080/ords/hr/employees/?page=1"
},
"items": [
{
"empno": 7369,
"ename": "SMITH",
"job": "CLERK",
"mgr": 7902,
"sal": 800,
"deptno": 20
},
{
"empno": 7934,
"ename": "MILLER",
"job": "CLERK",
"mgr": 7782,
"sal": 1300,
"deptno": 10
}
]
}

她是我的模特课:
public class RootObject
{
[JsonProperty("items")]
public Item[] Items { get; set; }
[JsonProperty("next")]
public Next Next { get; set; }
}
public class Next
{
[JsonProperty("$ref")]
public string Ref { get; set; }
}
public class Item
{
[JsonProperty("deptno")]
public long Deptno { get; set; }
[JsonProperty("empno")]
public long Empno { get; set; }
[JsonProperty("ename")]
public string Ename { get; set; }
[JsonProperty("job")]
public string Job { get; set; }
[JsonProperty("mgr")]
public long Mgr { get; set; }
[JsonProperty("sal")]
public long Sal { get; set; }
}

当我尝试反序列化为List时,它会在此行引发异常:
var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
&#13;
错误是:
附加信息:无法将当前JSON对象(例如{&#34; name&#34;:&#34; value&#34;})反序列化为类型System.Collections.Generic.List`1 [ System.Object的]&#39;因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。
要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如,不是像整数这样的基本类型,而不是可以从JSON对象反序列化的集合类型,如数组或List)。 JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化。
这段代码绝对是Json,但我现在不会检索数据并填充该类:
public class ApiServices {
public async Task<RootObject> GetRootObject()
{
var client = new HttpClient();
var url = string.Format("http://mysite/ords/hr/employees");
var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
dynamic jsonDe = JsonConvert.DeserializeObject<RootObject>(json);
return jsonDe;
}
&#13;
我已经在MainViewModel中创建了一些代码,但我不知道如何检索数据并插入类Item:
public class MainViewModel
{
#region Properties
public ObservableCollection<RootItemViewModel> RootObjects { get; set; }
private ApiServices apiServices;
#endregion
#region Constructors
public MainViewModel()
{
//Create observable collections
RootObjects = new ObservableCollection<RootItemViewModel>();
//Instance services
apiServices = new ApiServices();
//Load Data
LoadData();
}
#endregion
#region Methods
private async void LoadData()
{
var emps = new RootObject();
emps = await apiServices.GetRootObject();
RootObjects.Clear();
foreach (var item in RootObjects)
{
RootObjects.Add(new RootItemViewModel
{
});
}
}
#endregion
}
}
&#13;
RootItemViewModel类:
public class RootItemViewModel : RootObject
{
}
&#13;
答案 0 :(得分:0)
对于这个JSON:
{
"next": {
"$ref": "http://192.168.0.100:8080/ords/hr/employees/?page=1"
},
"items": [
{
"empno": 7369,
"ename": "SMITH",
"job": "CLERK",
"mgr": 7902,
"sal": 800,
"deptno": 20
},
{
"empno": 7934,
"ename": "MILLER",
"job": "CLERK",
"mgr": 7782,
"sal": 1300,
"deptno": 10
}
]
}
使用此类:
internal class SomeObject{ //in C# you can even NOT to define internal as well :)
public class next{
public string ref {get; set;} //var do not use $, you need to change the JSON code or you nned to make a custom reader for that.
}
public List<Item> items {get; set;}
public class Item{
public string empno {get; set;}
public string ename {get; set;}
public string job {get; set;}
public string mgr {get; set;}
public string sal {get; set;}
public string deptno {get; set;}
}
}
要将这些JSON反序列化为类,请使用以下代码:
var obj = JSONConvert.DeserializeObject<SomeObject>(json); //json is a string of your JSON
//Now you can access the data like
listView.ItemsSource = obj.Items; //for mobile listview
你不能把List放到因为JSON对象不是纯List Of对象,它是下一个对象和items对象之间的组合对象。因此,在将JSON放入列表之前,您需要先创建一个类。
答案 1 :(得分:0)
http://json2csharp.com/总是很有用,(快速获取课程&#39;骨架&#39;)
喜欢&#39; Hery先生&#39;写道你可能不得不做自定义阅读器或删除$符号 - 如果你自己生成json输出。public class Next
{
public string @ref { get; set; }
}
public class Item
{
public int empno { get; set; }
public string ename { get; set; }
public string job { get; set; }
public int mgr { get; set; }
public int sal { get; set; }
public int deptno { get; set; }
}
public class RootObject //(rename class you something better like Employees)
{
public Next next { get; set; }
public List<Item> items { get; set; }
}
反序列化:
var data = JsonConvert.DeserializeObject<RootObject>(json);
或
var _employees = JsonConvert.DeserializeObject<Employees>(json);
答案 2 :(得分:0)
1)您的Json响应显示,它只包含RootObject
类型的实例。
2) var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
不会,因为您尝试将RootObject
投射到List<RootObject>
。在您的错误回复中描述。
3) dynamic jsonDe = JsonConvert.DeserializeObject<RootObject>(json);
会有效,因为在此您将RootObject
投射到RootObject
。我也建议你使用&#34; var&#34;而不是&#34;动态&#34; (见原因:dynamic vs var)
4)您的以下方法似乎有错误:
private async void LoadData()
{
var emps = new RootObject();
emps = await apiServices.GetRootObject();
RootObjects.Clear();
//Mistake:
//You iterate through the previously cleared observable collection.
//it really should be "foreach (var item in emps.Items)"
foreach (var item in RootObjects)
{
RootObjects.Add(new RootItemViewModel
{
});
}
}
5)您希望在Item
上使用RootObject
类型的数组提供可观察集合:
public class RootObject
{
[JsonProperty("items")]
public Item[] Items { get; set; } //This property
[JsonProperty("next")]
public Next Next { get; set; }
}
所以你实际应该做的是设置这样的数据:
private async void GetRootObjectItems()
{
RootObject emps = await apiServices.GetRootObject(); //Get the root object
RootObjects.Clear(); //clear the list
foreach (var item in emps.Items) //Important, to get the data from the Array on the RootObject
{
///its a nice way to give your viewmodel a ctor signature that ensures a correct initialization
///public RootItemViewModel(Item item)
///{
/// this.Deptno = item.Deptno;
///}
RootObjects.Add(new RootItemViewModel(item));
}
}
}
6) RootItemViewModel
从RootObject
继承是没有意义的。您应该将其从Item
继承,或者使其拥有Item
类型的属性。
我希望我能搞清楚!