使用SOAP请求中的自定义字段实现WSSE安全标头时出现C#运行时错误
我正在尝试将SOAP请求发送到使用WSSE和UsernameToken进行身份validation的Web服务。 示例查询如下(屏蔽机密数据):
abc 123 12345678901
我使用WSE 3.0生成了一个代理类,问题是我收到错误:“对象引用没有设置为对象的实例。” 我的C#代码中有问题的部分如下:
queryNoSorguType q = new queryNoSorguType(); string query_parameter = query_no; q.queryNo = query_parameter; ResultType[] r = new ResultType[10]; UsernameToken token = new UsernameToken("abc", "123",PasswordOption.SendPlainText); //mWebService.SetClientCredential(token); //Policy webServiceClientPolicy = new Policy(); mWebService.RequestSoapContext.Security.Tokens.Add(token); //mWebService.SetPolicy(webServiceClientPolicy); //r = mWebService.documentQuerybyQueryNo(q); System.Data.DataTable outputDataTable = new System.Data.DataTable(); //System.Data.DataRow outRow = outputDataTable.Rows.Add(); //outRow["field1"] = r; output = outputDataTable;
我通过系统地评论我的部分代码找到了有问题的部分。 我对Web服务很不熟悉,C#和我实际上是在Blue Prism中实现它。 尽管此程序可以与SOAP Web服务一起使用,但遗憾的是它本身并不支持SOAP标头。
SOAP请求在SOAP UI中正常工作,Blue Prism中没有编译器错误。 我尝试按照手册和网络上的说明添加标题,但它不起作用。 如果你能指出我正确的方向,我将不胜感激。
编辑编写完成后,在Visual Studio 2017中编译控制台应用程序时出现以下错误。 据我所知,它没有标题的定义。
Unhandled Exception: System.Web.Services.Protocols.SoapHeaderException: MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at WebService.queryByQueryNo(queryNoQueryType queryByQueryNo1) in C:\Users\user\source\repos\ConsoleApp1\ConsoleApp1\Web References\WebService\Reference.cs:line 1533 at ConsoleApp1.Program.Main(String[] args) in C:\Users\user\source\repos\ConsoleApp1\ConsoleApp1\Program.cs:line 33
我认为当您使用时,标准符号是xml结构
abc 123
我决定使用一种不同的方法,并暂时尝试使用代理类,因为存在与之相关的问题。 利用此链接上的答案: 客户端发送SOAP请求并收到响应我在进行一些自定义后想出了自己的解决方案。
但是,我仍然想知道如何使用Visual Studio或WSE 3.0定义的包装类来使其工作。 在编写代码并在Visual Studio中测试之后,很容易将其移植到Blue Prism中。
using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Threading.Tasks; using System.Xml; using System.Net; using System.IO; using System.Xml.Linq; namespace WebService { class Program { /// /// Execute a Soap WebService call /// public static string Execute(string queryNo) { HttpWebRequest request = CreateWebRequest(); XmlDocument soapEnvelopeXml = new XmlDocument(); soapEnvelopeXml.LoadXml(@" USER CODE " + queryNo + @" "); using (Stream stream = request.GetRequestStream()) { soapEnvelopeXml.Save(stream); } using (WebResponse response = request.GetResponse()) { using (StreamReader rd = new StreamReader(response.GetResponseStream())) { string soapResult = rd.ReadToEnd(); Console.WriteLine(soapResult); return soapResult; } } } /// /// Create a soap webrequest to [Url] /// /// public static HttpWebRequest CreateWebRequest() { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"https://webservice.com/webservice?wsdl"); webRequest.Headers.Add(@"SOAP:Action"); webRequest.ContentType = "text/xml;charset=\"utf-8\""; webRequest.Accept = "text/xml"; webRequest.Method = "POST"; return webRequest; } static void Main(string[] args) { if (args.Length == 0 || args.Length > 1) { System.Console.WriteLine("Please provide a query no"); System.Console.WriteLine("Usage: WebService.exe 3523423333"); return; } string output, XMLresponse; try { XMLresponse = Execute(args[0]); output = "Successful query"; XmlDocument xml = new XmlDocument(); xml.LoadXml(XMLresponse); // suppose that str string contains the XML data. You may load XML data from a file too. XmlNodeList resultCodeList = xml.GetElementsByTagName("resultCode"); XmlNodeList resultNoList = xml.GetElementsByTagName("resultNo"); int i = 0; var OutputTable = new DataTable(); OutputTable.Columns.Add("Result Code", typeof(string)); OutputTable.Columns.Add("Result No", typeof(string)); foreach (XmlNode xn in resultCodeList) { Console.WriteLine(resultCodeList[i].InnerText + " " + resultNoList[i].InnerText); OutputTable.Rows.Add(resultCodeList[i].InnerText, resultNoList[i].InnerText); i++; } } catch (System.Net.WebException exc) { Console.WriteLine("HTTP POST request failed!"); output = "!!!HTTP POST request failed!!!"; } } } }