对具有嵌套列表的集合进行反序列化期间发生JsonReaderException

时间:2019-04-14 15:16:46

标签: c# json.net

我正在使用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; }
}

在这里您将看到一个示例,它是使用dapper在.net c#中创建的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,“状态”:0,“数量”:0.0,“价格”:23.00},{“ id”:2,“ ItemNumber”:null,“ StockCode”:“ ST232032”,“ StockDescription” :“ WashingUpLiqud”,“ isDamaged”:false,“ isMissing”:false,“状态”:0,“数量”:0.0,“价格”: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.路径”,第0行,位置0。在   Newtonsoft.Json.JsonTextReader.ParseValue()[0x002ac]在   //Src/Newtonsoft.Json/JsonTextReader.cs:1776,位于   Newtonsoft.Json.JsonTextReader.Read()[0x0004c]在   //Src/Newtonsoft.Json/JsonTextReader.cs:419 at   Newtonsoft.Json.JsonReader.ReadAndMoveToContent()[0x00000]在   //Src/Newtonsoft.Json/JsonReader.cs:1238 at   Newtonsoft.Json.JsonReader.ReadForType   (Newtonsoft.Json.Serialization.JsonContract合同,System.Boolean   hasConverter)//Src/Newtonsoft.Json/JsonReader.cs:1195
中的[0x0004a]   在   Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize   (Newtonsoft.Json.JsonReader阅读器,System.Type objectType,   System.Boolean checkAdditionalContent)[0x000db]在   //Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:196   在Newtonsoft.Json.JsonSerializer.DeserializeInternal   (Newtonsoft.Json.JsonReader阅读器,System.Type objectType)[0x00046]   在//Src/Newtonsoft.Json/JsonSerializer.cs:907中   Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader   阅读器,System.Type objectType)[0x00000]在   //Src/Newtonsoft.Json/JsonSerializer.cs:886 at   Newtonsoft.Json.JsonConvert.DeserializeObject(System.String值,   System.Type类型,Newtonsoft.Json.JsonSerializerSettings设置)   //Src/Newtonsoft.Json/JsonConvert.cs:830中的[0x0002d]   Newtonsoft.Json.JsonConvert.DeserializeObject [T](System.String值,   Newtonsoft.Json.JsonSerializerSettings设置)[0x00000]在   //Src/Newtonsoft.Json/JsonConvert.cs:786在   Newtonsoft.Json.JsonConvert.DeserializeObject [T](System.String值)   //Src/Newtonsoft.Json/JsonConvert.cs:719中的[0x00000]   App1.Views.DeliveryPage.OnAppearing()[0x00015]在   D:\ Projects \ Mobile \ New   folder \ 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


 }

1 个答案:

答案 0 :(得分:1)

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

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

但是在original versioncalling code中,您试图通过简单地调用Task<TResult>.ToString()来获取返回的字符串。

string content = GetDeliverysFromAPi().ToString();

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

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

string content = GetDeliverysFromAPi().Result;

从文档中注意Result的{​​{3}}:

  

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

     

一旦操作结果可用,就将其存储并在随后对Result属性的调用中立即返回。

正在工作的演示小提琴#2 Remarks

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

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

这甚至无法编译,因此可能是该问题中的错字;参见演示小提琴#3 here