【问题标题】:RestSharp deserialization of Enum Type Property枚举类型属性的 RestSharp 反序列化
【发布时间】:2015-08-31 11:49:25
【问题描述】:

我有一个对象

            var testTcc = new TrendingConfigurationConfigDto
            {
                TrendingConfigurationId =1,
                ConfigId = 1,
                DeviceId = 1,
                Selected = true,
                YAxisPosition = YAxisPosition.Left,
                Order = 1,
                Color = "#ffffff",
                Configuration = new BO.Shared.Dtos.List.ConfigurationListDto
                {
                    Id = 1,
                    Name = "configuration",
                    Alias = "configuationAlias",
                    EnableEdit = true,
                    IsBusinessItem = true
                },
                Device = new BO.Shared.Dtos.List.DeviceListDto
                {
                    Id = 1,
                    Name = "Device"
                }
            };

当我将它序列化为 json 时

var jsonTcc = SimpleJson.SerializeObject(testTcc);

它返回包含 YAxisPosition = 1 的 json 对象的字符串,当我尝试使用

对其进行反序列化时
testTcc = SimpleJson.DeserializeObject<TrendingConfigurationConfigDto>(jsonTcc);

它给出了一个异常 System.InvalidCastException 并带有消息“指定的转换无效”。

我尝试将 json 字符串中的 YAxisPosition 值更改为字符串“1”或“Left”,它总是给我同样的错误,直到我从 json 字符串中删除了属性 YAxisPosition。

我可能遗漏了一些东西(枚举属性上的属性或类似的东西)。

请帮助我找到一种方法,以便我可以使用 RestSharp 对包含 Enum 类型属性的对象进行序列化和反序列化。

注意:我尝试使用 NewtonSoft 成功进行序列化和反序列化。但我不希望我的 Web API 客户端依赖于 NetwonSoft,因为我已经在使用 RestSharp。

【问题讨论】:

    标签: c# restsharp


    【解决方案1】:

    RestSharp 删除了 v103.0 中的 JSON.NET 支持。默认的 Json 序列化器不再与 Json.NET 兼容。如果您想继续使用 JSON.NET 并保持向后兼容性,您有几个选择。除此之外,JSON.NET 具有更多功能,并且可以解决您使用 RestSharp 现在所依赖的基本 .NET 序列化程序的问题。

    此外,您还可以使用 [EnumMember] 属性在反序列化期间定义自定义映射。

    选项 1:实现使用 JSON.NET 的自定义序列化程序

    要使用 Json.NET 进行序列化,请复制以下代码:

    /// <summary>
    /// Default JSON serializer for request bodies
    /// Doesn't currently use the SerializeAs attribute, defers to Newtonsoft's attributes
    /// </summary>
    public class JsonNetSerializer : ISerializer
    {
        private readonly Newtonsoft.Json.JsonSerializer _serializer;
    
        /// <summary>
        /// Default serializer
        /// </summary>
        public JsonSerializer() {
            ContentType = "application/json";
            _serializer = new Newtonsoft.Json.JsonSerializer {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                NullValueHandling = NullValueHandling.Include,
                DefaultValueHandling = DefaultValueHandling.Include
            };
        }
    
        /// <summary>
        /// Default serializer with overload for allowing custom Json.NET settings
        /// </summary>
        public JsonSerializer(Newtonsoft.Json.JsonSerializer serializer){
            ContentType = "application/json";
            _serializer = serializer;
        }
    
        /// <summary>
        /// Serialize the object as JSON
        /// </summary>
        /// <param name="obj">Object to serialize</param>
        /// <returns>JSON as String</returns>
        public string Serialize(object obj) {
            using (var stringWriter = new StringWriter()) {
                using (var jsonTextWriter = new JsonTextWriter(stringWriter)) {
                    jsonTextWriter.Formatting = Formatting.Indented;
                    jsonTextWriter.QuoteChar = '"';
    
                    _serializer.Serialize(jsonTextWriter, obj);
    
                    var result = stringWriter.ToString();
                    return result;
                }
            }
        }
    
        /// <summary>
        /// Unused for JSON Serialization
        /// </summary>
        public string DateFormat { get; set; }
        /// <summary>
        /// Unused for JSON Serialization
        /// </summary>
        public string RootElement { get; set; }
        /// <summary>
        /// Unused for JSON Serialization
        /// </summary>
        public string Namespace { get; set; }
        /// <summary>
        /// Content type for serialized content
        /// </summary>
        public string ContentType { get; set; }
    }
    

    并向您的客户注册:

    var client = new RestClient();
    client.JsonSerializer = new JsonNetSerializer();
    

    选项 2:使用 nuget 包来使用 JSON.NET

    与其做所有这些并在整个项目中使用自定义 JSON 序列化程序,不如只使用这个 nuget 包:https://www.nuget.org/packages/RestSharp.Newtonsoft.Json。它允许您使用继承的 RestRequest 对象,该对象默认在内部使用 Newtonsoft.JSON,如下所示:

    var request = new RestSharp.Newtonsoft.Json.RestRequest(); // Uses JSON.NET
    

    另一个选项是像这样在每个请求上设置它:

    var request = new RestRequest();
    request.JsonSerializer = new NewtonsoftJsonSerializer();
    

    免责声明:我对在我的项目中放置自定义序列化程序感到沮丧后创建了这个项目。我创建它是为了保持整洁,并希望能帮助那些希望向后兼容在 v103 之前工作的 RestSharp 代码的其他人。

    【讨论】:

    【解决方案2】:

    找到解决这个问题的方法:

    private IRestClient GetRestClient()
            {
                return new RestClient(url)
                    .AddDefaultHeader("Authorization", $"Bearer {token.AccessToken}")
                    .AddDefaultHeader("Accept", "*/*")
                    .AddDefaultHeader("Accept-Encoding", "gzip, deflate, br")
                    .AddDefaultHeader("Connection", "close")
                    .UseSystemTextJson(new JsonSerializerOptions
                    {
                        Converters = { new JsonStringEnumConverter() }
                    });
            }
    

    即指示 RestSharp 使用 System.Text.Json 序列化程序,然后指示序列化程序使用JsonStringEnumConverter 类来序列化/反序列化枚举。

    【讨论】:

      【解决方案3】:

      我在PocoJsonSerializerStrategy 的帮助下完成了它。 RestSharp 允许您指定自己的序列化/反序列化策略,因此我创建了自己的策略来为我处理枚举:

      public class HandleEnumsJsonSerializerStrategy : PocoJsonSerializerStrategy
      {
        public override object DeserializeObject(object value, Type type)
        {
          if (type.IsEnum)
            return Enum.Parse(type, (string)value);
          else
            return base.DeserializeObject(value, type);
        }
      }
      

      现在您可以将此类的对象传递给SimpleJson.DeserializeObject 调用,就像这样,您的枚举会被优雅地处理:

      SimpleJson.DeserializeObject<JsonObject>(Response.Content, Strategy);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-10
        • 2019-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多