“Préfixe d'espace de noms non définie” lorsque c'est réellement défini
Je vais avoir de la difficulté à désérialisation XML avec un "undefined" préfixe d'espace de noms, ce qui est vraiment défini.
Nous avons publié un interne du service web en C# qui sert une variété de clients. Un nouveau client, l'IDE insiste sur le fait de déclarer xsi:type pour chaque élément XML de sortie, et ils ne peuvent pas désactiver cette "fonctionnalité".
Le message XML ils produisent va comme cela, "espace de noms" est l'espace de noms correct.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<myOperation xsi:type="ns1:namespace" xmlns="namespace" xmlns:ns1="namespace">
<inputString xsi:type="xsd:string">ABCDEF</inputString>
<books xsi:type="ns1:booksType">
<bookID xsi:type="xsd:string">ABC123</bookID>
<bookID xsi:type="xsd:string">DEF456</bookID>
</books>
<!-- ... snip... -->
</myOperation>
</soapenv:Body>
<books>
est, fondamentalement, un tableau de chaînes de caractères.
La méthode de service accepte comme XmlNode, mais XmlSerializer lance un "préfixe" ns1 "non défini erreur". (Elle est définie dans un nœud parent, mais apparemment ce n'est pas assez bon.) J'ai un problème similaire à l'aide de wsdl.exe pour générer des classes et désérialiser les données d'entrée pour moi.
À l'aide de XmlNamespaceManager pour spécifier les préfixes ne semble pas juste, sorte de numéros de magie, et je ne peux pas prédire que le préfixe d'un consommateur se déclarer de toute façon. Est-il un moyen de gérer cela sans enlever les attributs de sortir (des livres.Les attributs.RemoveAll)? Qui ne se sentent pas particulièrement élégant non plus.
J'ai trouvé que les livres.OuterXML ne contient pas toute l'information pour " ns1 "à moins que je bidouille l'élément entrant à l'utilisation du préfixe (), donc je peux voir pourquoi il se plaint, mais je n'ai pas encore de comprendre pourquoi" ns1 " n'est pas reconnu par rapport à la définition ci-dessus.
Merci beaucoup pour toute aide, ou au moins de l'éducation, quelqu'un peut fournir.
Modifications: il fonctionne très bien si je change <books>
à utiliser le préfixe, c'est à dire <ns1:books xsi:type="ns1:booksType">
. Cela fonctionne si j'ai défini xmlns ou pas. Qui peut être compatible avec la cette réponse, mais je ne vois pas comment je pourrais procéder à déclarer le préfixe dans le code de service.
@Chris, certainement. J'espère que je peux trouver un équilibre entre "avares de " closed source" et "utilisable pour ceux qui voudraient de l'aide". Ici, les "livres" est le XmlNode reçu dans le service paramètre de méthode. (À ne pas m'éloigner du sujet, mais aussi humblement prendre des suggestions pour l'améliorer en général; je suis encore un novice.)
XmlSerializer xmlSerializer = new XmlSerializer(typeof(booksType));
StringReader xmlDataReader = new StringReader(books.OuterXml);
books = (booksType)xmlSerializer.Deserialize(xmlDataReader);
La classe est à peu près ceci:
[Serializable()]
[XmlRoot("books", Namespace = "namespace")]
[XmlTypeAttribute(TypeName = "booksType", Namespace = "namespace")]
public class booksType
{
[XmlElement(ElementName = "bookID")]
public string[] bookIDs { get; set; }
}
- Certains DOM implémentations ne semble pas possible de traiter avec le même espace de noms URI être lié à deux reprises. Faut-il encore se plaindre si vous vous retirez xmlns="espace de noms"?
- c'est une suggestion intéressante. Pas un problème que j'ai vu avant. Qui DOM implémentations avez-vous vu que avec?
- Il fonctionne (avec xmlns défini) si j'utilise le préfixe dans le <livres> élément<ns1:livres...>). Si j'ai des nations unies défini xmlns, je dois mettre le préfixe, donc qui ne fonctionne pas. Je soupçonne que c'est plus parce que j'ai utilisé le préfixe dans les livres de l'élément.
- S'il vous plaît pourriez-vous nous montrer le code de faire la désérialisation, et le type de la désérialisation d'? Je n'ai pas de problème de désérialisation de votre instance XML exactement comme il est, à l'aide je pense à ce que le type ressemble.
- bien sûr, mis à jour à la question principale, voir la partie inférieure.
- Merci de poster l'exception complète. Je suis curieux de voir qui de ligne et de caractère, c'est de se plaindre. Assurez-vous d'inclure toutes les exceptions internes ainsi.
Vous devez vous connecter pour publier un commentaire.
Votre désérialisation code pourrait ressembler à quelque chose comme ceci:
[EDIT] C'est mieux, parce que les déclarations d'espace de noms sont conservés avec le XmlNode, tandis que la conversion d'une chaîne de caractères XML via OuterXml semble tranche de la déclaration d'espace de noms pour la protéine ns1 préfixe, et le sérialiseur puis barfs sur la valeur de l'attribut type contenant ce préfixe. J'imagine que c'est un bug dans le fichier XML de mise en œuvre, mais peut-être un XML gourou peut le confirmer.
Cela devrait vous obtenez delà de l'erreur que vous voyez, mais s'il permet de résoudre complètement le problème, je ne suis pas sûr.
[MODIFIER] Comme l'a souligné dans les commentaires ci-dessous, il y a un bug dans le .NET XmlSerializer qui est à l'origine de la désérialisation à l'échec. Pas à pas dans le code de la désérialisation dans l'assembly généré, il ya un point où la condition suivante est testée:
Bien que le
Namespace
propriété de laXmlQualifiedName
a la même valeur ('espace de noms') comme la variable de chaîneid2_namespace
, la condition est d'évaluer à faux car il est codé en tant qu'identité de l'objet de test plutôt que d'un test pour la chaîne de valeur de l'équivalence. À défaut de cette condition conduit directement à l'exception signalée par l'OP.Aussi loin que je peux voir, ce bug sera toujours à cause de la désérialisation d'échouer à chaque fois que le XML de l'objet désérialisé utilise un préfixe de l'objet nom de l'élément racine, et un autre préfixe (défini comme le même espace de noms) sur cet élément de l'attribut xsi:type.