c# - serializacion - Referencia de servicio WCF-Obtención de "XmlException: El nombre no puede comenzar con el carácter ''<'', valor hexadecimal 0x3C" en el lado del cliente
serialize and deserialize c# (5)
Tengo una aplicación de cliente inteligente que se comunica con su servidor a través de WCF. Los datos se crean en el cliente y luego se envían a través del servicio para que se conserven. El servidor y el cliente utilizan las mismas clases de dominio a través de un dll compartido y estoy usando la útil funcionalidad "Agregar referencia de servicio" en Visual Studio que envuelve SvcUtil.exe y genera las clases de cliente y proxy.
Recibo el siguiente error al intentar llamar al servicio:
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:
Esto es particularmente problemático porque el servicio funcionará durante semanas sin que se produzca este error y, de repente y sin previo aviso, volverá a aparecer. No he podido averiguar qué lo causa en absoluto. Cuando suceda, haré una profunda inmersión en la investigación de cómo solucionarlo y, por lo general, no encontraré nada más que personas que hayan experimentado el mismo error al tratar de serializar cosas a XML mediante programación. No estoy usando nada más que el cliente generado y los proxies para intentar enviar estos datos.
He examinado los proxies generados en la carpeta Service References/AwesomeService
de mi solución y no veo nada que se vea fuera de lo común. Las únicas apariciones de corchetes angulares en los archivos generados son:
- Etiquetas xml en los archivos * .svcinfo, Reference.svcmap, AwesomeService.disco, AwesomeService.wsdl y * .xsd
- argumentos a colecciones genéricas en el archivo Reference.cs
El código que estoy usando para llamar al servicio es tal:
using (var client = new AwesomeServiceClient())
{
client.SaveAwesomeness(instanceOfAwesomeness);
}
Esta es la pila que comienza con el primer fotograma arriba del código de llamada listado arriba:
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
¿Qué causa esto y cómo lo evito? O, también, bienvenido, ¿cómo puedo continuar con la solución de problemas?
Eche un vistazo a sus DataTables (si eso es lo que está utilizando para transportar datos).
Si el nombre de DataTable está vacío, el serializador puede confundirse y serializar cosas incorrectamente.
De lo contrario, si está utilizando objetos escritos, [Serializables], he encontrado que a veces el serializador también se confunde si utiliza declaraciones de propiedades dinámicas, por ejemplo:
public string MyName { get; set; }
Pero este sería un error fácilmente repetible.
En mi caso, una de las clases tenía una propiedad, cuyo tipo de datos era un objeto. Algo como esto:
public class BuyAddOnServiceRequest
{
object site_id
}
después de cambiar esto a:
public class BuyAddOnServiceRequest
{
string site_id
}
¡funcionó!
Ok, encontré otro escenario en este caso. Tenía un tipo serializable utilizado como parámetro para uno de mis métodos de contrato de operación.
Comentando este método específico desde el uso me permitió encontrar el problema. En este caso, el parámetro era un modelo deserializado de un archivo, así que simplemente reemplacé la implementación con un parámetro de byte [] y ejecuté la lógica de deserialización en el otro extremo.
Si bien no es necesariamente una respuesta para todos, en el caso de los tipos de parámetros en sus métodos de Contrato de Operación que son Serializables, también puede encontrarse con esta excepción. Imagino que decorarlos con los atributos correctos de DataContract ayudaría a rectificar este problema.
Personnally, tengo el mismo problema con la serialización de la jerarquía de clases (no DataTables).
Mi problema no estaba relacionado con la propiedad automática en absoluto, de hecho tengo muchos. Mi problema era que olvidé incluir una referencia a " System.Runtime.Serialization
" en uno de mis dll y también me olvidé de agregar algunos atributos [DataContract]
en algunas clases a las que hacen referencia los atributos superiores de [DataMember]
en la jerarquía.
Para rastrear mi problema, comencé desde mi clase raíz y [DataMember]
un [DataMember]
en la jerarquía hasta que me indicó el problema exacto. Podría tomar algunas veces según los niveles jerárquicos ...
¡Espero eso ayude! Eric
Un error similar me disparó, pero resultó que mi archivo de configuración (en realidad un archivo clientconfig para Silverlight) contenía lo siguiente
<<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
¡Así que a veces los mensajes sobre caracteres adicionales deben tomarse literalmente!