0

Say I have made the following WCF service using BasicHttpsBinding:

[ServiceContract]
    public interface IHelloWorld
    {
        [OperationContract]
        void HelloWorld();
    }

How would I have to change it in order to be able to handle the following PostAsync request containing XML data?

httpContent = new StringContent(xmlDoc.ToString(), Encoding.UTF8, "application/xml");
httpClient.PostAsync(requestURI, httpContent);

Or is there a better way to do this?

Thank you!

Johan

Johan Maes
  • 1,161
  • 13
  • 13
  • Do I need to use SOAP instead of XML? I'm trying to reproduce the answer in https://stackoverflow.com/a/20108971/9266796 but no luck so far. – Johan Maes May 17 '18 at 16:10
  • Also, I've configured the WCF service with HTTPS according to this link https://blogs.msdn.microsoft.com/james_osbornes_blog/2010/12/10/selfhosting-a-wcf-service-over-https/ – Johan Maes May 17 '18 at 16:34

1 Answers1

0

Here's my solution. There were several issues I had to face: which binding to choose (WebHttpBinding), dealing with PostAsync (async within sync method) and preventing StringWriter to change UTF8 to UTF16.

On the server side, the interface looks like this:

[ServiceContract]
[XmlSerializerFormat]
public interface IHelloWorld
{
    [OperationContract]
    [WebInvoke(Method = "POST",
               RequestFormat = WebMessageFormat.Xml,
               BodyStyle = WebMessageBodyStyle.Bare,
               UriTemplate = "")]
    void HelloWorld(MyRequest request);
}

The attribute XmlSerializerFormat indicates that WCF should use the XMLSerializer instead of the default DataContractSerializer. In order for this to work the class MyRequest has to be properly annotated with [XmlElement], [XmlAttribute], etc., see https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-the-xmlserializer-class.

This is where I configure the WCF host:

WebServiceHost host = new WebServiceHost(typeof(HelloWorldService));

WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.Transport;

var endpoint = host.AddServiceEndpoint(typeof(IHelloWorld), binding, _address);
endpoint.Behaviors.Add(new WebHttpBehavior());

host.Open();            

On the client side, the code now looks like this:

var _serializer = new XmlSerializer(typeof(MyRequest));
StringContent _httpContent;

// We need to keep UTF8 encoding here (StringWriter uses UTF16 by default)
using (StringWriter _textWriter = new Utf8StringWriter())
{
     _serializer.Serialize(_textWriter, _ebicsRequest);
     _httpContent = new StringContent(_textWriter.ToString(), Encoding.UTF8, "application/xml");
}

HttpClient _httpClient = new HttpClient();
var task = _httpClient.PostAsync(_requestURI, _httpContent).Result;

I found the Utf8StringWriter class here: https://stackoverflow.com/a/25731993/9266796.

Johan Maes
  • 1,161
  • 13
  • 13