如何从JSON字符串C#Newtonsoft.json获取对象列表

时间:2018-07-03 12:35:48

标签: c# json json.net

我正在尝试将JSON字符串转换为对象列表,但出现错误

无法将当前JSON对象反序列化为类型List,因为该类型需要JSON数组才能正确反序列化。

我检索了json,它看起来像这样

{
    "Code":0,
    "Message":"OK",
    "Data":
    {
        "Houses":
        [
            {
                "Id":1,
                "Name":"House 1",
                "Area":"22.00",
                "ShortName":"H1",
                "FarmName":"Farm 1"
            },
            {
                "Id":2,
                "Name":"Farmi1 - House 1",
                "Area":"1000.00",
                "ShortName":"H1",
                "FarmName":"Farm 1"
            }
        ]
    }
}

然后我说

List<House> Houses = JsonConvert.DeserializeObject<List<House>>(json); 

6 个答案:

答案 0 :(得分:3)

您获得的JSON字符串不是列表,而是具有嵌套级别的列表的对象。您将必须反序列化最外面的结构,然后获取各自的嵌套属性。

您可以定义代表数据完整结构的整个类,或者,如果您仅对房屋清单感兴趣,只需使用JObjects

var o = JsonConvert.DeserializeObject<JObject>(json);
var h = o.Value<JObject>("Data")
    .Value<JArray>("Houses")
    .ToObject<List<Houses>>();

答案 1 :(得分:2)

您不能直接进入json字符串中的子节点。您必须创建一个具有“房屋”属性的类,该类是房屋列表,然后将其反序列化。

package com.example.admin.calendlist;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity  {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mToggle;
    DatabaseHelper dbHelper;
    ArrayAdapter<String> mAdapter;
    ListView lstTask;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer);
        mToggle = new ActionBarDrawerToggle(this,mDrawerLayout, R.string.open,R.string.close);
        mDrawerLayout.addDrawerListener(mToggle);
        mToggle.syncState();
        dbHelper = new DatabaseHelper(this);
        lstTask = (ListView)findViewById(R.id.lstTask);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        NavigationView nvDrawer = (NavigationView)findViewById(R.id.nav_view);
        setupDrawerContent(nvDrawer);
        loadTaskList();

    }

    private void loadTaskList() {
        ArrayList<String> taskList = dbHelper.getTaskList();
        if(mAdapter==null){
            mAdapter = new ArrayAdapter<String>(this, R.layout.row,R.id.task_title,taskList);
            lstTask.setAdapter(mAdapter);
        }
        else{
            mAdapter.clear();
            mAdapter.addAll(taskList);
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mToggle.onOptionsItemSelected(item)){
            return true;
        }
         {
            switch (item.getItemId()) {
             case R.id.action_add_task:
                 final EditText taskEditText = new EditText(this);
                 AlertDialog dialog = new AlertDialog.Builder(this)
                         .setTitle("Add New Task")
                         .setMessage("What do you want to do next?")
                         .setView(taskEditText)
                         .setPositiveButton("Add", new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialog, int which) {
                                 String task = String.valueOf(taskEditText.getText());
                                 dbHelper.insertNewTask(task);
                                 loadTaskList();
                             }
                         })
                         .setNegativeButton("Cancel", null)
                         .create();
                 dialog.show();
         }
             switch (item.getItemId()) {
                 case R.id.td:
                     Intent newIntent = new Intent(this,MainActivity.class);
                     return true;
             }
             switch (item.getItemId()) {
                 case R.id.tt:
                     Intent newIntent = new Intent(this,Timetable.class);
                     return true;
             }
             switch (item.getItemId()) {
                 case R.id.ep:
                     Intent newIntent = new Intent(this,EventPage.class);
                     return true;
             }
        }
        return super.onOptionsItemSelected(item);
    }

    private void selectItemDrawer(MenuItem item) {
        int id = item.getItemId();
         if (id ==R.id.ep) {
             Intent newItent = new Intent (this, EventPage.class);
             startActivity(newItent);
         }
         else if (id == R.id.td) {
             Intent newIntent = new Intent (this,MainActivity.class);
             startActivity(newIntent);
         }
         else if (id == R.id.tt) {
             Intent newIntent = new Intent (this,Timetable.class);
             startActivity(newIntent);
         }
         DrawerLayout drawer = findViewById(R.id.drawer);
         drawer.closeDrawer(GravityCompat.START);
    }
    private void setupDrawerContent (NavigationView navigationView) {
        navigationView.setNavigationItemSelectedListener (new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                selectItemDrawer(item);
                return true;
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.listmenu,menu);
        Drawable icon =menu.getItem(0).getIcon();
        icon.mutate();
        icon.setColorFilter(getResources().getColor(android.R.color.black), PorterDuff.Mode.SRC_IN);
        return super.onCreateOptionsMenu(menu);
    }

    public void deleteTask(View view){
        View parent = (View)view.getParent();
        TextView taskTextView = (TextView)findViewById(R.id.task_title);
        String task = String.valueOf(taskTextView.getText());
        dbHelper.deleteTask(task);
        loadTaskList();
    }

}

