在JSON对象内部返回JArray

时间:2018-08-28 18:43:51

标签: c# json json.net

我一直在开发一个简单的.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元素返回?

谢谢!

1 个答案:

答案 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更改为数组,则可以执行以下操作:

  1. 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; }
    }
    
  2. 将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; }
    }
}