簡體   English   中英

枚舉類型屬性的 RestSharp 反序列化

[英]RestSharp deserialization of Enum Type Property

我有一個對象

            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。

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

只需使用這個 nuget 包: https ://www.nuget.org/packages/RestSharp.Newtonsoft.Json ,而不是做所有這些並在您的項目中傳播自定義 JSON 序列化程序。 它允許您使用繼承的 RestRequest 對象,該對象默認在內部使用 Newtonsoft.JSON,如下所示:

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

另一種選擇是在每個請求上設置它,如下所示:

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

免責聲明:我對在我的項目中放置自定義序列化程序感到沮喪后創建了這個項目。 我創建這個是為了保持干凈,並希望能幫助那些想要向后兼容他們在 v103 之前工作的 RestSharp 代碼的人。

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

找到此問題的解決方案:

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類來序列化/反序列化枚舉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM