Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
包含数组的嵌套类的JSON到C#转换_C#_Json_Json.net - Fatal编程技术网

包含数组的嵌套类的JSON到C#转换

包含数组的嵌套类的JSON到C#转换,c#,json,json.net,C#,Json,Json.net,摘要 将CICS(=大型机)Web服务生成为使用JSON进行通信的COBOL程序,并生成相关的C#接口,将这些服务作为属性和方法公开给客户端程序。程序JSPG2以一条员工记录作为响应,JSPG2A是一个可以返回最多10条员工记录的版本。JSPG2可以完美地工作(),但JSPG2A不能 细节 为了将层次化COBOL记录结构映射到C#类,一组嵌套的C#类定义如下 namespace MyJSv { public class ResponseJSPG2A { publi

摘要 将CICS(=大型机)Web服务生成为使用JSON进行通信的COBOL程序,并生成相关的C#接口,将这些服务作为属性和方法公开给客户端程序。程序JSPG2以一条员工记录作为响应,JSPG2A是一个可以返回最多10条员工记录的版本。JSPG2可以完美地工作(),但JSPG2A不能

细节 为了将层次化COBOL记录结构映射到C#类,一组嵌套的C#类定义如下

namespace MyJSv
{
    public class ResponseJSPG2A
    {
        public class JSPG2AResponse_
        {
            public class OJSPG2A_
            {
//...
                public int JZ_Employee_BrowseCount { get; set; }
                // and more scalar classes,
                public class JZ_Employee_
                {
                    public string JZ_Employee_NthReturnCode { get; set; }
                    public string EMPNO { get; set; }
                    // and more classes within the Employee record
                }
                public JZ_Employee_[] JZ_Employee { get; } = new JZ_Employee_[10];
            }
            public OJSPG2A_ OJSPG2A { get; } = new OJSPG2A_ ();
        }
        public JSPG2AResponse_ JSPG2AResponse { get; } = new JSPG2AResponse_ ();
    }
}
对于JZ Employee的单个事件,其定义为

            public JZ_Employee_ JZ_Employee { get; } = new JZ_Employee_ ();
否则,ResponseJSPG2和ResponseJSPG2A的定义相同

JSON将传入的JSON转换为C#,并使用

将来自ResponseJSPG2的数据分配给JSPG2Client希望公开的属性

这一切都适用于
ResponseJSPG2
,其中只有一个员工记录。与
等效的,其中有10条记录的数组返回10条空记录,等效的
AssignResponseToProperties
在尝试引用员工字段时失败:-

_EMPNO = Response.JSPG2AResponse.OJSPG2A.JZ_Employee[EmployeeSub].EMPNO;
然而,VisualStudio调试以及使用测试实用程序ReadyAPI对web服务程序JSPG2A进行的相同测试表明,返回的JSON包含10条员工记录,所有记录都包含预期的数据

以下是返回到测试的JSON,经过编辑以删除大多数字段和仅2条员工记录,以便与上面嵌套的C#类匹配:-

{
“JSPG2A响应”:{
“OJSPG2A”:{
“JZ_员工_BrowseCount”:16,
“JZ_员工”:[
{
“JZ_员工返回代码”:“F”,
“EMPNO”:“000060”
},
{
“JZ_员工返回代码”:“N”,
“EMPNO”:“000090”
}
]
}
}
}
问题


有没有办法让反序列化对象自动处理数组类,或者我必须使用Newtonsoft.Json.Linq和写逻辑来解析Json并显式处理数组?或者通过其他方式实现我的目标?

您的问题是
JZ_Employee
属性是一个数组值属性,而缺少setter

public JZ_Employee_[] JZ_Employee { get; } = new JZ_Employee_[10];
由于.Net数组无法调整大小,Json.Net将其视为只读集合,其内容需要累积到临时列表中,然后用于构造数组并将其设置回其父级。但是,您的数组属性没有setter,因此Json.NET将其视为完全只读,并完全跳过它

要解决此问题,可以添加setter。如果您使用以下标记属性,则它可能受到
保护
私有

演示小提琴#1

或者,您可以将属性保留为get only,但将数组替换为可调整大小的集合,如
List


转换器将自动将单个
JZ_Employee
对象的大小写转换为一个包含一项的列表。

您的问题是
JZ_Employee
属性是一个数组值属性,缺少setter

public JZ_Employee_[] JZ_Employee { get; } = new JZ_Employee_[10];
由于.Net数组无法调整大小,Json.Net将其视为只读集合,其内容需要累积到临时列表中,然后用于构造数组并将其设置回其父级。但是,您的数组属性没有setter,因此Json.NET将其视为完全只读,并完全跳过它

要解决此问题,可以添加setter。如果您使用以下标记属性,则它可能受到
保护
私有

演示小提琴#1

或者,您可以将属性保留为get only,但将数组替换为可调整大小的集合,如
List


转换器将自动将单个
JZ_员工
对象的大小写转换为包含一个项目的列表。

这是否回答了您的问题?我添加了一个实际JSON的编辑版本(只有2条记录,大部分字段被省略),以便它与我给出的C#类结构(数据模型)匹配。反序列化代码也已给出。您不需要完整的请求/响应代码,因为这也需要任何人复制我的实际程序来设置CICS Web服务器和DB2数据库。谢谢Martin,我会检查这些代码,然后我会回来说“一切正常”或提出进一步的问题“@RobertB_NZ-对于未来,这个问题有很多不需要的额外细节。真正需要的是——刚好足够的代码和JSON来演示这个问题。我在这里创建了一个:。这是否回答了您的问题?我添加了一个实际JSON的编辑版本(只有2条记录,大部分字段被省略),以便它与我给出的C#类结构(数据模型)匹配。反序列化代码也已给出。您不需要完整的请求/响应代码,因为这也需要任何人复制我的实际程序来设置CICS Web服务器和DB2数据库。谢谢Martin,我会检查这些代码,然后我会回来说“一切正常”或提出进一步的问题“@RobertB_NZ-对于未来,这个问题有很多不需要的额外细节。真正需要的是——刚好足够的代码和JSON来演示这个问题。我在这里创建了一个:。非常好,这为我的问题提供了一个非常简单的解决方案。我同意第二种选择。谢谢你,罗伯特。太好了,这为我的问题提供了一个非常简单的解决方法。我同意第二种选择。谢谢你,罗伯特。
public JZ_Employee_[] JZ_Employee { get; } = new JZ_Employee_[10];
[JsonProperty]
public JZ_Employee_[] JZ_Employee { get; private set; } = new JZ_Employee_[10];
public List<JZ_Employee_> JZ_Employee { get; } = new List<JZ_Employee_>();
[JsonConverter(typeof(SingleOrArrayConverter<JZ_Employee_>))]
public List<JZ_Employee_> JZ_Employee { get; } = new List<JZ_Employee_>();