How can I add a SOAP authentication header with HTTPRequestMessage? - c#

Here is what the header is supposed to look like
<soap:Header>
<AuthenticationHeader>
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
Here is what I've tried:
string username = "TheUserName";
string password = "ThePassword";
HttpRequestMessage requestMessage = new HttpRequestMessage(method, uri);
requestMessage.Headers.Add("UserName", username);
requestMessage.Headers.Add("Password", password);
Maybe I have to somehow set the authorization header?
requestMessage.Headers.Authorization = ??
I feel like somehow I have to "build" that AuthenticationHeader element but I'm not sure how to do that. Any suggestions?
Edit: Full SOAP Envelope
?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationHeader xmlns="http://www.test.com/testing/Security">
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
<soap:Body>
<GetMeSomething xmlns="http://www.test.com/testing/WorkFileCatalog">
<Param1>string</Param1>
<Param2>string</Param2>
<XMLRetMess>string</XMLRetMess>
</GetMeSomething>
</soap:Body>
</soap:Envelope>

Given the provided OP, the following Unit Test was done as a proof of concept of how you can populate the header message header and create a request.
[TestClass]
public class SOAP_UnitTests {
private HttpMethod method;
private string uri;
private string action;
[TestMethod]
public void _Add_SOAP_Auth_Header_Details_With_HttpRequestMessage() {
string username = "TheUserName";
string password = "ThePassword";
var xml = ConstructSoapEnvelope();
var doc = XDocument.Parse(xml);
var authHeader = doc.Descendants("{http://www.test.com/testing/Security}AuthenticationHeader").FirstOrDefault();
if (authHeader != null) {
authHeader.Element(authHeader.GetDefaultNamespace() + "UserName").Value = username;
authHeader.Element(authHeader.GetDefaultNamespace() + "Password").Value = password;
}
string envelope = doc.ToString();
var request = CreateRequest(method, uri, action, doc);
request.Content = new StringContent(envelope, Encoding.UTF8, "text/xml");
//request is now ready to be sent via HttpClient
//client.SendAsync(request);
}
private static HttpRequestMessage CreateRequest(HttpMethod method, string url, string action, XDocument soapEnvelopeXml) {
var request = new HttpRequestMessage(method: method, requestUri: url);
request.Headers.Add("SOAPAction", action);
request.Headers.Add("ContentType", "text/xml;charset=\"utf-8\"");
request.Headers.Add("Accept", "text/xml");
request.Content = new StringContent(soapEnvelopeXml.ToString(), Encoding.UTF8, "text/xml"); ;
return request;
}
private string ConstructSoapEnvelope() {
var message = #"<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<soap:Header>
<AuthenticationHeader xmlns='http://www.test.com/testing/Security'>
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
<soap:Body>
<GetMeSomething xmlns='http://www.test.com/testing/WorkFileCatalog'>
<Param1>string</Param1>
<Param2>string</Param2>
<XMLRetMess>string</XMLRetMess>
</GetMeSomething>
</soap:Body>
</soap:Envelope>
";
return message;
}
}

If you are using HttpClient to POST a request, then you should build the full XML request.
In other words, you would build the exact Soap XML including all the elements
string requestXml = your actual full soap xml
string result = HttpClient.Post ( your actual xml )

Related

LoadXML Add Parameters

I'm doing LoadXML, but I need to add a field from the form but I couldn't,
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>TXBHesKodu.Text</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
I need to add the TXBHESKodu.Text from the form to the <HesKodu> field here.
I think I couldn't make the upper quotation marks added into the file.
Can you show me how to do it?
Here are two ways you could do that. The first being the simplest. Just use string formatting like this (note the $ sign before your # sign):
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
The second method uses the XML Dom to add the text into the element. We find the element using the XPath syntax:
var xmlDocument = GetXmlDocument(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu></HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
XmlNode HesKodu = xmlDocument.SelectSingleNode("//Servis5001/HesKodu");
HesKodu.InnerText = TXBHesKodu.Text;
You would be better off letting Visual Studio handle all the SOAP stuff for you. Take a look at adding a reference to a SOAP Web Service Reference (right click on project and Add => Web Service Reference). You can simply enter the url with ?wsdl at the end and it will generate everything you need to consume the web service.
You can use the url in a webbrowser too. If you have access to the service you can simply enter the url in the addressbar and press Enter. It should give you a description of the service and how to consume it.
Method Usage Error When I Want to Add TXT HesKodu.Text
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
SOAP Whatever I Use My Blog Is All The Code Is As Below, Maybe If You Want To See It
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace TOBBHesKoduSorgulama
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void BTNSorgula_Click(object sender, EventArgs e)
{
var _url = "https://kpsoda.tobb.org.tr/hesservis.php?wsdl";
var _action = "https://kpsoda.tobb.org.tr/hesservis.php?op=Servis5001";
var result = "";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
result = soapResult;
Console.Write(soapResult);
}
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
}
}
I also tried the Service References Process But I Didn't Know How To Request
string Kodu = "Kodu";
string Sifre = "Sifre";
string HesKodu = "HesKodu";
TOBBHesKoduSorgulamaServices.Servis5001Request S5001R = new TOBBHesKoduSorgulamaServices.Servis5001Request();
S5001R.Kodu = Kodu;
S5001R.Sifre = Sifre;
S5001R.HesKodu = HesKodu;
TOBBHesKoduSorgulamaServices.Servis5001Response S5001Response = ?
Which One Is Right For Me?
Waiting for your support, good work ...

