WCF 服务参考 - 在客户端获取“XmlException:名称不能以 '<' 字符开头,十六进制值 0x3C”
Posted
技术标签:
【中文标题】WCF 服务参考 - 在客户端获取“XmlException:名称不能以 \'<\' 字符开头,十六进制值 0x3C”【英文标题】:WCF Service Reference - Getting "XmlException: Name cannot begin with the '<' character, hexadecimal value 0x3C" on Client SideWCF 服务参考 - 在客户端获取“XmlException:名称不能以 '<' 字符开头,十六进制值 0x3C” 【发布时间】:2011-10-21 05:05:00 【问题描述】:我有一个智能客户端应用程序通过 WCF 与其服务器通信。数据在客户端上创建,然后通过服务发送以进行持久化。服务器和客户端通过共享 dll 使用相同的域类,我在 Visual Studio 中使用方便的“添加服务引用”功能,它包装了 SvcUtil.exe 并生成客户端和代理类。
尝试调用服务时出现以下错误:
System.Xml.XmlException occurred
Message=Name cannot begin with the '<' character, hexadecimal value 0x3C.
Source=System.Xml
LineNumber=0
LinePosition=1
StackTrace:
at System.Xml.XmlConvert.VerifyNCName(String name, ExceptionType exceptionType)
InnerException:
这特别麻烦,因为该服务一次可以运行数周而不会发生此错误,然后会突然毫无预警地再次出现。我一直无法弄清楚是什么原因造成的。当它确实发生时,我将深入研究如何修复它,并且通常不会想出比那些在实际尝试以编程方式将事物序列化为 xml 时遇到相同错误的人更多的东西。我只使用生成的客户端和代理来尝试发送这些数据。
我查看了我的解决方案的 Service References\AwesomeService
文件夹中生成的代理,没有发现任何异常。生成的文件中唯一出现的尖括号是:
我用来调用服务的代码是这样的:
using (var client = new AwesomeServiceClient())
client.SaveAwesomeness(instanceOfAwesomeness);
这是从上面列出的调用代码上方的第一帧开始的堆栈:
System.Xml.dll!System.Xml.XmlConvert.VerifyNCName(string name, System.Xml.ExceptionType exceptionType) + 0xb5 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.IsValidNCName(string name) + 0x27 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.EncodeLocalName(string localName) + 0x1d bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ImportDataMembers() + 0x2e1 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type) + 0x10d bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x198 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x57 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerContext.GetDataContract(int id, System.RuntimeTypeHandle typeHandle) + 0x37 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(System.Runtime.Serialization.XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, System.RuntimeTypeHandle declaredTypeHandle) + 0x49 bytes
[Lightweight Function]
System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.WriteXmlValue(System.Runtime.Serialization.XmlWriterDelegator xmlWriter, object obj, System.Runtime.Serialization.XmlObjectSerializerWriteContext context) + 0x25 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlWriterDelegator xmlWriter, object obj, System.RuntimeTypeHandle declaredTypeHandle) + 0x18 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlWriterDelegator xmlWriter, object obj, System.RuntimeTypeHandle declaredTypeHandle) + 0x49 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(System.Runtime.Serialization.XmlWriterDelegator writer, object graph, System.Runtime.Serialization.DataContractResolver dataContractResolver) + 0xdf bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(System.Runtime.Serialization.XmlWriterDelegator writer, object graph, System.Runtime.Serialization.DataContractResolver dataContractResolver) + 0x26 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(System.Runtime.Serialization.XmlWriterDelegator writer, object graph, System.Runtime.Serialization.DataContractResolver dataContractResolver) + 0x60 bytes
System.Runtime.Serialization.dll!System.Runtime.Serialization.XmlObjectSerializer.WriteObject(System.Xml.XmlDictionaryWriter writer, object graph) + 0x2d bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo part, object graph) + 0x38 bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo part, object graph) + 0xbe bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameters(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo[] parts, object[] parameters) + 0x3e bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion version, string action, System.ServiceModel.Description.MessageDescription messageDescription, object returnValue, object[] parameters, bool isRequest) + 0x68 bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion version, object[] parameters, object returnValue, bool isRequest) + 0x7b bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer) + 0x4f bytes
System.ServiceModel.dll!System.ServiceModel.Channels.BodyWriter.WriteBodyContents(System.Xml.XmlDictionaryWriter writer) + 0xf8 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.BodyWriterMessage.OnBodyToString(System.Xml.XmlDictionaryWriter writer) + 0x1f bytes
System.ServiceModel.dll!System.ServiceModel.Channels.Message.ToString(System.Xml.XmlDictionaryWriter writer) + 0xaa bytes
System.ServiceModel.dll!System.ServiceModel.Diagnostics.MessageLogTraceRecord.WriteTo(System.Xml.XmlWriter writer) + 0x166 bytes
System.ServiceModel.dll!System.ServiceModel.Diagnostics.MessageLogger.LogInternal(System.ServiceModel.Diagnostics.MessageLogTraceRecord record) + 0x77 bytes
System.ServiceModel.dll!System.ServiceModel.Diagnostics.MessageLogger.LogMessageImpl(ref System.ServiceModel.Channels.Message message, System.Xml.XmlReader reader, System.ServiceModel.Diagnostics.MessageLoggingSource source) + 0x104 bytes
System.ServiceModel.dll!System.ServiceModel.Diagnostics.MessageLogger.LogMessage(ref System.ServiceModel.Channels.Message message, System.Xml.XmlReader reader, System.ServiceModel.Diagnostics.MessageLoggingSource source) + 0x3a bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.PrepareCall(System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, bool oneway, ref System.ServiceModel.Dispatcher.ProxyRpc rpc) + 0x436 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call(string action, bool oneway, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation, object[] ins, object[] outs, System.TimeSpan timeout) + 0x12b bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage methodCall, System.ServiceModel.Dispatcher.ProxyOperationRuntime operation) + 0x64 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage message) + 0x6a bytes
mscorlib.dll!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref System.Runtime.Remoting.Proxies.MessageData msgData, int type) + 0xee bytes
这是什么原因造成的,我该如何预防?或者,也欢迎,我该如何进一步排除故障?
【问题讨论】:
我认为这与 .Net 序列化域类属性的方式有关。您使用的是 ISerializable 接口,还是 DataContract 属性,或者可能是一些自定义序列化? @edwin 我正在使用 Serializable 属性,但是在检查了整个域图之后,我很尴尬地说有些类缺少该属性。我会试试的。谢谢。 我收到了很多次,最后在这里尝试调试,后来才意识到这是内部捕获的第一次机会异常,对象图将成功序列化/反序列化。可能与您的特定错误无关,但仅适用于将来在调试器中遇到此问题的人(或我自己)! 【参考方案1】:查看您的 DataTables(如果这是您用来传输数据的)。
如果 DataTable 名称为空,则 Serializer 可能会混淆并错误地序列化。
否则,如果您使用的是类型化的 [Serializable] 对象,我发现如果您使用动态属性声明,有时 Serializer 也会感到困惑,例如:
public string MyName get; set;
但这将是一个容易重复的错误。
【讨论】:
我没有使用 DataTables,而只是在整个服务中传送域图。但是,我确实有很多自动属性,所以如果我扩展它们,我会看看序列化程序是如何工作的。 用实例变量替换所有要支持的自动属性为我解决了这个问题。【参考方案2】:就个人而言,我在类层次结构(不是 DataTables)的序列化方面遇到了同样的问题。
我的问题根本与自动属性无关,实际上我有很多。
我的问题是我忘记在我的一个 dll 中包含对“System.Runtime.Serialization
”的引用,并且我还忘记在层次结构中的上层 [DataMember]
属性引用的某些类上添加一些属性 [DataContract]
。
为了跟踪我的问题,我从我的根类开始,并从层次结构中删除了一些[DataMember]
,直到它指出了确切的问题。这可能需要一些时间,具体取决于您的层次结构...
希望对您有所帮助! 埃里克
【讨论】:
这不是答案,因为我没有任何由我创建的 WCF 服务序列化的数据。如果我运行该方法 @JohnWashburn,抱歉耽搁了,我现在才看到你的评论。我不太了解 WCF,但我怀疑它会在发送数据之前序列化数据并在接收时反序列化数据。 在类层次结构中添加属性 [DataContract] 和 [DataMember] 对我有用。【参考方案3】:一个类似的错误让我大吃一惊,但事实证明我的配置文件(实际上是 silverlight 的客户端配置文件)包含以下内容
<<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
所以有时关于额外<
字符的消息应该按字面意思理解!
【讨论】:
刚刚遇到这个问题,我排了很长的队,我看不到它的结尾,而且它缺少 > 所以它可以去任何一种方式。【参考方案4】:要么使用[Serializable]
的完整属性,要么使用[DataContract]
和[DataMember]
。
以下内容给了我一个错误,可能是因为 .Net 在后台创建了一个支持变量,其中包含 XmlSerializer
不喜欢的一些字符。
[Serializable]
public class MyClass
public int MyValue get; private set;
...
要么创建完整的属性
[Serializable]
public class MyClass
int _myValue;
public int MyValue
get return _myValue;
private set _myValue = value;
...
或使用DataContract
和DataMember
属性
[DataContract]
public class MyClass
[DataMember]
public int MyValue get; private set;
...
【讨论】:
【参考方案5】:在我的例子中,其中一个类有一个属性,其数据类型是对象。像这样的:
public class BuyAddOnServiceRequest
object site_id
将其更改为:
public class BuyAddOnServiceRequest
string site_id
成功了!
【讨论】:
【参考方案6】:好的,刚刚遇到了另一个场景。 我有一个 Serializable 类型用作我的 Operation Contract 方法之一的参数。
从使用中注释掉这个特定的方法让我找到了问题。在这种情况下,参数是从文件反序列化的模型,所以我只是将实现替换为 byte[] 参数并在另一端运行反序列化逻辑。
虽然不一定是所有人的答案,但对于可序列化的 Operation Contract 方法上的参数类型,您也可能会遇到此异常。我想用正确的 DataContract 属性装饰它们将有助于纠正这个问题。
【讨论】:
大多数人会发现包含一个 sn-p 代码来支持您的答案很有用。以上是关于WCF 服务参考 - 在客户端获取“XmlException:名称不能以 '<' 字符开头,十六进制值 0x3C”的主要内容,如果未能解决你的问题,请参考以下文章
如何获取 WCF Web 服务请求的 XML SOAP 请求?