WCF服务参考 - 获取“XmlException:名称不能以'<'开头客户端的字符,十六进制值0x3C“

时间:2011-08-05 20:58:19

标签: c# .net wcf serialization datacontractserializer

我有一个智能客户端应用程序通过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文件夹中生成的代理,看不到任何与众不同的内容。生成的文件中唯一出现的尖括号是:

  • .svcinfo,Reference.svcmap,AwesomeService.disco,AwesomeService.wsdl和* .xsd文件中的xml标签
  • Reference.cs文件中泛型集合的参数

我用来调用服务的代码是这样的:

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

是什么导致这种情况以及如何预防?或者,也欢迎,我该如何进一步排除故障?

6 个答案:

答案 0 :(得分:16)

查看您的DataTables(如果这是您用来传输数据的那些)。

如果DataTable名称为空,那么Serializer可能会混淆并错误地序列化。

否则,如果您使用的是类型化的[Serializable]对象,我发现如果使用动态属性声明,有时串行器也会混淆,例如:

public string MyName { get; set; }

但这可能是一个容易重复的错误。

答案 1 :(得分:9)

个人而言,我对类层次结构的序列化(而不是DataTables)也遇到了同样的问题。

我的问题根本与自动财产无关,实际上我有很多。 我的问题是我忘记在我的一个dll中包含对“System.Runtime.Serialization”的引用,我也忘了在上部[DataContract]属性引用的某些类上添加一些属性[DataMember]层次结构。

为了跟踪我的问题,我从我的根类开始,在层次结构中删除了一些[DataMember],直到它指出了确切的问题。这可能需要一些时间,具体取决于您的层次结构级别......

希望它有所帮助! 埃里克

答案 2 :(得分:1)

要么对[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; }
    }
    ...
}

或使用DataContractDataMember属性

[DataContract]
public class MyClass
{
    [DataMember]
    public int MyValue { get; private set; }
    ...
}

答案 3 :(得分:0)

在我的例子中,其中一个类有一个属性,其数据类型是object。像这样:

public class BuyAddOnServiceRequest
{
    object site_id
}

将此更改为:

public class BuyAddOnServiceRequest
{
    string site_id
}

有效!

答案 4 :(得分:0)

类似的错误让我失望,但事实证明我的配置文件(实际上是silverlight的clientconfig文件)包含以下内容

   <<security mode="Transport">
       <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
       <message clientCredentialType="Certificate" algorithmSuite="Default" />
   </security>

因此,有时候应该从字面上理解有关额外<字符的消息!

答案 5 :(得分:0)

好的,刚刚遇到了另一个场景。 我有一个Serializable类型用作我的一个Operation Contract方法的参数。

从使用中评论这个特定的方法让我找到了问题。在这种情况下,参数是从文件反序列化的模型,所以我只是用byte []参数替换了实现,并在另一端运行反序列化逻辑。

虽然不一定是所有人的答案,但对于可操作合同方法的可序列化参数类型,您也可能遇到此异常。我想用正确的DataContract属性来装饰它们将有助于纠正这个问题。