我正在尝试将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);
答案 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)
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)
嵌套在具有代码,消息和数据的父对象中的房屋列表。 首先尝试反序列化父对象,然后可以从数据中提取房屋。