C# JsonConvert.DeserializeObject函数在分析过时的枚举属性时抛出错误
我想将现有的枚举属性标记为过时,并为相同的功能添加新属性。因此,我的项目中有两个可用的枚举(新的和过时的标记的) 使用jsonconvert.deserializeobject函数序列化此枚举值时,仅会从Newtonsoft 11.0以上版本引发以下错误C# JsonConvert.DeserializeObject函数在分析过时的枚举属性时抛出错误,c#,enums,json.net,deserialization,obsolete,C#,Enums,Json.net,Deserialization,Obsolete,我想将现有的枚举属性标记为过时,并为相同的功能添加新属性。因此,我的项目中有两个可用的枚举(新的和过时的标记的) 使用jsonconvert.deserializeobject函数序列化此枚举值时,仅会从Newtonsoft 11.0以上版本引发以下错误 InvalidOperationException:枚举“EditingType”上已存在枚举名称“stringedit”。 Newtonsoft.Json.Utilities.EnumUtils.InitializeValuesAndName
InvalidOperationException:枚举“EditingType”上已存在枚举名称“stringedit”。
Newtonsoft.Json.Utilities.EnumUtils.InitializeValuesAndNames(类型enumType)JsonSerializationException:将值“boolean”转换为类型“Student.Models.EditingType”时出错。路径“列[0]。编辑类型”,第1行,位置3997。Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader阅读器,对象值,CultureInfo区域性,JsonContract契约,类型targetType)
如果在我的项目中需要做任何更改,或者有任何计划从序列化函数中解决此新错误
我已将下面的代码块用于过时的枚举属性序列化
[DataContract]
public enum EditingType
{
[Obsolete("String property has been deprecated. Use StringEdit property instead")]
[EnumMember(Value = "stringedit")]
String,
[EnumMember(Value = "stringedit")]
StringEdit
}
public class JsonPropertyAttribute : Attribute
{
public JsonPropertyAttribute(string argName)
{
PropertyName = argName;
}
public string PropertyName { get; set; }
}
public class JsonConverterAttribute : Attribute
{
public Type ConverterType
{
get; set;
}
public string ValueType
{
get; set;
}
public JsonConverterAttribute(Type type, string valueType)
{
this.ConverterType = type;
this.ValueType = valueType;
}
public JsonConverterAttribute(Type type)
{
this.ConverterType = type;
}
}
public abstract class Converter
{
protected internal abstract IDictionary<string, object> BuildJsonDictionary(object value);
public abstract string SerializeToJson(object inputObject);
}
public class StringEnumConverter : Converter
{
protected internal override IDictionary<string, object> BuildJsonDictionary(object value)
{
IDictionary<string, object> jsonDictionary = new Dictionary<string, object>();
Type objectType = value.GetType();
FieldInfo member = objectType.GetField(value.ToString(), BindingFlags.Static | BindingFlags.Public);
var attrList = member.GetCustomAttributes(typeof(EnumMemberAttribute), true);
var enumMember = attrList.OfType<EnumMemberAttribute>().FirstOrDefault();
string val = enumMember != null ? enumMember.Value : value.ToString();
jsonDictionary.Add(value.GetType().Name, val);
return jsonDictionary;
}
public override string SerializeToJson(object inputObject)
{
var attrList = inputObject.GetType().GetCustomAttributes(false);
var listAttr = attrList.ToList();
FlagsAttribute flagAttr = attrList.Count() != 0 ? (FlagsAttribute)listAttr.Find(item => item.GetType() == typeof(FlagsAttribute)) : null;
bool flag = (flagAttr != null) ? true : false;
if (flag)
{
int value = (int)inputObject;
return value.ToString();
}
else
{
IDictionary<string, object> enumDictionary = BuildJsonDictionary(inputObject);
object enumValue = enumDictionary.First().Value;
string enumstring = "\"" + enumValue.ToString() + "\"";
return enumstring;
}
}
}
[Serializable]
public class TestClass
{
private EditingType _editingType = EditingType.StringEdit;
[JsonProperty("editType")]
[DefaultValue(EditingType.StringEdit)]
[JsonConverter(typeof(StringEnumConverter))]
public EditingType EditType
{
get { return _editingType; }
set { _editingType = value; }
}
}
谢谢
我对此进行了调查,这是预期的行为。Json.NET现在总是关心EnumMember,并且您有重复的值
如果要自定义JsonConverter的序列化,请实现JsonConverter。我不知道您想对示例中的转换类做什么,但Json.NET并不关心它们
来自@dbc的GitHub链接GitHub上听起来相同的Newtonsoft问题:。
public class HomeController : Controller
{
public IActionResult Index()
{
// This function will throws the error
JsonConvert.DeserializeObject("{\"editType\":\"string\"}", typeof(TestClass));
return View();
}
}