我有一个 json 属性路径及其值的键值对列表,
Key: $.orderNumber Value: "100001"
Key: $.orderedOn Value: "01-01-2021"
Key: $.product.name Value: "hard"
Key: $.product.type Value: "plastic"
Key: $.contacts[?(@.contactType == 'primary')].phone Value: "101010101010"
Key: $.contacts[?(@.contactType == 'secondary')].phone Value: "2020202020"
并且想要创建一个 JSON 对象或 JSON 字符串,如下所示
{
"orderNumber": "100001",
"orderedOn": "01-01-2021",
"product": {
"type": "hard",
"name": "plastic"
},
"contacts": [
{
"contactType": "primary",
"phone": "101010101010"
},
{
"contactType": "secondary",
"phone": "202020202020"
}
]
}
是否可以使用 JSON PATH 创建 JSON 对象,或者我需要手动检查写入所有属性?
我想动态创建 JSON 对象。
我尝试过 Json.net Unflatten,但它没有覆盖条件数组键。
静态解决方案:
没有找到动态解决方案,所以我创建了一个静态解决方案:
型号: 定义表示 JSON 对象结构的 C# 类。
class Order
{
public string OrderNumber { get; set; }
public string OrderedOn { get; set; }
public Product Product { get; set; }
public List<Contact> Contacts { get; set; }
}
class Product
{
public string Type { get; set; }
public string Name { get; set; }
}
class Contact
{
public string ContactType { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
}
M拍打功能: 将 JSON 路径和值映射到 Order 对象中的相应属性。
Order MapOrderObjectWithJsonPath(Order order, string jsonPath, string value)
{
// First initialize the order object if necessary for nested objects.
InitializeObjects(order, jsonPath);
// Use switch-case for better performance.
switch (jsonPath)
{
case "$.orderNumber":
order.OrderNumber = value;
break;
case "$.orderedOn":
order.OrderedOn = value;
break;
case "$.product.type":
order.Product.Type = value;
break;
case "$.product.name":
order.Product.Name = value;
break;
// In my case, contact type is an identifier.
case "$.contacts[?(@.contactType == 'primary')].phone":
order.Contacts.FirstOrDefault(x => x.ContactType == "primary").Phone = value;
break;
case "$.contacts[?(@.contactType == 'primary')].address":
order.Contacts.FirstOrDefault(x => x.ContactType == "primary").Address = value;
break;
case "$.contacts[?(@.contactType == 'secondary')].phone":
order.Contacts.FirstOrDefault(x => x.ContactType == "secondary").Phone = value;
break;
case "$.contacts[?(@.contactType == 'secondary')].address":
order.Contacts.FirstOrDefault(x => x.ContactType == "secondary").Address = value;
break;
}
}
对象初始化: 基于 JSON 路径初始化嵌套对象(产品、联系人)。
public void InitializeObjects(Order order, string jsonPath)
{
// Initialize the product object if it is not initialized before.
if (jsonPath.Contains(".product.") && order.Product == null)
order.Product = new Product();
// For the contacts array, initialize and check the respective contact element.
// If it is not in the list mentioned in the JSON path, create that element and add it to the contact list.
else if (jsonPath.Contains("$.contacts[?(@.contactType == 'primary')]"))
{
if (order.Contacts == null) order.Contacts = new List<Contact>();
if (!order.Contacts.Any(x => x.ContactType.Equals("primary")))
{
Contact primaryContact = new Contact();
primaryContact.ContactType = "primary";
order.Contacts.Add(primaryContact);
}
}
else if (jsonPath.Contains("$.contacts[?(@.contactType == 'secondary')]"))
{
if (order.Contacts == null) order.Contacts = new List<Contact>();
if (!order.Contacts.Any(x => x.ContactType.Equals("secondary")))
{
Contact secondaryContact = new Contact();
secondaryContact.ContactType = "secondary";
order.Contacts.Add(secondaryContact);
}
}
}
用途:
using Newtonsoft.Json;
// Create an empty Order object
Order order = new Order();
// List of JSON paths and corresponding values, considering that you have that in a list.
List<(string jsonPath, string value)> jsonPathValues = new List<(string, string)>
{
// Add your JSON paths and values here
// Example: ("$.orderNumber", "100001"),
};
// Loop through each JSON path and value, mapping them to the order object.
foreach (var (jsonPath, value) in jsonPathValues)
{
// Map the JSON path and value to the existing Order object
MapOrderObjectWithJsonPath(order, jsonPath, value);
}
// Serialize the 'order' object into JSON with settings to handle null values for empty objects
string json = JsonConvert.SerializeObject(order, Formatting.None, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
// Now 'json' has the result