我正在使用Visual Studio的自动生成的REST Web应用程序项目结构来创建一个使用JSON输入的RESTful API。将JSON数组中的对象从C#中的自定义类转换为对象#
没有进入太多细节,我试图限定JSON结构喜欢这些:
实施例1:
"operation": {
"type": "EXIST",
"args": [
{
"ColumnName": "SomeColumnA",
"Row": 2
}
]
}
实施例2:
"operation": {
"type": "ADD",
"args": [
{
"type": "ADD",
"args": [
{
"columnName": "SomeColumnB",
"row": 12
},
{
"columnName": "SomeColumnC",
"row": 18
}
]
},
20
]
}
operation
表示的一个任何数量的基本数据库操作以及这些操作的参数。在我的第一个示例中,操作是EXIST
,它应检查数据库单元以查看值是否存在。此操作的args
只是一个包含要检查的单元格的列和行信息的对象(我称之为Value
)。在我的第二个示例中,函数ADD
,它应该将两个值一起添加并返回总和。这里的参数是一个常数20和嵌套的ADD
函数,它本身需要两个Values
。因此,一般来说,args
数组可以采用原始值,嵌套的另一个operation
或表示单元格的一对值来读取实际值。这里的最终目标是创建一个通用结构,使我可以嵌套函数,单元格值和常量的组合来创建复合函数,如Average
或Sum
。
在我的模型文件夹中,我有以下的类来我的数据转换为:
public class Instruction
{
public Operation[] Operations { get; set; }
}
public class Operation
{
public string Type { get; set; }
public object[] Args { get; set; }
}
public class Value
{
public string ColumnName { get; set; }
public int Row { get; set; }
}
注意,在Operation
的Args
为object[]
类型。
当我通过POST这个JSON调用我的web应用程序时,C#会自动将JSON解析为我的Models文件夹中定义的对象。假设我们用例1:
[HttpPost]
public IHttpActionResult Foo(Instruction instruction)
{
foreach(Operation op in instruction.Operations) {
switch (op.Type) {
case "EXIST":
Console.WriteLine("exist"); // works fine
// since we got here, expect Args[0] to be type 'Value'
var value = (Value) op.Args[0]; // InvalidCastException
// logic for EXIST
case "ADD":
// logic for ADD
// ...
}
}
}
它铸造Operation
就好了,我也得到了Type
正确。我还得到Args
作为object[]
与一个孤立的元素。但如果我尝试将它投射到Value
,它会拒绝正确投射。
我的问题毕竟是这样的:什么是最好的方式来实现它看起来像我在这里试图做的?我在正确的轨道上吗?如果是这样,我的错误是什么?如果我以错误的方式回答这个问题,那么更好的替代方法是什么?请注意,由于我使用的是Visual Studio的开箱即用的Web应用程序框架,因此我似乎无法访问将JSON去分流的功能,所以我不认为我可以构建自定义的反序列化器。
除非你试图顺应一些已经发布的JSON有效载荷的规格,为什么不首先定义类启动和使用的许多类到JSON预览工具之一?这样你就知道在反序列化过程中很可能没有任何问题。这与XML相同,我很懒,总是先创建类 – MickyD
哪个JSON数组,你想投射?Example1与Example2不同 –
如果将Args定义为'public Value [] Args {get; set; }'?还要看看C#中的动态类型。你可以在你的Operation模型中定义Args为'public dynamic Args {get; set;}'。从那里你可以使用'Args [0] .row'而不需要另一个模型。 – garethb