【问题标题】:Deserialize object does not return full data in Xamarin.Forms反序列化对象不返回 Xamarin.Forms 中的完整数据
【发布时间】:2019-08-14 16:04:35
【问题描述】:

我有一个基于用户键入的关键字返回的 JSON 对象。它只返回用户输入的一些关键字。当我检查邮递员并输入相同的关键字时,它会正确返回。

引发以下异常:

Newtonsoft.Json.JsonSerializationException: 
Must specify valid information for parsing in the string

JSON

{
  "valid": true,
  "result": {
    "points": [
      {
        "pointId": "505",
        "name": "Building one",
        "description": "Office of Technology and Data Application Development",
        "latitude": "xxx",
        "longitude": "xxx",
        "floor": "B",
        "aliases": [],
        "comments": [],
        "images": []
      }
    ],
    "categories": []
  },
  "errors": []
}

模型类

public class SearchPoints
{
    public bool Valid { get; set; }
    public Result Result { get; set; }
    public List<string> Errors { get; set; }
}

public class Result
{
    public List<Point> Points { get; set; }
    public List<Category> Categories { get; set; }
}

public class Category
{
  public long CategoryId { get; set; }
  public string Name { get; set; }
  public long ParentId { get; set; }
  public string Parent { get; set; }
}

public class Point
{
    public long PointId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Latitude { get; set; }
    public string Longitude { get; set; }
    public Floor Floor { get; set; }
    public List<string> Aliases { get; set; }
    public List<string> Comments { get; set; }
    public List<string> Images { get; set; }
}

public enum Floor 
{ 
    A, 
    B 
};

服务方式

var apiResponse = await _httpClient.GetAsync(Url + _keyword);
var apiContent = apiResponse.Content.ReadAsStringAsync().Result;
var pointsJsonResponse = JsonConvert.DeserializeObject<SearchPoints>(apiContent);

var potentialPoints = new ObservableCollection<Point>(pointsJsonResponse.Result.Points);

PointsItemSource = potentialPoints;

【问题讨论】:

  • 您是否将代码中返回的原始 json 与邮递员进行了比较?它们是相同的还是不同的?如果它们不同,那么您发布的所有代码都与解决问题无关。
  • 是的,我比较了它们,它们是相同的。
  • 所以当你反序列化时,只是缺少一些项目?多少?有什么规律吗?
  • @Anthony 您如何发送键入的关键字?当用户输入或他们有一个提交按钮可以点击?
  • 他们没有多少失踪,我不认为有一个模式。我怎么知道有些缺失是当我在邮递员中测试相同的关键字时,我得到了正确的列表,但是当我用应用程序测试时,我没有

标签: c# xamarin.forms json.net


【解决方案1】:

问题中显示的 JSON 成功反序列化为问题中显示的数据模型,请参阅https://dotnetfiddle.net/nDhNPL

但是,您的问题中显示的异常提供了一些信息。根据search,特别是在@ 987654323@:

public static object ParseEnum(Type enumType, NamingStrategy? namingStrategy, string value, bool disallowNumber)
{

// SNIP

    if (firstNonWhitespaceIndex == -1)
    {
        throw new ArgumentException("Must specify valid information for parsing in the string.");
    }

如果在解析enum 字符串时,传入的值仅包含空格,则相关代码将引发异常。因此,我将您问题中的 JSON 修改如下:

    "floor": " ",

并重现了此处显示的异常:https://dotnetfiddle.net/6zaG9W

因此,您实际上必须尝试使用​​ Floor 的空值或空格值解析 JSON 并失败,因为这是不可能的。要完成这项工作,您可以:

  1. Point.Floor 改为字符串:

    public string Floor { get; set; }
    

    JSON 现在将成功解析。演示小提琴在这里:https://dotnetfiddle.net/zg5YWr.

  2. 使用StringEnumConverter 的特殊子类来处理Floor 的空字符串。在Davor ZlotrganswerHow to handle deserialization of empty string into enum in json.net 中显示了一个示例,我在这里对其进行概括:

    public class EmptyTolerantStringEnumConverter : StringEnumConverter
    {
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.String && string.IsNullOrWhiteSpace(reader.Value.ToString()))
                // Return a default value.  Note if deserializing a nullable enum the default value is null
                return Activator.CreateInstance(objectType);
    
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }       
    }
    

    并应用如下:

    [JsonConverter(typeof(EmptyTolerantStringEnumConverter))]
    public Floor Floor { get; set; }
    

    或者,如果您希望将 "" 映射到可为空的:

    [JsonConverter(typeof(EmptyTolerantStringEnumConverter))]
    public Floor? Floor { get; set; }
    

    这里是演示小提琴:https://dotnetfiddle.net/DwGKHU

相关:How to tell Json.Net globally to apply the StringEnumConverter to all enumsparsing an enumeration in JSON.net

【讨论】:

  • 谢谢,我知道我正确解析了 JSON,但我不明白 EnumUtils.ParseEnum (System.Type enumType, Newtonsoft.Json.Serialization.NamingStrategy namingStrategy, System.String value, System.Boolean disallowNumber) 错误
【解决方案2】:

我很确定 Json.Net 无法反序列化“对象”类型。它需要真正的类型:

所以用List&lt;TRealType&gt;替换你所有的List&lt;object&gt;

例子:

    public List<string> Aliases { get; set; }
    public List<string> Comments { get; set; }
    public List<string> Images { get; set; }

如果您仍然收到错误,则错误在您的 apiContent 变量中,它不是正确的 json 字符串。

您还需要将[JsonConverter(typeof(StringEnumConverter))] 属性放在您的枚举类型上。

【讨论】:

  • 它似乎仍然没有反序列化
  • 那么您的问题出在您的apiContent 字符串中,因此您需要更新您的帖子并添加创建此字符串的代码。
  • 你的更新不好:你检索了一个 apiResponse,然后反序列化了一个 apiContent。
  • 好的,现在在这一行之后放置一个断点,然后将 apiContent 的值复制粘贴到您的帖子中。并使用您在列表中所做的更改更新您的所有 SearchPoints、Result 和 Point 类
  • 您的属性名称的大小写与 json 不匹配
猜你喜欢
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-16
相关资源
最近更新 更多