我有许多属性正在尝试使用 Json.NET 进行序列化。复杂对象可以正常工作,因为我必须在它们之上放置 [JsonProperty("name")] 属性。
不幸的是,我一直在努力让它与任何枚举一起工作。理想情况下,我希望能够通过说以下内容来定义属性:
MyValue = ThisEnum.First;
并让我的类中的属性自动将枚举序列化为适当的更改值名称(正如这个问题所问的:Control enum value format during (de)serialization via attributes。不幸的是,我编写了许多自定义转换器并尝试应用我之前的一个问题(Can't get enum to convert to json using Json.NET)中人们的建议,尽管该线程中的受访者给出了看起来可行的答案,但在我的解决方案中,他们没有没有任何影响。
例如,给定此类属性:
public class Animal
{
[JsonProperty("id")]
public string Id {get;set;}
[JsonProperty("types")]
[JsonConverter(typeof(StringEnumConverter))]
public AnimalType Types {get;set;}
[JsonProperty("created")]
[JsonConverter(typeof(MyDateTimeToSecondsSinceEpochConverter))]
public DateTime Created {get;set;}
}
在 AnimalType 枚举中:
public enum AnimalType
{
[EnumMember(Value="black_rhino")]
BlackRhino,
[EnumMember(Value="wild_pig")]
WildPig,
[EnumMember(Value="chicken")]
Chicken
}
在 MyDateTimeToSecondsSinceEpochConverter 类中:
public class MyDateTimeToSecondsSinceEpochConverter : DateTimeConverterBase
{
public override WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue(@"""\/Date(" + ConvertDateTimeToEpoch((DateTime)value).ToString() + @")\/""");
}
public override ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null) return null;
if (reader.TokenType == JsonToken.Integer)
return ConvertEpochToDateTime((long)reader.Value);
return DateTime.Parse(reader.Value.ToString());
}
public DateTime ConvertEpochToDateTime(long seconds)
{
return new DateTime(1970, 1, 1).AddSeconds(seconds);
}
public long ConvertDateTimeToEpoch(DateTime dateTime)
{
var epochStart = new DateTime(1970,1,1);
if (dateTime < epochStart) return 0;
return Convert.ToInt64(dateTime.Subtract(epochStart).TotalSeconds);
}
}
在我的调用方法中,我可以有类似的东西:
var data = new Animal {
Id = "123abc",
Types = AnimalType.BlackRhino,
Created = new DateTime(2014,3,15)
}
我使用了一种方法,通过该方法我逐步遍历对象的每个属性,其简单目的是列出每个属性以及值的 HTML 编码输出,并将它们全部放在一个字符串中(稍后我将附加到一个 URL ):
public static string GetString(Animal animal)
{
var result = "";
foreach( var property in animal.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
{
foreach(var attribute in property.GetCustomAttributes(false))
{
var name = (JsonPropertyAttribute)attribute;
var value = property.GetValue(animal, null);
if (value != null)
{
if (!string.Empty(result))
result += "&";
result += string.Format("{0}={1}", name.PropertyName, HttpUtility.UrlEncode(value.ToString()));
}
}
}
return result;
}
不幸的是,当我运行它时,我看到:
'id=abc123&type=BlackRhino&created=3%2f15%2f2014+12%3a00%3a00+AM'
有没有人对我如何让两个 JsonConverter 实际进行一些转换有任何想法?JsonProperty 名称显然在发生变化,但“BlackRhino”没有更改为“black_rhino”,DateTime 也没有转换为 long。
理想情况下,我正在寻找属性土地或使用这些转换器的东西,这样我就不必为我在项目中使用的每个枚举编写一个 get/set,而是可以只应用属性并完成用它。
谢谢!