使用Newtonsoft和biding View(MVVM)反序列化JSON [英] Deserialize JSON using Newtonsoft and biding View (MVVM)
问题描述
我是C#和Xamarin的初学者.我正在尝试使用newtonsoft反序列化json数组吗? 这是我的json文件:
I'm a beginner in C # and Xamarin. I'm trying to deserialize json arrays with newtonsoft? Here is my json file:
{
"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; }
}
当我尝试反序列化为列表时,它将在此行上引发异常:
When I try deserialize into a List it throws exception on this line:
var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
错误是:
其他信息:无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.List`1 [System.Object]',因为该类型需要JSON数组(例如[1,2,3])正确反序列化.
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[System.Object]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不是整数之类的原始类型,而不是可以从JSON对象反序列化的集合类型(如数组或List).还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
此代码反序列化了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;
}
我已经在MainViewModel中创建了一些代码,但是我不知道如何检索数据并插入类Item:
I have already created some code in MainViewModel, but I do not know how to retrieve the data and insert the class 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
}
}
RootItemViewModel类:
The class RootItemViewModel:
public class RootItemViewModel : RootObject
{
}
推荐答案
1).您的Json响应显示,它仅包含类型为RootObject
的实例.
1) Your Json response shows, that it just holds an instance of the type RootObject
.
2) var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
将因此不起作用,因为您尝试将RootObject
强制转换为List<RootObject>
.在您的错误响应中进行了说明.
2) var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
will not work therefore, because you try to cast a RootObject
to a List<RootObject>
. Described in your error response.
3) dynamic jsonDe = JsonConvert.DeserializeObject<RootObject>(json);
将起作用,因为在这里将RootObject
强制转换为RootObject
.我还建议您使用"var"代替"dynamic"(请查看原因: dynamic vs var )
3) dynamic jsonDe = JsonConvert.DeserializeObject<RootObject>(json);
will work because here you cast a RootObject
to a RootObject
. I also suggest you tu use "var" instead of "dynamic" (see why: dynamic vs var)
4),您的以下方法似乎有一个错误:
4) your following method seems to have a mistake in there:
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):您似乎想在RootObject
上使用类型为Item
的数组来提供可观察的集合:
5) It looks like you wanted to feed the observable collection with the array of type Item
on your RootObject
:
public class RootObject
{
[JsonProperty("items")]
public Item[] Items { get; set; } //This property
[JsonProperty("next")]
public Next Next { get; set; }
}
所以您实际上应该做的是像这样设置数据:
So what you actually should be doing is setting the data like this:
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
类型的属性.
6) It makes no sense for your RootItemViewModel
to inherit from RootObject
. You should make it inherit from Item
or have it hold a property of type Item
.
我希望我能把事情弄清楚!
I hope I could clear things up!
这篇关于使用Newtonsoft和biding View(MVVM)反序列化JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!