Enum Type属性的RestSharp反序列化

时间:2015-08-31 11:49:26

标签: c# restsharp

我有一个对象

            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序列化和反序列化包含枚举类型属性的对象。

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

3 个答案:

答案 0 :(得分:5)

RestSharp删除了v103.0中的JSON.NET支持。默认的Json Serializer不再与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。它允许您使用默认使用Newtonsoft.JSON的继承RestRequest对象,如下所示:

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

另一个选择是在每个请求上设置它:

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

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

答案 1 :(得分:0)

我在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);

答案 2 :(得分:0)

找到此问题的解决方案:

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 类来序列化/反序列化枚举。