我是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; }
}
当我尝试避免到列表中时,它会在此行上引发异常:
var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
错误是:
附加信息:无法对当前的json对象(例如{'name':&quot'value; value; quort; quot; quot; quot})type'system.collections.generic.generic.list.1 [system.Object]',因为该类型需要JSON阵列(例如[1,2,3])以正确序列化。
要解决此错误要么将JSON更改为JSON数组(例如[1,2,3])或更改供应类型,因此它是正常的.NET类型(例如,不是像Integer这样的原始类型,而不是一个原始类型收集类型像数组或列表一样)可以从JSON对象中进行应对。也可以将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;
}
我已经在MainViewModel中创建了一些代码,但是我不知道如何检索数据并插入类项目:
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:
public class RootItemViewModel : RootObject
{
}
1)您的JSON响应显示,它只是容纳了类型RootObject
的实例。
2) var data = JsonConvert.DeserializeObject<List<RootObject>>(json);
因此,因为您尝试将RootObject
施放到List<RootObject>
。在您的错误响应中描述。
3) dynamic jsonDe = JsonConvert.DeserializeObject<RootObject>(json);
会起作用,因为在这里您将RootObject
施放到RootObject
。我还建议您使用" var"而不是"动态"(请参阅为什么:动态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)看起来您想用RootObject
上的Item
类型喂食可观察的收藏:
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
类型的属性。
我希望我能清理东西!
为此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
您无法放置列表,因为JSON对象不是对象的纯列表,而是下一个对象和项目对象之间的对象。因此,您需要先创建一个类,然后再将JSON列入列表。
http://json2csharp.com/总是有用的,
就像"赫里先生"写的那样,您可能必须执行自定义读者或删除$符号 - 如果您自己生成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);