简体   繁体   English

枚举类型属性的 RestSharp 反序列化

[英]RestSharp deserialization of Enum Type Property

I have an object我有一个对象

            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"
                }
            };

when I serialized it into json as当我将它序列化为 json 时

var jsonTcc = SimpleJson.SerializeObject(testTcc);

it returned string containing json object with YAxisPosition = 1, and when I tried deserializing it using它返回包含 YAxisPosition = 1 的 json 对象的字符串,当我尝试使用反序列化它时

testTcc = SimpleJson.DeserializeObject<TrendingConfigurationConfigDto>(jsonTcc);

It is giving an exception System.InvalidCastException with message 'Specified cast is not valid'.它给出了一个异常 System.InvalidCastException 和消息“指定的强制转换无效”。

I tried changing YAxisPosition value in json string to string "1" or "Left" it was always giving me the same error, until I removed the property YAxisPosition from json string.我尝试将 json 字符串中的 YAxisPosition 值更改为字符串“1”或“Left”,它总是给我同样的错误,直到我从 json 字符串中删除了属性 YAxisPosition。

I might be missing some thing (an Attribute on enum property or something similar).我可能遗漏了一些东西(枚举属性上的属性或类似的东西)。

Please help me finding a way so that I can Serialize and De-serialize an object which contains Enum type property, using RestSharp.请帮助我找到一种方法,以便我可以使用 RestSharp 序列化和反序列化包含 Enum 类型属性的对象。

Note: I tried successful serialization and de-serialization using NewtonSoft.注意:我尝试使用 NewtonSoft 成功进行序列化和反序列化。 but I do not want a dependency of my Web API Client on NetwonSoft, as I am already using RestSharp.但我不希望我的 Web API 客户端依赖 NetwonSoft,因为我已经在使用 RestSharp。

RestSharp removed JSON.NET support in v103.0 . RestSharp 在v103.0 中删除了 JSON.NET 支持。 The default Json Serializer is no longer compatible with Json.NET.默认的 Json Serializer 不再与 Json.NET 兼容。 You have a couple of options if you want to continue using JSON.NET and maintain backwards compatibility.如果您想继续使用 JSON.NET 并保持向后兼容性,您有几个选择。 Beyond that, JSON.NET has more capability and may solve your issues over using the basic .NET serializer which RestSharp now depends on.除此之外,JSON.NET 具有更多功能,并且可以通过使用 RestSharp 现在依赖的基本 .NET 序列化程序来解决您的问题。

Plus you can use the [EnumMember] properties to define custom mappings during deserialization.此外,您可以使用 [EnumMember] 属性在反序列化期间定义自定义映射。

Option 1: Implement a custom serializer that uses JSON.NET选项 1:实现使用 JSON.NET 的自定义序列化程序

To use Json.NET for serialization, copy this code:要使用 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; }
}

and register it with your client:并向您的客户注册:

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

Option 2: Use a nuget package to use JSON.NET选项 2:使用 nuget 包来使用 JSON.NET

Instead of doing all of that and having a custom JSON serializer spread throughout your projects is to just use this nuget package: https://www.nuget.org/packages/RestSharp.Newtonsoft.Json .只需使用这个 nuget 包: https ://www.nuget.org/packages/RestSharp.Newtonsoft.Json ,而不是做所有这些并在您的项目中传播自定义 JSON 序列化程序。 It allows you to use an inherited RestRequest object that defaults to using Newtonsoft.JSON internally like this:它允许您使用继承的 RestRequest 对象,该对象默认在内部使用 Newtonsoft.JSON,如下所示:

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

The other option is to set it on every request like this:另一种选择是在每个请求上设置它,如下所示:

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

Disclaimer: I created this project after getting frustrated with having a custom serializer laying around in my projects.免责声明:我对在我的项目中放置自定义序列化程序感到沮丧后创建了这个项目。 I created this to keep things clean and hopefully help others who want backwards compatibility with their RestSharp code that worked prior to v103.我创建这个是为了保持干净,并希望能帮助那些想要向后兼容他们在 v103 之前工作的 RestSharp 代码的人。

I got it working with the help of PocoJsonSerializerStrategy .我在PocoJsonSerializerStrategy的帮助下得到了它。 RestSharp allows you to specify your own serialization/deserialization strategy, so I created my own strategy that handles enums for me: 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);
  }
}

Now you can pass an object of this class to SimpleJson.DeserializeObject call, like this and your enums are handled elegantly:现在您可以将此类的对象传递给SimpleJson.DeserializeObject调用,就像这样,您的枚举将得到优雅的处理:

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

Found solution for this problem:找到此问题的解决方案:

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() }
                });
        }

Ie instructed RestSharp to use System.Text.Json serializer and then instructed the serializer to use JsonStringEnumConverter class to serialize/deserialize enums.即指示 RestSharp 使用 System.Text.Json 序列化器,然后指示序列化器使用JsonStringEnumConverter类来序列化/反序列化枚举。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM