I'm transferring soap message to my web service using C# .Net2
the soap message is:
<?xml version="1.0"?>
<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>
<AUTHHEADER xmlns="http://mysite.com/WebServices/Agent">
<AgentGUID>24563532-c973-fbf3-d072-d9cf671d5905</AgentGUID>
</AUTHHEADER>
</soap:Header>
<soap:Body>
<LoginRSA xmlns="http://mysite.com/WebServices/Agent">
<loginId>admin#dt.com</loginId>
<password>password</password>
<tenant></tenant>
</LoginRSA>
</soap:Body>
</soap:Envelope>
in my C# section I defined the following:
public class AuthHeader : SoapHeader
{
public string AgentGUID;
}
[WebService(Namespace = "http://mysite.com/WebServices/Agent", Description = "Some description")]
public class AgentService : WebService
{
public AuthHeader Authentication;
[SoapHeader("Authentication")]
[WebMethod(Description = "SomeDesc.", MessageName = "LoginRSA")]
public LoginResult LoginRSA(string loginId, string password, string tenant)
{
if (Authentication != null)
{
string guid = Authentication.AgentGUID;
}
}
}
but my Authentication always null, I can't read the header but I getting all variables that are inside the soap:body.
Can you see my mistake?
thanks.
Related
I'm trying to make a call to a webservice and want to manually add the ws-security headers into the request because .net core 2.2 currently does not support ws-security.
I have created my custom security header class:
public class SoapSecurityHeader : MessageHeader
{
private readonly string _password, _username;
public SoapSecurityHeader(string id, string username, string password)
{
_password = password;
_username = username;
}
public override bool MustUnderstand => true;
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement("wsse", Name, Namespace);
writer.WriteAttributeString("s", "mustUnderstand", "http://schemas.xmlsoap.org/soap/envelope/", "1");
writer.WriteXmlnsAttribute("wsse", Namespace);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement("wsse", "UsernameToken", Namespace);
writer.WriteAttributeString("wsu", "Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "UsernameToken-32");
// Username
writer.WriteStartElement("wsse", "Username", Namespace);
writer.WriteValue(_username);
writer.WriteEndElement();
// Password
writer.WriteStartElement("wsse", "Password", Namespace);
writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
writer.WriteValue(_password);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
And this is my method calling the SOAP service:
public ActionResult<Ted_Result> Get(DateTime dateFrom, DateTime dateTo, int? pageFrom, int? pageTo)
{
BasicHttpBinding basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
EndpointAddress endpointAddress = new EndpointAddress(new Uri("https://localhost/SomeService.svc"));
ChannelFactory<IConnectPublicService> factory = new ChannelFactory<IConnectPublicService>(basicHttpBinding, endpointAddress);
GetContractNoticesResponseMessage result = null;
// Bypass SSL/TLS secure channel validation
#if DEBUG
factory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
{
CertificateValidationMode = X509CertificateValidationMode.None,
RevocationMode = X509RevocationMode.NoCheck
};
#endif
// Debugging inspector
factory.Endpoint.EndpointBehaviors.Add(new InspectorBehavior());
IConnectPublicService serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var soapSecurityHeader = new SoapSecurityHeader("UsernameToken-32", "sampleUsername", "samplePassword123");
// Adding the security header
opContext.OutgoingMessageHeaders.Add(soapSecurityHeader);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
var info = new ExternalIntegrationRequestMessageInfo
{
UserCode = "1000249",
CompanyCode = "200000040"
};
var request = new GetContractNoticesRequestMessage
{
Info = info,
DateFrom = dateFrom,
DateTo = dateTo,
PageFrom = pageFrom,
PageTo = pageTo
};
result = serviceProxy.GetContractNoticesAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
return Ok(result);
}
If I put a breakpoint inside the inspector at BeforeSendRequest I can see that the security header is added to the request:
<wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-32" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>sampleUsername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">samplePassword123</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
And putting a breakpoint inside the inspector at AfterReceiveReply, I get the CORRECT result, but I still get an exception.
The result:
<...>
<s:Header>
<...>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2019-01-11T19:42:53.606Z</u:Created>
<u:Expires>2019-01-11T19:47:53.606Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<GetContractNoticesResponseMessage>
<ContractNotices>....</ContractNotices>
</GetContractNoticesResponseMessage>
</s:Body>
The exception:
An unhandled exception occurred while processing the request.
ProtocolException: The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.
Why do I still get an exception after calling the webservice successfully?
For .net core 2.2 you need to pass Security header manually. You'll need to-do some workarounds - WCF isn't fully implemented yet in .Net Core (has been stated by project contributors). Assuming the requirements aren't too complex, you should be able to get something going without too much headache.
public class SecurityHeader : MessageHeader
{
public UsernameToken UsernameToken { get; set; }
public override string Name => "Security";
public override string Namespace => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
public override bool MustUnderstand => true;
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
serializer.Serialize(writer, this.UsernameToken);
}
}
[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
[XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
public string Id { get; set; }
[XmlElement]
public string Username { get; set; }
}
Add below code in BeforeSendRequest method
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var soapSecurityHeader = new SecurityHeader()
{
UsernameToken = new UsernameToken()
{
Username = "User Name"
}
};
request.Headers.Add(soapSecurityHeader);
}
I did some digging and in the AfterReceiveReply you could do this:
public void AfterReceiveReply(ref Message reply, object correlationState)
{
var security = reply.Headers.Where(w => w.Namespace == "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd").First();
reply.Headers.UnderstoodHeaders.Add(security);
}
I suppose that in this step you could also check the value of the timestamp, if DateTime.UtcNow is in range and act upon that...?
Hi guys i'm new to soap and we started working with some service that make post calls to my asmx with xml.
inside my project in asmx file i need to build the model that i receive from them. so i have the xml:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Exit xmlns="http://tempuri.org/">
<UserName>daniel#xxx.com</UserName>
<Password>123456</Password>
<parkingLotId>21</parkingLotId>
<gateNumber>EX 41</gateNumber>
<ticketNumber>123123123123123123123</ticketNumber>
<plateNumber>12211221</plateNumber>
<paymentSum>10.0</paymentSum>
<ExitDateTime>2018-12-23T09:56:10</ExitDateTime>
<referenceId>987462187346238746263</referenceId>
</Exit>
</s:Body>
</s:Envelope>
when i paste this xml in visual studio Edit -> Special Pase -> Paste XML As Class it builds the model for me with xml attributes like:
[XmlRoot(ElementName = "Exit", Namespace = "http://tempuri.org/")]
public class Exit
{
[XmlElement(ElementName = "UserName", Namespace = "http://tempuri.org/")]
public string UserName { get; set; }
....
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "Exit", Namespace = "http://tempuri.org/")]
public Exit Exit { get; set; }
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "s", Namespace = "http://www.w3.org/2000/xmlns/")]
public string S { get; set; }
}
but! i get error every time i do POST request with this data:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Xml.XmlException: Root element is missing.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read()
at System.Xml.XmlReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
--- End of inner exception stack trace ---</soap:Text>
</soap:Reason>
<soap:Detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
and this is my code:
[WebMethod]
public string Exit()
{
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); }
}
var password = xmlSoapRequest?.GetElementsByTagName("Password")?.Item(0)?.FirstChild?.Value;
var userName = xmlSoapRequest?.GetElementsByTagName("UserName")?.Item(0)?.FirstChild?.Value;
var parkingLotId = xmlSoapRequest?.GetElementsByTagName("parking_lot_Id")?.Item(0)?.FirstChild?.Value;
var gateNumber = xmlSoapRequest?.GetElementsByTagName("gateNumber")?.Item(0)?.FirstChild?.Value;
var plateNumber = xmlSoapRequest?.GetElementsByTagName("plateNumber")?.Item(0)?.FirstChild?.Value;
var paymentSum = xmlSoapRequest?.GetElementsByTagName("paymentSum")?.Item(0)?.FirstChild?.Value;
var exitDateTime = xmlSoapRequest?.GetElementsByTagName("ExitDateTime")?.Item(0)?.FirstChild?.Value;
var referenceId = xmlSoapRequest?.GetElementsByTagName("referenceId")?.Item(0)?.FirstChild?.Value;
var exitParking = new Exit
{
ExitDateTime = Convert.ToDateTime(exitDateTime),
gateNumber = gateNumber,
parkingLotId = Convert.ToByte(parkingLotId),
Password = Convert.ToUInt32(password),
paymentSum = Convert.ToDecimal(paymentSum),
plateNumber = Convert.ToUInt32(plateNumber),
referenceId = referenceId,
UserName = userName
};
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
var jsonObject = jsonSerializer.Serialize(exitParking);
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
var result = client.PostAsync("http://merchant-api-eb-parking-prod.eu-west-1.elasticbeanstalk.com/v1/parkings/exit", content).Result;
Context.Response.Output.Write($"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><ExitResponse xmlns=\"http://tempuri.org/\"><ExitResult xmlns:a=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:i=\"http://www.w3.org/2001/XMLSchema\"><a:Status>OK</a:Status></ExitResult></ExitResponse></s:Body></s:Envelope>");
Context.Response.ContentType = "text/xml";
Context.Response.End();
return string.Empty;
}
i can see the data i post in Global.asax in Request Object
i see the xml i post as string but after global asax it throws exception.
i have Root attribute but in exception it says: Root element is missing
Thank You!
Ok figured it out!
the reason for error was:
<Exit xmlns="http:--tempuri-org-">
the namespace (xmlns) have to be my website url on sever
http:--mysite-com-
instead of
http:--tempuri-org-
I'm trying to add this Header class to my SOAP request but can't see how. The Header class was given to me as part of the implementation but there's no instructions on how to use it and I'm a bit stuck - I've not used WSDL and web services before. I'm sure the answer must be blindingly easy but I just can't see it.
Header Requirements
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-19" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>##USERNAME##</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">##PASSWORD##</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Header class
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
namespace Consuming
{
public class SecurityHeader : MessageHeader
{
private readonly UsernameToken _usernameToken;
public SecurityHeader(string id, string username, string password)
{
_usernameToken = new UsernameToken(id, username, password);
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
serializer.Serialize(writer, _usernameToken);
}
}
[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
public UsernameToken()
{
}
public UsernameToken(string id, string username, string password)
{
Id = id;
Username = username;
Password = new Password() { Value = password };
}
[XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
public string Id { get; set; }
[XmlElement]
public string Username { get; set; }
[XmlElement]
public Password Password { get; set; }
}
public class Password
{
public Password()
{
Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
}
[XmlAttribute]
public string Type { get; set; }
[XmlText]
public string Value { get; set; }
}
}
Code
var mySoapHeader = new SecurityHeader("ID","Username","password");
var client = new GroupWebServiceClient(); // Created from Add Web Reference
client.?????? = mySoapHeader;// I can't see how to add the Header to the request
var response = new groupNameListV1();
response = client.getAllDescendants("6335");//This needs the header - omitting gives "An error was discovered processing the <wsse:Security> header"
EDIT
I figured it out in the end, turns out it was pretty easy - Adding the solution in case anyone else finds it useful
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(
new SecurityHeader("ID", "USER", "PWD"));
var response = new groupNameListV1();
response = client.getAllDescendants("cng_so_6553");
//other code
}
Generally you need to add behavior extension.
Create a class that implements IClientMessageInspector. In the BeforeSendRequest method, add your custom header to the outgoing message. It might look something like this:
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER]))
{
httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER] = this.m_userAgent;
}
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, this.m_userAgent);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
Then create an endpoint behavior that applies the message inspector to the client runtime. You can apply the behavior via an attribute or via configuration using a behavior extension element.
Here is a example of how to add an HTTP user-agent header to all request messages. I used this in a few of my clients.
Is this what you had in mind?
I am creating ASMX web service in .Net for javaclient. Provided soap looks like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pus="http://www.example.org/pusheventservice/">
<soapenv:Header>
<ServiceHeader>
<TransactionID>258350</TransactionID>
<TransactionDate>2014/12/21</TransactionDate>.......
and javaclient expects response SOAP
like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pus="http://www.example.org/pusheventservice/">
<soapenv:Header>
<ResponseServiceHeader>
<TransactionID>258350</TransactionID>
<TransactionDate>2014/12/21</TransactionDate>....
means requestElement is 'ServiceHeader' and ResponseElement must be 'ResponseServiceHeader'
I WebMethod i achieved this but unable in Header.
Is it Possible?? If Yes how?? Also I Cant use WCF....
EDITS
namespace PushWS
{
[WebService(Namespace = "http://localhost:60463/PushEvent.asmx")]
[WebServiceBinding(ConformsTo = WsiProfiles.None)]
[SoapDocumentService(SoapBindingUse.Literal, SoapParameterStyle.Bare, RoutingStyle = SoapServiceRoutingStyle.SoapAction)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class PushEvent : System.Web.Services.WebService
{
public ServiceHeader serviceHeader = null;
public SoapUnknownHeader[] userCredentials;
[WebMethod(Description = "updateEvent receives XML from Client")]
[SoapHeader("serviceHeader", Direction = SoapHeaderDirection.InOut)]
[SoapHeader("userCredentials", Required = true)]
[return: XmlElement("EventResponse")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://localhost:60463/PushEvent.asmx/updateEvent",
RequestElementName = "updateEventRequest",
ResponseElementName = "updateEventResponse")]
public XmlElement updateEvent([XmlAnyElement]XmlElement MyPushEvent)
{
//Logic here
}
public class ServiceHeader : SoapHeader
{
public string TransactionID{get;set;}
public string TransactionDate{get;set;}
}
}
Create a derived class for the response header:
public class ResponseServiceHeader : ServiceHeader
{
}
public ServiceHeader serviceHeader = null;
public ResponseServiceHeader responseServiceHeader = null;
[SoapHeader("serviceHeader", Direction = SoapHeaderDirection.Int)]
[SoapHeader("responseServiceHeader", Direction = SoapHeaderDirection.Out)]
How do you add create a SOAP web service header?
Example
<soap:Header>
<myHeader xmlns="https://www.domain.com">
<Username>string</Username>
<Password>string</Password>
</myHeader>
</soap:Header>
source code
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
namespace TestWebServices
{
/// <summary>
/// Summary description
/// </summary>
[WebService(Namespace = "https://Test.com")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Testing : System.Web.Services.WebService
{
[WebMethod]
public string GetTestValue()
{
return "xyz";
}
}
}
How about:
public class MyHeader : SoapHeader
{
public string Username;
public string Password;
}
There's more on the subject here:
Using SOAP Headers (MSDN - archived)
Defining and Processing SOAP Headers (MSDN)
If you need fine grain control over how the soap header xml gets rendered (happens when interfacing with a webservice written with java), you can always override all rendering by implementing IXmlSerializable
[XmlRoot("customHeader", Namespace = "http://somecompany.com/webservices/security/2012/topSecret")]
public class customHeader: SoapHeader, IXmlSerializable
{
public customHeader()
{
Actor = "http://schemas.xmlsoap.org/soap/actor/next";
MustUnderstand = false;
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
//throw new NotImplementedException();
}
public void ReadXml(XmlReader reader)
{
//throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("soap:actor", Actor);
writer.WriteAttributeString("soap:mustUnderstand", MustUnderstand ? "1" : "0");
writer.WriteRaw("some encrypted data");
//get it exactly the way you want it in here without mucking with Xml* property attributes for hours on end
//writer.WriteElement(...);
}
}
A SOAP message with headers may look something like the following:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Username>string</Username>
<Password>string</Password>
</soap:Header>
</soap:Envelope>
EndpointAddressBuilder builder = new EndpointAddressBuilder(client.Endpoint.Address);
AddressHeader header = AddressHeader.CreateAddressHeader("apiKey", "http://tempuri.org", "longapikeyhere");
builder.Headers.Add(header);
client.Endpoint.Address = builder.ToEndpointAddress();