Я добавил второй метод в свою службу WCF. По сути, он выполняет ту же работу, что и другой, за исключением того, что он получает XML-документ, десериализует его и вызывает другой метод. Он отлично работает локально, мой XML десериализован, и вызов выполняется успешно. Однако теперь, когда я развернул его на своем локальном сервере, вызов возвращает ошибку 500 из-за сбоя десериализации.
В моем XML-документе есть пространства имен, связанные с каждым узлом, корневым и подкорневым элементом, имеющими префикс «ns1», а все остальные — «ns2». Чтобы выполнить десериализацию, я (по крайней мере, на данный момент) жестко запрограммировал пространства имен для каждого узла.
Укороченный xml-документ:
<ns1:ValiderEtEnrichirGlobalEchangePartage
xmlns:ns1 = "API:WebApi"
xmlns:ns0 = "http://www.ra.fr/API/Transport/"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance">
<ns1:messageGlobal>
<ns0:AuteurEchange>...</ns0:AuteurEchange>
<ns0:Documents>
<ns0:DocumentEchangePartage>...</ns0:DocumentEchangePartage>
</ns0:Documents>
<ns0:ExpediteurEchange>...</ns0:ExpediteurEchange>
</ns1:messageGlobal>
</ns1:ValiderEtEnrichirGlobalEchangePartage>
Процесс десериализации в методе службы:
public GlobalEchangePartageValide ValiderEtEnrichirGlobalEchangePartageXML(string xmlMessageGlobal)
{
XmlRootAttribute xroot = new XmlRootAttribute();
xroot.ElementName = "ValiderEtEnrichirGlobalEchangePartage";
xroot.Namespace = "API:WebApi";
XmlSerializer serializer = new XmlSerializer(typeof(ValiderEtEnrichirGlobalEchangePartage),xroot );
StringReader stringReader = new StringReader(xmlMessageGlobal);
ValiderEtEnrichirGlobalEchangePartage messageGlobal = (ValiderEtEnrichirGlobalEchangePartage)serializer.Deserialize(stringReader);
return ValiderEtEnrichirGlobalEchangePartage(messageGlobal.GlobalEchangePartage);
}
Класс, соответствующий корневому элементу xml:
[XmlRootAttribute("ValiderEtEnrichirGlobalEchangePartage")]
public class ValiderEtEnrichirGlobalEchangePartage
{
[XmlElement(ElementName=("messageGlobal"))]
public GlobalEchangePartage GlobalEchangePartage { get; set; }
}
Класс подкорневого элемента xml:
[DataContract(Namespace = NamespacesConstantes.NAMESPACE_TRANSPORT)]
public class GlobalEchangePartage
{
[DataMember]
[XmlElement(ElementName = ("AuteurEchange"), Namespace = "http://www.ra.fr/API/Transport/")]
public Auteur AuteurEchange { get; set; }
[DataMember]
[XmlElement(ElementName = ("ExpediteurEchange"), Namespace = "http://www.ra.fr/API/Transport/")]
public Auteur ExpediteurEchange { get; set; }
[DataMember]
[XmlArray(ElementName = "Documents", Namespace = "http://www.ra.fr/API/Transport/")]
[XmlArrayItem("DocumentEchangePartage")]
public List<DocumentEchangePartage> Documents { get; set; }
}
Ошибка, которую я получаю, на французском языке очень неоднозначна, но ее можно приблизительно перевести следующим образом:
WCF error : System.ServiceModel.Dispatcher.NetDispatcherFaultException: The formatting module generated an exception when trying to deserialize the
message: an error occurred when trying to deserialize the
API:WebApi:xmlMessageGlobal parameter. The InnerException message was 'An
error occurred when deserializing the System.String object. Ending (TN :
last /final ) element 'xmlMessageGlobal' from the namespace 'API:WebApi'
expected. Found element 'ns1:ValiderEtEnrichirGlobalEchangePartage' from the
namespace "API:WebApi'.
Оригинал:
WCF error : System.ServiceModel.Dispatcher.NetDispatcherFaultException: Le
module de formatage a généré une exception en tentant de désérialiser le
message : Une erreur s'est produite en tentant de désérialiser le paramètre
API:WebApi:xmlMessageGlobal. Le message InnerException était 'Une
erreur s'est produite lors de la désérialisation de l'objet de type
System.String. Élément de fin 'xmlMessageGlobal' provenant de l'espace de
noms 'API:WebApi' attendu. Trouvé élément
'ns1:ValiderEtEnrichirGlobalEchangePartage' provenant de l'espace de noms
'API:WebApi'.'.
Обратите внимание, что в XML-документе ожидается «xmlMessageGlobal», хотя это имя переменной...
Большое спасибо (за прочтение)!
PS: Если бы сообщение об ошибке на французском языке можно было поместить во что-то, что его рушит, я был бы признателен, я не нашел способа сделать это.
Я поменял спасибо! (ничего не меняет)
Проверьте заголовки кодировки в веб-запросе.
@AEonAX Веб-запрос выполняется через Microsoft Azure Logic Apps, и я полагал, что он отправляет все в UTF-8. Я не уверен, что могу проверить заголовки запроса.
Ну, локальные и развернутые различия очень странные. Мы говорим об одном и том же коде, верно? Остаются ОС (версия), настройки культуры, другие конфигурации... WCF использует Web.Config в разных местах. И Machine.config .
Возникшая проблема действительно была проблемой десериализации. Однако дело было не в написанном мной фрагменте кода, а в момент получения строкового параметра. Поскольку мой XML-документ был заключен в другой XML-документ (запрос), при обработке возникли проблемы. С помощью base64, кодирующего мой XML в моем приложении логики и декодирующего его в сервисе, я смог решить проблему десериализации.
TLDR: будьте осторожны при отправке xml через параметр String.
Почему у вас есть [XmlRoot] на GlobalEchangePartage? Это кажется как минимум лишним.