C# WCF反序列化中的XmlException:“;名称不能以'<'"E;”在自动属性备份字段中
今天,我开始在WCF反序列化中遇到错误——代码一直保持不变,并且工作了几个月C# WCF反序列化中的XmlException:“;名称不能以'<'"E;”在自动属性备份字段中,c#,wcf,serialization,.net-4.0,xmlexception,C#,Wcf,Serialization,.net 4.0,Xmlexception,今天,我开始在WCF反序列化中遇到错误——代码一直保持不变,并且工作了几个月 问题是,我得到运行时xmleexceptions,说“名称不能以“开头,我现在有一个解决办法,但这不是我可以依赖的->导致问题的DTO已从[ServiceKnownType]发布服务器上删除,这使得错误消失 我想知道问题是否与我得到的例外的成员名称有关。到目前为止,我已经看到它抱怨 Id 地址 用户名 我想,这些特定的属性名在序列化或服务模型中的其他地方使用是合理的,这会导致它们的编译方式不同。我想我已经找到了更多
问题是,我得到运行时
xmleexception
s,说“名称不能以“开头,我现在有一个解决办法,但这不是我可以依赖的->导致问题的DTO已从[ServiceKnownType]
发布服务器上删除,这使得错误消失
我想知道问题是否与我得到的例外的成员名称有关。到目前为止,我已经看到它抱怨
Id
地址
用户名
我想,这些特定的属性名在序列化或服务模型中的其他地方使用是合理的,这会导致它们的编译方式不同。我想我已经找到了更多的信息来帮助解释这个问题(至少在某些类型上出现错误的原因方面是这样的) 收到针对其异常报告的DTO包括:
- 作为我的
属性的一部分发布[ServiceKnownType]
- 用
[Serializable]
- 未标记有
[DataContract]
向类型添加
[DataContract]
属性可以解决此问题。我不知道为什么,也不知道为什么这个错误在发生时是间歇性的,但在影响方面是一致的 我也看了这个问题:
这就是我目前发现的。希望有帮助。我今天讨论了这个问题(第一次机会例外,否则没有明显的问题)。在我的例子中,NetDataContractSerializer(NDCS)正在序列化
IFieldData[]
(从)。NDC可以序列化数组,它还可以序列化没有应用[DataContract]
属性的对象。在这种情况下,序列化程序推断出契约–该类型的所有公共读/写属性和字段都被序列化。这里有记录:
因此,在我的例子中,数组中的一个对象对分数(我自己的类)的引用定义如下:
public sealed class Fraction
{
public int Numerator { get; private set; }
public int Denominator { get; private set; }
public double Value { get; private set; }
}
它导致WCF抛出“名称无法开始…”异常,这是由于自动属性使用名为k_ubackingfield
的生成的私有字段造成的。如果将[DataContract]
属性添加到类中,则必须明确标记需要通过[DataMember]
属性序列化的内容。这使得例外消失了。序列化程序不再接触私有字段
在我看来,这是WCF中的一个bug。推断出的契约应该只使用类的公共表面,它没有任何命名问题。它不应该窥探私有字段(不管是否由编译器生成)
我的答案支持/补充了前面所说的内容,我对他们的答案进行了投票。找出问题出在哪个字段的最佳方法是在出现错误时检查StackTrace:
在我的例子中,答案是将auto属性更改为显式声明支持字段,以避免这种命名的可能性。所以
public string ScreenName { get; set; }
变成:
private string _screenName;
public string ScreenName { get { return _screenName; } set { _screenName = value; } }
对于存在此问题的任何其他人:如果在Visual Studio的异常设置中检查了XmlException,则即使异常将在System.Runtime.Serialization中得到处理,它也会抛出。我花了大约20个小时试图弄清楚为什么我的代码在打开所有异常时突然停止工作——这实际上不是一个致命的异常,它只是约1200个被捕获的XmlExceptions。你能发布一个示例DataContract吗?我将尝试将其进一步隔离到问题发生的地方。目前,它已决定再次工作…:-(随着问题再次出现,我用最新版本更新了此问题。我进一步隔离了某些类型被报告为错误的原因…结果可能没有-尝试重命名其中一些字段,并在“MyId”、“BogusAddress”、“UserNameX”中遇到同样的问题。但问题肯定与这些类型有关-它不像某些names在某些类型中,不管名字是什么……!如果它碰巧对其他人有帮助,这是我提出的最好的解决方案,尽管我仍然没有解释,所以我很高兴接受一个更好的答案。非常感谢这个提示;刚才为我节省了很多时间。我的DTO从未标记过[DataContract]
属性,它工作了好几个月。有一天我不得不重新启动它,突然遇到了这个问题。添加该属性立即解决了它。这对我帮助很大。在我的情况下,我的一个基类没有用[DataContract]属性修饰。在添加[DataContract]之后
属性,请确保还标记需要由[DataMember]
属性序列化的内容。否则,不会序列化任何内容,并且对象反序列化为空。
public string ScreenName { get; set; }
private string _screenName;
public string ScreenName { get { return _screenName; } set { _screenName = value; } }