Search code examples
c#wcfuwpsoap-client

How to choose Soap client configuration from app.config using C#/UWP?


I'm trying to put the Soap client configuration into the app.config. But I still face some problems.

Here's my app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="MyServiceHttpSoapBinding" maxReceivedMessageSize="20000000">
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpBinding>
            <basicHttpsBinding>
                <binding name="MyServiceHttpsSoapBinding" maxReceivedMessageSize="20000000">
                    <security mode="Transport">
                        <transport clientCredentialType="Basic" />
                    </security>
                </binding>
            </basicHttpsBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8080/webservice/MyService"
                binding="basicHttpBinding" bindingConfiguration="MyServiceHttpSoapBinding"
                contract="MyServiceReference.MyService" name="MyServiceHttpPort" />
            <endpoint address="https://localhost:8080/webservice/MyService"
                binding="basicHttpsBinding" bindingConfiguration="MyServiceHttpsSoapBinding"
                contract="MyServiceReference.MyService" name="MyServiceHttpsPort" />
        </client>
    </system.serviceModel>
</configuration>

And here's the code:

// init client
MyServiceClient client = new MyServiceClient();
client.ClientCredentials.UserName.UserName = uname;
client.ClientCredentials.UserName.Password = pws;
GetHelloServiceResponse response = await client.GetHelloService();
// ...

With the debugger I found out that the client's endpoint's address is "http://localhost:8080/webservice/MyService" and the binding is basicHttpBinding. But the Name is just "MyServicePort" not "MyServiceHttpPort" and the binding configuration "MyServiceHttpSoapBinding" is not used. So it doesn't work, because the binding's security settings are not set.

I thought I could create the client with new MyServiceClient("MyServiceHttpPort");, but that constructor option is not available.

Previously it worked with the coded configuration:

client.Endpoint.Address = new EndpointAddress(EndPoint);
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
client.Endpoint.Binding = binding;

But I'd prefer to do it by configuration.


Solution

  • As you are using WCF in UWP, then you are actually using the .NET Core version of the Windows Communication Foundation client libraries.

    It's a subset of the .NET Framework version of Windows Communication Foundation and currently supports the same API surface available for Windows 8.1 Store apps. It is used to build .NET Core apps, including Windows UWP and ASP.NET 5. These client libraries are suitable for mobile devices or on mid-tier servers to communicate with existing WCF services.

    And unlike the .NET Framework version, all configuration for WCF in .NET Core is done in code now — there is no config file. For more info, please see Removing dead code associated with ClientBase #252 and also the source code of ClientBase.cs.

    So in UWP apps, we can't configure Client with a configuration file, we need to do this programmatically.