首页 > 解决方案 > 反序列化具有嵌套列表的集合期间出现 JsonReaderException

问题描述

我正在使用 Json.NET 反序列化一个包含我的类的列表的列表,如下所示。但是,我现在收到一个异常说非法字符,我认为这将是因为我需要有关某些东西的数据,如果有人可以帮助我,请。

public class DeliverysItems
{
    [Key]
    public int id { get; set; }
    public string OrderNumber { get; set; }
    public string CustomerName { get; set; }
    public int DeliveryDriverId { get; set; }
    public decimal OrderTotal { get; set; }
    public string TelephoneNumber { get; set; }
    public string EmailAddress { get; set; }        
    public int hasBeenDelivered { get; set; }
    public List<DeliverItemLines> DeliveryLines { get; set; }
}

public class DeliverItemLines
{
    [Key]
    public int id { get; set; }
    public string ItemNumber { get; set; }
    public string StockCode { get; set; }
    public string StockDescription { get; set; }

    public bool isDamaged { get; set; }

    public bool isMissing { get; set; }

    public int Status  { get; set; }
    public decimal Qty { get; set; }
    public decimal Price { get; set; }
}

在这里,您将看到从 .net c# 中使用 dapper 创建的 web api 2 返回的数据示例。

[{"id":1,"OrderNumber":null,"CustomerName":null,"DeliveryDriverId":1,"OrderTotal":100.00,"TelephoneNumber":"2393029023","EmailAddress":"test@test.com ","hasBeenDelivered":0,"DeliveryLines":[{"id":1,"ItemNumber":null,"StockCode":"ST233202","StockDescription":"MopBoxes","isDamaged":false,"isMissing ":false,"Status":0,"Qty":0.0,"Price":23.00},{"id":2,"ItemNumber":null,"StockCode":"ST232032","StockDescription":"WashingUpLiqud ","isDamaged":false,"isMissing":false,"Status":0,"Qty":0.0,"Price":24.99}]}]

这是我用来在我的应用程序中检索上述内容的功能。

private HttpClient _client;
public async Task<String> GetDeliverysFromAPi()
{
    var content = "";
    _client = new HttpClient();

    var uri = new Uri("http://192.168.31.65:81/api/Deliverys/"); // Your url is here

    try
    {
        var response = await _client.GetAsync(uri);
        if (response.IsSuccessStatusCode)
        {
            content = await response.Content.ReadAsStringAsync();
        }
    }
    catch (Exception ex)
    {

    }

    return content;
}

正如您所看到的,但是当我调试它时,我遇到了以下错误,顺便说一下,我正在使用 json.net。

这就是我使用 dapper.net 对上述内容进行编码的方式

public IHttpActionResult Get()
{
    string retJson;
    string constring = ConfigurationManager.AppSettings["DeliveryGocs"].ToString();

    string sql = "SELECT TOP 10 * FROM Deliverys AS A INNER JOIN DeliveryLines AS B ON A.id = B.DeliveryId;";

    using (var connection = new SqlConnection(constring))
    {
        var orderDictionary = new Dictionary<int, DeliverysItems>();

        var list = connection.Query<DeliverysItems, DeliverItemLines, DeliverysItems>(
            sql,
            (order, orderDetail) =>
            {
                DeliverysItems orderEntry;

                if (!orderDictionary.TryGetValue(order.id, out orderEntry))
                {
                    orderEntry = order;
                    orderEntry.DeliveryLines = new List<DeliverItemLines>();
                    orderDictionary.Add(orderEntry.id, orderEntry);
                }

                orderEntry.DeliveryLines.Add(orderDetail);
                return orderEntry;
            })
        .Distinct()
        .ToList();

        retJson = JsonConvert.SerializeObject(list);
        var response = this.Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent(retJson, Encoding.UTF8, "application/json");

        return ResponseMessage(response);
    }
}

引发的异常如下。

