在C#中反序列化大小为1的JSON数组

问题描述

我有两个不同的JSON对象,它们的一个属性略有不同:

import pandas as pd
from pathlib import Path


def get_sheet_details(filename):
    import os
    import xmltodict
    import shutil
    import zipfile
    sheets = []
    # Make a temporary directory with the file name
    directory_to_extract_to = (filename.with_suffix(''))
    os.mkdir(directory_to_extract_to)
    # Extract the xlsx file as it is just a zip file
    zip_ref = zipfile.ZipFile(filename,'r')
    zip_ref.extractall(directory_to_extract_to)
    zip_ref.close()
    # Open the workbook.xml which is very light and only has meta data,get sheets from it
    path_to_workbook = directory_to_extract_to / 'xl' / 'workbook.xml'
    with open(path_to_workbook,'r') as f:
        xml = f.read()
        dictionary = xmltodict.parse(xml)
        for sheet in dictionary['workbook']['sheets']['sheet']:
            sheet_details = {
                'id': sheet['@sheetId'],# can be sheetId for some versions
                'name': sheet['@name']  # can be name
            }
            sheets.append(sheet_details)
    # Delete the extracted files directory
    shutil.rmtree(directory_to_extract_to)
    return sheets


def csvfrmxlsx(xlsxfl,df):  # create csv files in csv folder on parent directory
    from xlsx2csv import Xlsx2csv
    for index,row in df.iterrows():  
        shnum = row['id']
        shnph = xlsxfl.parent / 'csv' / Path(row['name'] + '.csv')  # path for converted csv file
        Xlsx2csv(str(xlsxfl),outputencoding="utf-8").convert(str(shnph),sheetid=int(shnum))  
    return


pthfnc = 'c:/xlsx/'
wrkfl = 'my.xlsx'
xls_file = Path(pthfnc + wrkfl)
sheetsdic = get_sheet_details(xls_file)  # dictionary with sheet names and ids without opening xlsx file
df = pd.DataFrame.from_dict(sheetsdic)
csvfrmxlsx(xls_file,df)  # df with sheets to be converted

如何在不添加新类或对MyObject进行修改的情况下反序列化JSONObject2?

解决方法

更新我的答案以提供针对此问题的更动态和更可靠的答案。 在使用此解决方案时,对我来说,关于OP问题提到的问题变得显而易见,但是假设考虑到以下项目列表,则可以使用动态json解决此问题。

  1. 提供的json无效
  2. 提供的类不是可公开的,因此不能序列化
  3. 属性也不可序列化,因为它们也不公开
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Text;
using System.Threading.Tasks;

namespace commandexample
{
    class Program
    {
        static void Main(string[] args)
        {
            string JSONObject1 = @"
            {
                        prop1: ""val1"",prop2: {
                            prop3: ""val3"",prop4: ""val4""
                               }
            }";

            string JSONObject2 = @"
            {
                        prop1: ""val1"",prop2:[{
                                prop3: ""val3"",prop4: ""val4""
                              }]
            }";


            var dyn = JsonConvert.DeserializeObject<dynamic>(JSONObject2);
            if (dyn.prop2.GetType().Name == "JArray")
            {
                dyn.prop2 = dyn.prop2[0];
            }
            string updatedJson = JsonConvert.SerializeObject(dyn);

            MyObject result1 = JsonConvert.DeserializeObject<MyObject>(JSONObject1);
            MyObject result2 = JsonConvert.DeserializeObject<MyObject>(updatedJson);

        }
        public class MyObject
        {
            public string prop1 { get; set; }
            public MyInnerObject prop2 { get; set; }
        }

        public class MyInnerObject
        {
            public string prop3;
            public string prop4;
        }
    }
}

原始帖子

如果您知道该数组将始终仅包含一个项目,并且您的json文档中只有一个数组,则可以在方括号的json字符串上执行字符串替换。这将满足您特定问题的条件,但是如果将来文档更改以添加其他阵列属性,则可能会导致问题。确实取决于您的用例。

我认为这是一个数据问题,一个人试图读取由两个独立系统生成的json文档,而其中一个系统未正确创建该文档。

JSONObject2 = JSONObject2.Replace("[","").Replace("]","");

//then continue with the Deserialization 
JsonConvert.DeserializeObject<MyObject>(JSONObject2);

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...