我一直想知道是否可以这样做。
如果XML响应的值不正确,需要映射到枚举,这将是一个很好的帮助。
我特别处理的情况是,当预期值有一个尾随空格且枚举期望它没有时。
<Foo>
<Bar>EnumValue </Bar>
</Foo>
public enum MyEnum
{
[XmlEnum("EnumValue")]
EnumValue
}
public class Foo
{
[XmlElement("Bar")]
public MyEnum myEnum { get; set; }
}
我使用自定义属性(而不是&#34; XmlEnum&#34;)进行调查以修剪值,但在反序列化过程中似乎没有达到它。
有没有办法在反序列化之前/期间修剪XML值(需要时),以便可以正确地将值映射到枚举?
-
我应该补充一点,我不能对XML的发送方式进行任何更改,我只能处理响应。
此外,只需将属性参数更改为[XmlEnum(&#34; EnumValue&#34;)]即可解决问题,但这并不令人满意,因为XML值可能会在以后更改。
答案 0 :(得分:0)
如果XML不是很大并且/或者性能不太可能成为问题,那么您可以使用LINQ to XML解析它,并在使用{{1}进行反序列化之前修复任何不正确的值。 }}:
XmlSerializer
答案 1 :(得分:0)
请试试这个:
public class Foo
{
[XmlIgnore]
public MyEnum myEnum { get; set; }
[XmlElement("Bar")]
[EditorBrowsable(EditorBrowsableState.Never)]
public string _myEnum
{
get { return myEnum.ToString(); }
set { myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), value.Trim()); }
}
}
答案 2 :(得分:0)
不幸的是,没有任何事件在未知的枚举值上触发,它允许您替换自己的解析算法。此外,XmlEnumAttribute
未设置AttributeUsage.AllowMultiple = true
,因此您无法使用前导和尾随空格的各种组合添加多个枚举别名。
一种可能的解决方法是add a string-valued property to your class并手动进行解析。另一种方法是添加一个封装结构,封装enum来处理解析:
public class Foo
{
[XmlIgnore]
public MyEnum myEnum { get; set; }
[XmlElement("Bar")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public XmlEnumWrapper<MyEnum> myEnumXml { get { return myEnum; } set { myEnum = value; } }
}
public struct XmlEnumWrapper<TEnum> : IEquatable<XmlEnumWrapper<TEnum>> where TEnum : struct, IConvertible, IComparable, IFormattable
{
TEnum value;
public XmlEnumWrapper(TEnum value)
{
this.value = value;
}
public static implicit operator TEnum(XmlEnumWrapper<TEnum> wrapper)
{
return wrapper.Value;
}
public static implicit operator XmlEnumWrapper<TEnum>(TEnum anEnum)
{
return new XmlEnumWrapper<TEnum>(anEnum);
}
public static bool operator ==(XmlEnumWrapper<TEnum> first, XmlEnumWrapper<TEnum> second)
{
return first.Equals(second);
}
public static bool operator !=(XmlEnumWrapper<TEnum> first, XmlEnumWrapper<TEnum> second)
{
return !first.Equals(second);
}
[XmlIgnore]
public TEnum Value { get { return value; } private set { this.value = value; } }
[XmlText]
public string ValueString
{
get
{
return Value.ToString();
}
set
{
// See here if one needs to parse XmlEnumAttribute attributes
// http://stackoverflow.com/questions/3047125/retrieve-enum-value-based-on-xmlenumattribute-name-value
value = value.Trim();
Value = (TEnum)Enum.Parse(typeof(TEnum), value, false);
}
}
#region IEquatable<XmlEnumWrapper<TEnum>> Members
public bool Equals(XmlEnumWrapper<TEnum> other)
{
return EqualityComparer<TEnum>.Default.Equals(Value, other.Value);
}
#endregion
public override bool Equals(object obj)
{
if (obj is XmlEnumWrapper<TEnum>)
return Equals((XmlEnumWrapper<TEnum>)obj);
return Value.Equals(obj);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
}
这也允许您添加同义词处理或处理未知值,而不必在必要时抛出异常。