{Newtonsoft.Json.JsonReaderException: 解析值时遇到意外字符:S. Path '', line 0, position 0. at Newtonsoft.Json.JsonTextReader.ParseValue () [0x002ac] in //Src/Newtonsoft.Json/JsonTextReader. cs:1776 at Newtonsoft.Json.JsonTextReader.Read () [0x0004c] in //Src/Newtonsoft.Json/JsonTextReader.cs:419 at Newtonsoft.Json.JsonReader.ReadAndMoveToContent () [0x00000] in //Src/Newtonsoft. Json/JsonReader.cs:1238 at Newtonsoft.Json.JsonReader.ReadForType (Newtonsoft.Json.Serialization.JsonContract contract, System.Boolean hasConverter) [0x0004a] in //Src/Newtonsoft.Json/JsonReader.cs:1195
在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in / /Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:196 在 Newtonsoft。 Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00046] in //Src/Newtonsoft.Json/JsonSerializer.cs:907 at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader , System.Type objectType) [0x00000] in //Src/Newtonsoft.Json/JsonSerializer.cs:886 at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String 值, System.Type 类型, Newtonsoft.Json.JsonSerializerSettings 设置) [ 0x0002d] 在 //Src/Newtonsoft.Json/JsonConvert.cs:830 at Newtonsoft.Json.JsonConvert.DeserializeObject[T](System.String 值,Newtonsoft.Json.JsonSerializerSettings 设置)[0x00000] in //Src/Newtonsoft.Json/JsonConvert。 cs:786 at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) [0x00000] in / /Src/Newtonsoft.Json/JsonConvert.cs:719 at App1.Views.DeliveryPage.OnAppearing () [0x00015]在 D:\Projects\Mobile\New 文件夹\App1\App1\App1\Views\DeliveryPage.xaml.cs:95 }

第 95 行是我对列表对象进行反序列化的行。to 字符串用于确保不返回对象。

这就是我调用我的反序列化方法的方式。

string content = GetDeliverysFromAPi(); //Sends a GET request to the specified Uri and returns the response body as a string in an asynchronous operation
List<DeliverysItems> _deliveryItems =JsonConvert.DeserializeObject<List<DeliverysItems>>(content); //Deserializes or converts JSON String into a collection of Post

下面标记的答案确实是正确的,我可以通过如下调整我的方法来获取数据。

public DeliveryDataStore()
{

        Task<string> callTask = Task.Run(() => GetDeliverysFromAPi());
        // Wait for it to finish
        callTask.Wait();
        // Get the result
        string content = callTask.Result;

        //Sends a GET request to the specified Uri and returns the response body as a string in an asynchronous operation
         deliverysItems = JsonConvert.DeserializeObject<List<DeliverysItems>>(content); //Deserializes or converts JSON String into a collection of Post


 }

标签: c#json.net

解决方案


问题是您的方法GetDeliverysFromAPi()返回一个Task<String>

public async Task<String> GetDeliverysFromAPi() { /* Contents omitted */ }

但是在调用代码的原始版本中,您试图通过简单地调用来获取返回的字符串。 Task<TResult>.ToString()

string content = GetDeliverysFromAPi().ToString();

但是,Task<TResult>不会覆盖ToString(),因此这只会返回完整的类型名称(此处"System.Threading.Tasks.Task`1[System.String]"为演示小提琴 #1 )。

相反,使用Task<TResult>.Result来获得结果:

string content = GetDeliverysFromAPi().Result;

请注意文档中的备注Result

访问属性的 get 访问器会阻塞调用线程,直到异步操作完成;相当于调用Wait方法。

一旦操作的结果可用,它就会被存储并在后续调用 Result 属性时立即返回。

工作演示小提琴#2 here

顺便说一句,在您编辑的问题中

string content = GetDeliverysFromAPi(); //Sends a GET request to the specified Uri and returns the response body as a string in an asynchronous operation

这甚至不会编译,所以可能是问题中的错字;在此处查看演示小提琴#3 。


推荐阅读