2010-09-07 6 views
1

Je dois enregistrer le nom d'un utilisateur qui utilise un service Web ASP.NET. Pour ce faire, j'ai créé une SoapExtension qui capture une enveloppe Soap entrante et la convertit en XDocument. Le problème est que je ne connais rien à LINQ to XML et que les exemples que j'ai examinés ne semblent pas fonctionner avec l'enveloppe SOAP.Comment puis-je récupérer un nom d'utilisateur à partir de XML via LINQ to XML?

Le message SOAP ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
    <soap:Header> 
    <wsa:Action>http://www.company.net/2009/09/17/wriapp/GetConfigInfo</wsa:Action> 
    <wsa:MessageID>urn:uuid:da599d3d-1df5-4460-8987-8ccd75b87cfe</wsa:MessageID> 
    <wsa:ReplyTo><wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo> 
    <wsa:To>urn:Company:Wri:Tracking:1.0</wsa:To> 
    <wsse:Security soap:mustUnderstand="1"> 
     <wsu:Timestamp wsu:Id="Timestamp-efb2ad77-7822-43d9-86d6-0cbfbf0ed262"> 
      <wsu:Created>2010-09-07T13:31:20Z</wsu:Created> 
      <wsu:Expires>2010-09-07T13:36:20Z</wsu:Expires> 
     </wsu:Timestamp> 
     <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-c51f6c78-555b-420c-ba79-402d75f24d5e"> 
     <wsse:Username>[email protected]</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password1</wsse:Password> 
     <wsse:Nonce>xO+f8fJgh8zzxPi6JJMUag==</wsse:Nonce> 
     <wsu:Created>2010-09-07T13:31:20Z</wsu:Created> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </soap:Header> 
    <soap:Body> 
    <GetConfigInfo xmlns="http://www.company.net/2009/09/17/wriapp" /> 
    </soap:Body> 
</soap:Envelope> 

Tout ce que je besoin est le contenu de l'élément Nom d'utilisateur.

J'ai essayé ...

var xdoc = XDocument.Parse(xml, LoadOptions.None); 
var userName = from item in xdoc.Descendants("UsernameToken") 
       select new 
       { 
        UserName = item.Element("UserName") 
       }; 

... mais obtenir aucun résultat. Lorsque j'ai essayé d'utiliser "wsse: UsernameToken" et "wsse: Username", j'obtiens une exception qui dit que les deux points ne sont pas légaux.

Des conseils sur la façon d'obtenir cette information?

(je sais que je peux probablement regex le nom, mais si je dois saisir d'autres données à un moment donné avenir, alors il sera plus efficace de cette façon, je pense.)

Répondre

2

La partie devant la deux points est un espace de noms, sachant que j'ai trouvé cette réponse à partir d'une question similaire.

Linq to XML with Namespace

+0

plusieurs personnes avaient une réponse utile mais c'était la première (selon le "plus ancien" genre) donc il a obtenu la réponse. Tous ont eu +1. –

2

Vous devez créer un espace de noms et utiliser. Il est très contre-intuitif, mais comment cela fonctionne:

XNamespace ns = "http://schemas.xmlsoap.org/soap/envelope/"; 
from item in xdoc.Descendants(ns + "UsernameToken") 
...etc... 

... et vous aurez à faire pour tout élément qui a un préfixe.

Je pense que vous pouvez également utiliser des accolades ({}) comme une enveloppe autour de l'URI, comme ceci:

du produit en xdoc.Descendants ("{} http://schemas.xmlsoap.org/soap/envelope/ UsernameToken")

mais je Je n'ai jamais essayé.

More details here.

2

Il est jusqu'aux espaces de noms pour ces éléments XML. Vous devez ajouter cela à votre requête. Je ne suis pas un point d'essayer cela, mais quelque chose le long des lignes de:

XNamespace wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 

var xdoc = XDocument.Parse(xml, LoadOptions.None); 
var userName = from item in xdoc.Descendants(wsu + "UsernameToken") 
       select new 
       { 
        UserName = item.Element(wsu + "UserName") 
       }; 

Pour plus d'informations sur les espaces de noms dans LINQ to XML: http://msdn.microsoft.com/en-us/library/bb387069.aspx

1

Vous devez inclure tout l'espace de noms dans le LINQ:

XNamespace wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 

var xdoc = XDocument.Parse(xml, LoadOptions.None); 
var userName = from item in xdoc.Descendants(wsse + "UsernameToken") 
       select new 
       { 
        UserName = item.Element(wsse + "UserName") 
       };