Справка службы WCF - Получение "XmlException: имя не может начинаться с символа" < ", шестнадцатеричного значения 0x3C" на стороне клиента
У меня есть смарт-клиентское приложение, взаимодействующее с его сервером через 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
моего решения и не вижу ничего, что выглядит обычным. Единственными вхождениями угловых скобок в сгенерированных файлах являются:
- xml теги в файлах *.svcinfo, Reference.svcmap, AwesomeService.disco, AwesomeService.wsdl и *.xsd
- для общих коллекций в файле 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
Что вызывает это и как его предотвратить? Или также приветствуется, как я могу продолжить поиск и устранение неполадок?
Ответы
Ответ 1
Посмотрите на свои таблицы данных (если это то, что вы используете для транспортировки данных).
Если имя DataTable пуст, то Сериализатор может запутаться и неправильно выполнить сериализацию.
В противном случае, если вы используете типизированные объекты [Serializable], я обнаружил, что иногда Serializer также запутывается, если вы используете объявления динамических свойств, например:
public string MyName { get; set; }
Но это будет легко повторяемая ошибка.
Ответ 2
Лично я столкнулся с проблемой сериализации иерархии классов (не DataTables).
Моя проблема не была связана с автоматическим свойством вообще, на самом деле у меня их много.
Моя проблема заключалась в том, что я забыл включить ссылку на "System.Runtime.Serialization
" в одной из моих dll, и я также забыл добавить некоторые атрибуты [DataContract]
в некоторых классах, на которые ссылаются верхние атрибуты [DataMember]
в иерархии.
Чтобы отслеживать мою проблему, я начал с моего корневого класса и удалил несколько [DataMember]
вниз по иерархии, пока не указал точную проблему. Это может занять несколько раз в зависимости от уровня вашей иерархии...
Надеюсь, это поможет!
Эрик
Ответ 3
В моем случае один из классов имел свойство, чей тип данных был объектом. Что-то вроде этого:
public class BuyAddOnServiceRequest
{
object site_id
}
после изменения этого значения:
public class BuyAddOnServiceRequest
{
string site_id
}
это сработало!
Ответ 4
Схожая ошибка сработала, но оказалось, что мой конфигурационный файл (на самом деле файл clientconfig для silverlight) содержит следующие
<<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
Поэтому иногда сообщения о дополнительных символах <
должны быть взяты буквально!