我一直在开发一个简单的.Net Core API。我的大多数控制器都执行SQL过程,以获取数据并以C#端模型中指定的格式返回数据。我查询了一些动态数据(TransactionDetails),并将其转换为JSON格式。
我希望能够在C#端以JSON格式读取此字段,但无法使其正常工作。现在,我将类型设置为字符串。我尝试使用“ Newtonsoft.Json.Linq”并将模型中的TransactionDetails字段设置为JArray,但是由于某些原因,这破坏了API的Authorization部分。
控制器:
[HttpGet("/api/Customer/GetTransactions/{customerNumber}/{startDate}/{endDate}")]
public async Task<IEnumerable<CustomerTransaction>> GetCustomerTransactions(string customerNumber, DateTime startDate, DateTime endDate)
{
var custNum = new SqlParameter("@custNum", customerNumber);
var dateFrom = new SqlParameter("@dateFrom", startDate);
var dateTo = new SqlParameter("@dateTo", endDate);
return await context.CustomerTransactions.FromSql("EXEC MyDatabase.dbo.crm_GetCustomerTransactions @custNum, @dateFrom, @dateTo", custNum, dateFrom, dateTo)
.AsNoTracking()
.ToArrayAsync();
}
型号:
public class CustomerTransaction
{
[Key] public string KwiNumber { get; set; }
public int StoreNumber { get; set; }
public int TransactionNumber { get; set; }
public DateTime TransactionDate { get; set; }
public TimeSpan TransactionTime { get; set; }
public string TransactionDetails { get; set; }
}
当前响应:
[
"kwiNumber":"XXXXXXXXXX",
"storeNumber":"XXXXXX",
"transactionNumber":169306,
"transactionDate":"2014-03-30T00:00:00",
"transactionTime":"17:21:00",
"transactionDetails":"[\r\n {\"StoreNumber\":\"XXXXXX\",\"TransactionNumber\":\"170272\",\"KwiNumber\":\"XXXXXXXXXX\",\"TenDigitUPC\":\"4303677390\",\"TerminalNumber\":\"1\",\"TransactionDate\":\"2014-04-18\",\"TransactionTime\":\"14:27:00\",\"EmployeeNumber\":\"10546\",\"CashierNumber\":\"10546\",\"DiscountReasonCode\":\"0\",\"CouponCode\":\"0\",\"SalesType\":\"R\",\"UnitsSold\":\"2\",\"SalePrice\":\"30.00\",\"StyleNumber\":\"J97922\",\"ClassCode\":\"020\",\"SubClassCode\":\"108\"},\r\n {\"StoreNumber\":\"XXXXXX\",\"TransactionNumber\":\"170272\",\"KwiNumber\":\"XXXXXXXXXX\",\"TenDigitUPC\":\"4303678979\",\"TerminalNumber\":\"1\",\"TransactionDate\":\"2014-04-18\",\"TransactionTime\":\"14:27:00\",\"EmployeeNumber\":\"10546\",\"CashierNumber\":\"10546\",\"DiscountReasonCode\":\"0\",\"CouponCode\":\"0\",\"SalesType\":\"R\",\"UnitsSold\":\"1\",\"SalePrice\":\"0.00\",\"StyleNumber\":\"D31001\",\"ClassCode\":\"111\",\"SubClassCode\":\"039\"},\r\n {\"StoreNumber\":\"XXXXXX\",\"TransactionNumber\":\"170272\",\"KwiNumber\":\"XXXXXXXXXX\",\"TenDigitUPC\":\"8193434784\",\"TerminalNumber\":\"1\",\"TransactionDate\":\"2014-04-18\",\"TransactionTime\":\"14:27:00\",\"EmployeeNumber\":\"10546\",\"CashierNumber\":\"10546\",\"DiscountReasonCode\":\"0\",\"CouponCode\":\"0\",\"SalesType\":\"R\",\"UnitsSold\":\"1\",\"SalePrice\":\"8.00\",\"StyleNumber\":\"J96412\",\"ClassCode\":\"020\",\"SubClassCode\":\"108\"}\r\n]"
]
所需响应:
[
"kwiNumber":"XXXXXXXXXX",
"storeNumber":"XXXXXX",
"transactionNumber":169306,
"transactionDate":"2014-03-30T00:00:00",
"transactionTime":"17:21:00",
"transactionDetails": [
{
"StoreNumber":"XXXXXX",
"TransactionNumber":"169306",
"KwiNumber":"XXXXXXXXXX",
"TenDigitUPC":"4303680836",
"TerminalNumber":"1",
"TransactionDate":"2014-03-30",
"TransactionTime":"17:21:00",
"EmployeeNumber":"2215",
"CashierNumber":"2215",
"DiscountReasonCode":"0",
"CouponCode":"0",
"SalesType":"R",
"UnitsSold":"1",
"SalePrice":"68.00",
"StyleNumber":"JN7612",
"ClassCode":"008",
"SubClassCode":"026"
},
{
"StoreNumber":"XXXXXX",
"TransactionNumber":"169306",
"KwiNumber":"XXXXXXXXXX",
"TenDigitUPC":"8193434814",
"TerminalNumber":"1",
"TransactionDate":"2014-03-30",
"TransactionTime":"17:21:00",
"EmployeeNumber":"2215",
"CashierNumber":"2215",
"DiscountReasonCode":"0",
"CouponCode":"0",
"SalesType":"R",
"UnitsSold":"2",
"SalePrice":"52.00",
"StyleNumber":"J96442",
"ClassCode":"020",
"SubClassCode":"108"
}
]
]
当调用GetCustomerTransactions时,如何在C#中读取此动态JArray并将其作为子JSON元素返回?
谢谢!
答案 0 :(得分:1)
目前尚不清楚json为什么将transactionDetails
保留为字符串as it should be an array。如果它将是一个数组,则将具有以下类:
public class TransactionDetail
{
public string StoreNumber { get; set; }
public string TransactionNumber { get; set; }
public string KwiNumber { get; set; }
public string TenDigitUPC { get; set; }
public string TerminalNumber { get; set; }
public string TransactionDate { get; set; }
public string TransactionTime { get; set; }
public string EmployeeNumber { get; set; }
public string CashierNumber { get; set; }
public string DiscountReasonCode { get; set; }
public string CouponCode { get; set; }
public string SalesType { get; set; }
public string UnitsSold { get; set; }
public string SalePrice { get; set; }
public string StyleNumber { get; set; }
public string ClassCode { get; set; }
public string SubClassCode { get; set; }
}
public class CustomerTransaction
{
public string kwiNumber { get; set; }
public string storeNumber { get; set; }
public int transactionNumber { get; set; }
public DateTime transactionDate { get; set; }
public string transactionTime { get; set; }
public List<TransactionDetail> transactionDetails { get; set; }
}
然后解析它就像这样简单:
var records = JsonConvert.DeserializeObject<List<CustomerTransaction>>(json);
但是,如果由于某种原因无法将transactionDetails
更改为数组,则可以执行以下操作:
将CustomerTransaction
更改为:
public class CustomerTransaction
{
public string kwiNumber { get; set; }
public string storeNumber { get; set; }
public int transactionNumber { get; set; }
public DateTime transactionDate { get; set; }
public string transactionTime { get; set; }
[JsonProperty(PropertyName = "transactionDetails")]
public string transactionDetailsRaw { get; set; }
[JsonIgnoreAttribute]
public List<TransactionDetail> transactionDetails { get; set; }
}
将json解析为JArray
,迭代每个孩子,然后分别解析transactionDetails
。
完整的示例程序(我使用了更小的json版本。小提琴是here):
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string toParse =
"[{\r\n \"kwiNumber\":\"XXXXXXXXXX\",\r\n \"transactionDetails\" : \"[\\r\\n {\\\"StoreNumber\\\":\\\"XXXXXX\\\" } \\r\\n]\"}]";
List<CustomerTransaction> records = new List<CustomerTransaction>();
JArray parsed = JArray.Parse(toParse);
foreach(var item in parsed.Children())
{
CustomerTransaction customerTransaction = JsonConvert.DeserializeObject<CustomerTransaction>(item.ToString());
customerTransaction.transactionDetails = JsonConvert.DeserializeObject<List<TransactionDetail>>(customerTransaction.transactionDetailsRaw);
records.Add(customerTransaction);
}
}
public class TransactionDetail
{
public string StoreNumber { get; set; }
public string TransactionNumber { get; set; }
public string KwiNumber { get; set; }
public string TenDigitUPC { get; set; }
public string TerminalNumber { get; set; }
public string TransactionDate { get; set; }
public string TransactionTime { get; set; }
public string EmployeeNumber { get; set; }
public string CashierNumber { get; set; }
public string DiscountReasonCode { get; set; }
public string CouponCode { get; set; }
public string SalesType { get; set; }
public string UnitsSold { get; set; }
public string SalePrice { get; set; }
public string StyleNumber { get; set; }
public string ClassCode { get; set; }
public string SubClassCode { get; set; }
}
public class CustomerTransaction
{
public string kwiNumber { get; set; }
public string storeNumber { get; set; }
public int transactionNumber { get; set; }
public DateTime transactionDate { get; set; }
public string transactionTime { get; set; }
[JsonProperty(PropertyName = "transactionDetails")]
public string transactionDetailsRaw { get; set; }
[JsonIgnoreAttribute]
public List<TransactionDetail> transactionDetails { get; set; }
}
}