类似的东西。

答案 2 :(得分:0)

您可以使用两个类反序列化如下:

class Program
{
    static void Main(string[] args)
    {
        string json = "{\"Code\":0,\"Message\":\"OK\",\"Data\":{\"Houses\":[{\"Id\":1,\"Name\":\"House 1\",\"Area\":\"22.00\",\"ShortName\":\"H1\",\"FarmName\":\"Farm 1\"},{\"Id\":2,\"Name\":\"Farmi1 - House 1\",\"Area\":\"1000.00\",\"ShortName\":\"H1\",\"FarmName\":\"Farm 1\"}]}}";
        var obj = JsonConvert.DeserializeObject<MainClass>(json);
        ShowObject(obj);
        Console.Read();
    }

    static void ShowObject(MainClass obj)
    {
        Console.WriteLine("Code: " + obj.Code);
        Console.WriteLine("Message: " + obj.Message);
        Console.WriteLine("Data:\n " + obj.Data.Keys.ElementAt(0));
        foreach (var house in obj.Data.Values.ElementAt(0))
        {
            Console.WriteLine("  Id: " + house.Id);
            Console.WriteLine("  Name: " + house.Name);
            Console.WriteLine("  Area: " + house.Area);
            Console.WriteLine("  ShortName: " + house.ShortName);
            Console.WriteLine("  FarmName: " + house.FarmName);
            Console.WriteLine();
        }
    }
}

class MainClass
{
    public int Code { get; set; }
    public string Message { get; set; }

    public Dictionary<string, House[]> Data { get; set; }
}

class House
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Area { get; set; }
    public string ShortName { get; set; }
    public string FarmName { get; set; }
}

输出: Code: 0 Message: OK Data: Houses Id: 1 Name: House 1 Area: 22.00 ShortName: H1 FarmName: Farm 1 Id: 2 Name: Farmi1 - House 1 Area: 1000.00 ShortName: H1 FarmName: Farm 1

答案 3 :(得分:0)

我假设您有一个像这样建造的收藏房屋:

SparkContext

您可能需要一个包含JSON根结构的根对象

public class Houses : List<House>
{

}

然后将全部反序列化为

public class Datas
{
    public Houses Houses;
}

using Newtonsoft.Json;

public class RootObject
{
    [JsonProperty("Code")]
    public int Code { get; set; }

    [JsonProperty("Message")]
    public string Message { get; set; }

    [JsonProperty("Data")]
    public Datas Data { get; set; }
}

您可以使用var MyJSON = JsonConvert.DeserializeObject<RootObject>(json);

访问房屋

答案 4 :(得分:0)

http://rextester.com/

中运行此代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;

namespace Rextester
{
    public class House
    {
        public int Id {set; get;}
        public string Name {set; get;}
        public float Area{set; get;}
        public string ShortName{set; get;}
        public string FarmName{set; get;}

    }
    public class MyJason
    {
        public int Code { set; get; }
        public string Message { set; get; }
        public MyData Data { set; get; }

    }

    public class MyData
    {
        public MyData()
        {
            Houses = new List<House>();
        }
        public List<House> Houses { set; get; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            string jason= "{'Code':0,'Message':'OK','Data':{'Houses':[{'Id':1,'Name':'House 1','Area':'22.00','ShortName':'H1','FarmName':'Farm 1'},{'Id':2,'Name':'Farmi1 - House 1','Area':'1000.00','ShortName':'H1','FarmName':'Farm 1'}]}}";
            MyJason myJson = JsonConvert.DeserializeObject<MyJason>(jason);
            List<House> Houses = new List<House>();
            Houses = myJson.Data.Houses;
            Console.WriteLine(Houses.FirstOrDefault().Name);

        }
    }
}

答案 5 :(得分:-1)

嵌套在具有代码,消息和数据的父对象中的房屋列表。 首先尝试反序列化父对象,然后可以从数据中提取房屋。