How to pass XML input to API call using C#

I have below XML input. I need to call API and pass this as input but values will change dynamically. How can I build this input structure?
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Test xmlns="http://tempuri.org/">
<acc>test</acc>
<pass>abc</pass>
<xmlInvData>
<![CDATA[
<MyData>
<name>test</name>
<number>900</number>
</MyData>
]]>
</xmlInvData>
<username>test</username>
<password>123</password>
</Test>
</soap:Body>
</soap:Envelope>
I have MyData Class in C# which can be useful to setup name and number values.
But how can I form a complete structure and pass to Api call? soap:Envelop and soap body?
HttpClient httpClient = new HttpClient();
string requestUri = "https://testurl";
var byteArray = Encoding.ASCII.GetBytes("username:password");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpResponseMessage response = await httpClient.PostAsync(requestUri, httpContent);
I need to understand how to form httpContent as above my input json.
Assuming you've built the data structure and serialized it to a string called xml:
var httpContent = new StringContent(xml, Encoding.UTF8, "application/xml");

How to pass xml data as content to HttpClient in c#

my c# code to call webservice -
var content = new StringContent(req.Body.ToString(), Encoding.UTF8, "application/xml"); ;
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://mydemo.com/service.asmx?pk=listCustomer");
var byteArray = Encoding.ASCII.GetBytes("username:password");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
request.Content = content;
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
HttpResponseMessage response = await httpClient.SendAsync(request);
// getting 500 error in response data at root level invalid
in postman i call this azure function to pass xml input.
xml input format is -
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<listCustomer xmlns="http://tempuri.org/">
<id>KH001</id>
<fromDate>01/01/2018</fromDate>
<toDate>01/01/2020</toDate>
</listCustomer>
</soap:Body>
</soap:Envelope>
I test function on the local with postman, below is my code. Maybe you could have a try.
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
return new ContentResult { Content = requestBody, ContentType = "application/xml" };
}
And the content type would be right.

Connecting To Web Services through Xamarin

I am new to Xamarin and am trying to connect to my client web services whose address is http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?op=GetUserLogin. This is used to authenticate logins. The code that I have used is below.
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?WSDL");
string wUser = "XXXXX";
string wPassword = "xxxxxxxx";
string soapstr = string.Format(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<GetUserLogin xmlns=""http://tempuri.org/"">
<userName>{0}</userName>
<password>{1}</password>
</GetUserLogin>
</soap:Body>
</soap:Envelope>", wUser, wPassword);
var response = httpClient.PostAsync("http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?WSDL", new StringContent(soapstr, Encoding.UTF8, "text/xml")).Result;
var content = response.Content.ReadAsStringAsync().Result;
Unfortunately, the response that I get is:
<?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"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Server did not recognize the value of HTTP Header SOAPAction: http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx.</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
Any help would be appreciated,
Thanks

Consume Web Service with soap:mustUnderstand attribute

This is my sample Code for Web service. I'm new to SOAP application if someone can spot any problem here it's much appreciated. This error only happened if mustUnderstand attribute ="1"
[WebService(Namespace = "http://www.xxxx.co.uk/Integration/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class ADNHeaderContact : System.Web.Services.WebService
{
public MyHeader myHeader;
[WebMethod]
[SoapHeader("myHeader")]
public string HelloWorld()
{
XmlDocument xmlSoapRequest = new XmlDocument();
using (Stream receiveStream = HttpContext.Current.Request.InputStream)
{
receiveStream.Position = 0;
using (StreamReader readStream =
new StreamReader(receiveStream, Encoding.UTF8))
{
xmlSoapRequest.Load(readStream);
}
}
using (XmlBreaker readxml = new XmlBreaker())
{
using (ReponseSaveApplications respose = new ReponseSaveApplications())
{
return ("Hello");
}
};
}
}
My Postman post request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<MyHeader soap:mustUnderstand="true" xmlns="http:www.xxxx.co.uk/Integration/">
<MyValue>string</MyValue>
</MyHeader>
</soap:Header
<soap:Body>
<HelloWorld xmlns="http://www.xxxx.co.uk/Integration/" />
</soap:Body>
</soap:Envelope>
My Postman post response
<?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">
<soap:Body>
<soap:Fault>
<faultcode>soap:MustUnderstand</faultcode>
<faultstring>System.Web.Services.Protocols.SoapHeaderException: SOAP header MyHeader was not understood.
at System.Web.Services.Protocols.SoapHeaderHandling.SetHeaderMembers(SoapHeaderCollection headers, Object target, SoapHeaderMapping[] mappings, SoapHeaderDirection direction, Boolean client)
at System.Web.Services.Protocols.SoapServerProtocol.CreateServerInstance()
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
SoapHeader.MustUnderstand Property
When an XML Web service client adds a SOAP header to an XML Web
service method call with the MustUnderstand property set to true, the
XML Web service method must set the DidUnderstand property to true;
otherwise, a SoapHeaderException is thrown back to the XML Web service
client by ASP.NET.

Categories

Resources