如何在使用自定义格式规则序列化数据表到JSON时将对象添加到JArray ?



当尝试使用自定义格式将DataTable序列化为JSON时,我在向JArray(表示表)添加JObjects(表示行)时遇到了一些麻烦。

所以我希望这个表看起来是这样的:

[
"Orderline" : {"Item": "Table", "Quantity": "5", "Amount": "50$"},
"Orderline" : {"Item": "Chair", "Quantity": "20", "Amount": "30$"},
"Orderline" : {"Item": "Couch", "Quantity": "2", "Amount": "500$"}
]

我已经尝试使用Add方法的JArray,但我似乎不能让它正常工作。

在开始时,我已经将JArray设置为new JArray,因此它在内存中,然后我将继续并一次添加一个对象到它。

我可以看到add方法有两个参数(Item作为JToken, content作为object),这让我有点困惑,因为我没有看到其他人在我在网上看到的其他代码片段中处理这两个参数。

JArray是Newtonsoft.Json.Linq.JArray类的一个实例。

期望的jobobject输出:

{
"Orderlines": {
"Item": "Table",
"Quantity": "5",
"Amount": "50"
}
}

代码:草案

Dim JsonObejct as JObject
Dim MyArray as Jarray
Dim Table as datatable
Set MyArray = new JArray
for each row in table     
JsonObject = Jobject.FromObject(
New With {
Key.Orderlines = New With{
key.Item = row("Item").Tostring,
key.Quantity = row("Quantity").tostring,
key.Amount = row("Amount").tostring
}
}
)
Myarray.add(JsonObject)
Next row

我在UiPath Studio工作,没有在多个活动中分离的同一地方的代码,所以请不要在代码中错误定义的细节中被捕获,一切工作直到添加到java部分。

我在UiPath Studio中使用Vb .net,所以我很感激如何在Vb .net中将JObects添加到我的JArray中的解决方案。

如果您只是需要修复编译,下面的代码将成功编译并生成所需的JSON结构:

Public Module DataTableJsonExtensions
Public Function ToSpecificOrderlines(ByVal table As DataTable) As JArray
Dim MyArray as JArray = New JArray
For Each row As DataRow In table.Rows
' Possibly you need to use CultureInfo.InvariantCulture in your ToString calls
Dim JsonObject As JObject = JObject.FromObject(
New With {
Key.Orderlines = New With{
key.Item = row("Item").ToString, 
key.Quantity = row("Quantity").ToString,
key.Amount = row("Amount").ToString
}
}
)
MyArray.add(JsonObject)
Next row
Return MyArray
End Function
End Module

然后做

Dim myArray as JArray = DataTableJsonExtensions.ToSpecificOrderlines(table)

在这里演示小提琴#1。

但是,似乎更可取的做法是对代码进行泛化,以便按名称序列化任何一组DataTable列,并使用可选的指定格式:

Public Module DataTableJsonExtensions
' Serialize all the columns of the table to an Orderlines array
Public Function ToOrderlines(ByVal table As DataTable) As JArray
Return ToOrderlines(table, table.Columns.Cast(Of DataColumn).Select(Function(c) c.ColumnName).ToArray())
End Function
' Serialize the selected columns of the table to an Orderlines array with the specified culture and formats (if any)
Public Function ToOrderlines(ByVal table As DataTable, ByVal columns() As String, Optional ByVal culture As CultureInfo = Nothing, Optional ByVal formats As IDictionary(Of String, String) = Nothing) As JArray
culture = If (IsNothing(culture), CultureInfo.InvariantCulture, culture)
Dim array as JArray = New JArray
For Each row As DataRow In table.Rows
Dim obj As JObject = new JObject (
new JProperty("Orderlines", 
New JObject(columns.Select(Function(c) New JProperty(c, String.Format(culture, If(Not IsNothing(formats) AndAlso formats.ContainsKey(c), formats(c), "{0}"), row(c)))))
)
)
array.add(obj)
Next row
Return array
End Function
End Module

然后,要获得在问题顶部显示的JSON,将$附加到"Amount"属性的值,执行:

Dim formats = New Dictionary(Of String, String) From {{"Amount", "{0}$"}}
Dim myArray as JArray = DataTableJsonExtensions.ToOrderlines(table, {"Item", "Quantity", "Amount"}, Nothing, formats)

如果你根本不需要格式化,你可以这样调用它:

Dim myArray as JArray = DataTableJsonExtensions.ToOrderlines(table, {"Item", "Quantity", "Amount"}) 

指出:

  • 您可以使用DataTableJsonExtensions.ToOrderlines(table)将表的所有列序列化为Orderlines数组。

  • 一般来说,应该始终使用不变区域性执行序列化,以便在一个区域(例如,美国)中序列化的JSON可以在使用不同的十进制分隔符或DateTime格式的另一个区域(例如,欧洲)中反序列化。但是,ToString()使用当前区域性对其值进行格式化。因此,如果您真的想在CultureInfo.CurrentCulture中序列化,我为您提供了指定格式化区域性的选项。为区域性传递Nothing将导致使用不变区域性。

  • 在您的问题顶部显示的JSON中,您将$附加到Amount列,因此我提供了一个可选的格式字典,以防您在序列化时需要添加它。

在这里演示小提琴#2。

最新更新