2010-09-07 99 views
1

我需要記錄使用ASP.NET Web服務的用戶名。爲此,我創建了一個SoapExtension,它捕獲傳入的Soap信封並將其轉換爲XDocument。問題是我對LINQ to XML一無所知,並且我回顧的例子似乎不適用於SOAP信封。如何從XML獲取用戶名通過LINQ to XML?

的SOAP消息看起來是這樣的:

<?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> 

所有我需要的是用戶名元素的內容。

我想這...

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

...但沒有結果。

當我嘗試使用「wsse:UsernameToken」和「wsse:Username」時,我收到一個異常,說冒號不合法。

有關如何獲取此信息的任何提示?

(我知道我可以很可能只是正則表達式的名字,但如果我需要在未來的某個時刻搶其他數據,那麼這將是更有效的這種方式,我想。)

回答

2

該部分的前面冒號是一個命名空間,知道這個我從類似的問題中找到了這個答案。

Linq to XML with Namespace

+0

幾個人有一個有用的答案,但這是第一個(根據「最古老」的排序),所以它得到了答案。他們都得到+1。 – 2010-09-07 19:20:58

2

你需要創建一個命名空間,並使用它。這是高度直覺,但是這是它如何工作的:

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

...你就必須做到這一點對於有前綴的任何項目。

我想你也可以使用大括號({})周圍的URI的包裝,像這樣:

從項目中xdoc.Descendants( 「{} http://schemas.xmlsoap.org/soap/envelope/的UsernameToken」)

,但我我從來沒有嘗試過。

More details here.

2

它下降到其命名空間的XML元素。您需要將其添加到您的查詢中。我不是在一個點來試試這個,但東西沿着線:

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") 
       }; 

有關命名空間LINQ to XML中的詳細信息:http://msdn.microsoft.com/en-us/library/bb387069.aspx

1

你必須包括在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") 
       };