我需要记录使用ASP.NET Web服务的用户名。为此,我创建了一个SoapExtension,它捕获传入的Soap信封并将其转换为XDocument。问题是我对LINQ to XML一无所知,我所评论的例子似乎与SOAP信封无关。
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>user@mycompany.net</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>
我需要的只是Username元素的内容。
我试过了......
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”时,我得到一个异常,说结肠不合法。
有关如何获取此信息的任何提示?
(我知道我可能只是正确的名称,但如果我需要在未来的某个时间点获取其他数据,那么我认为这样会更有效率。)
答案 0 :(得分:2)
冒号前面的部分是一个命名空间,知道这一点,我从类似的问题中找到了这个答案。
答案 1 :(得分: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”)
但我从未尝试过。
答案 2 :(得分: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
答案 3 :(得分: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")
};