使用Newtonsoft和biding View(MVVM)反序列化JSON [英] Deserialize JSON using Newtonsoft and biding View (MVVM)

查看:103
本文介绍了使用Newtonsoft和biding View(MVVM)反序列化JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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) RootItemViewModelRootObject继承是没有意义的.您应该使它继承自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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