【问题标题】:Deserialize JSON object into type System.Guid将 JSON 对象反序列化为 System.Guid 类型
【发布时间】:2017-12-19 20:20:41
【问题描述】:

我有一个 JSON 格式的 REST 响应,如下所示:{ "guid": "c75d06a8-a705-48ec-b6b3-9076becf20f4" }

当尝试将此响应字符串反序列化为 System.Guid 类型的 Object 时,如下所示:Newtonsoft.Json.JsonConvert.DeserializeObject(response.content, type);,抛出以下异常:

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Nullable`1[System.Guid]',因为该类型需要 JSON 原始值(例如字符串、数字、布尔值) , null) 以正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 原始值(例如字符串、数字、布尔值、null)或将反序列化类型更改为正常的 .NET 类型(例如,不是整数等原始类型,而不是集合类型像数组或列表)可以从 JSON 对象反序列化。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径“guid”,第 1 行,位置 8。

感谢任何帮助!

【问题讨论】:

  • 错误告诉你为什么它不起作用:你试图将{"guid":"guid"}反序列化为GuidGuid 类型没有 guid 属性。反序列化对象,然后将guid 属性的 反序列化为Guid
  • 您可以从字符串值创建新的 GUID,如错误所示。当您提取该字符串时,请尝试 new Guid(myGuidString)

标签: c# json json.net deserialization


【解决方案1】:

GUID 和 Json 的完整示例

string content = "{\"data\":{\"Type\":\"Foo\",\"Description\":\"bar \",\"Software\":\"baz\",\"Version\":\"qux\",\"Url\":\"http://example.com\",\"DatabasePortNumber\":1,\"Id\":\"2cdc66f1-0000-0000-39ac-233c00000000\"}}";

var result_SystemText = System.Text.Json.JsonSerializer.Deserialize<SystemApplicationResponse>(content);  //Will result in null-object
var result_Newtonsoft = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemApplicationResponse>(content); //Will result in correctly serialized object

    public class SystemApplicationResponse
    {
        public SystemApplicationDto Data { get; set; }
    }


    public class SystemApplicationDto
    {
        public SystemApplicationDtoType Type { get; set; }

        public string Description { get; set; }

        public string Software { get; set; }

        public string Version { get; set; }
        public string Url { get; set; }

        public int DatabasePortNumber { get; set; }
        public System.Guid Id { get; set; }
    }

    public enum SystemApplicationDtoType
    {
        Foo = 0
    }

【讨论】:

    【解决方案2】:

    如果你不想创建一个只包含 Guid 值的类,你可以直接从解析的 Json 中解析该值:

    string json = "{ \"guid\": \"c75d06a8-a705-48ec-b6b3-9076becf20f4\" }";
    var container = JToken.Parse(json);
    Guid guid;
    if (Guid.TryParse(container["guid"]?.ToString(), out guid))
    {
        Console.WriteLine(guid);    
    }
    else{
        Console.WriteLine("No guid present or it has an invalid format");
    }
    // c75d06a8-a705-48ec-b6b3-9076becf20f4
    

    另一种选择是使用动态变量,但我个人认为这不是动态的好用例:

    string json = "{ \"guid\": \"c75d06a8-a705-48ec-b6b3-9076becf20f4\" }";
    dynamic container = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
    Guid guid;
    if (Guid.TryParse(container.guid?.ToString(), out guid)) {
        Console.WriteLine(guid);
    }
    else {
        Console.WriteLine("No guid present or it has an invalid format");
    }
    // c75d06a8-a705-48ec-b6b3-9076becf20f4
    

    【讨论】:

    • 如果数组 json 会怎样
    • 如果是呢?您仍然可以解析这些值。
    【解决方案3】:

    自从我做这种事情以来已经有一段时间了,但是我认为答案就在您的错误消息中。让它以字符串的形式返回。在您的类中覆盖 guid 字符串属性以设置 GUID 类型的另一个属性并在那里执行您的转换和错误处理。另一种方法是在这里使用构造函数来提供帮助。希望这能给你一个方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多