I´m porting a .net 4.6.2 code to a .net Core project, that calls a SOAP service. In the new code I´m using C# (because of some config reasons I just can´t remember why right now).
But I´m getting the following exception.
An error occurred while receiving the HTTP response to https://someurl.com/ws/Thing.pub.ws:Something. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
The code that is throwing it is
try
{
var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
var endpoint = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
var thing= new TheEndpoint.AService_PortTypeClient(binding, endpoint);
thing.ClientCredentials.UserName.UserName = "usrn";
thing.ClientCredentials.UserName.Password = "passw";
var response = await thing.getSomethingAsync("id").ConfigureAwait(false);
}
finally
{
await thing.CloseAsync().ConfigureAwait(false);
}
Based on the old config where it works calling the service is like this, what am I missing?
<bindings>
<basicHttpsBinding>
<binding name="TheEndpoint_pub_ws_AService_Binder" closeTimeout="00:02:00"
openTimeout="00:02:00" receiveTimeout="00:03:00" sendTimeout="00:03:00">
<security mode="Transport">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://someurl.com/ws/Thing.pub.ws:AService"
binding="basicHttpsBinding" bindingConfiguration="TheEndpoint_pub_ws_AService_Binder"
contract="TheEndpoint.AService_PortType" name="TheEndpoint_pub_ws_AService_Port" />
</client>
I´m just unable to find lot of information on this online. Hope you can help me.
UPDATE Per Sixto Saez suggestion I got the endpoint to reveal its error and it is
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="Integration Server", encoding="UTF-8"'.
I´ll try to find out what to do and post the result here if successful.
UPDATE 2
Ok now I tried to move to the new syntax with this code here
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
Binding binding = null;
try
{
binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
factory = new ChannelFactory<IAService>(binding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
//error caught here
throw;
}
but I still get the same (slightly different) error. It now has 'Anonymous' instead of 'Basic' and is now missing ", encoding="UTF-8" at the end.
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="Integration Server"'.
Is the problem at my side or the servers?
Obviously my SOAP "skills" are greatly lacking now days, but I have just about tried every config combo I can think of with this new approach without luck. Hope somebody can point me in the right direction.
The CoreWCF Project team has released the 1.0 version of CoreWCF, a port of WCF to the . NET Core platform. It provides a compatible implementation of SOAP, NetTCP, and WSDL.
Right click on Connected Services folder (should appear just below your project) and select Add Connected Service. Then select "Add a WCF web service". Put your asmx url into the URI field, set the name space and click Finish. You will now have the reference set.
NET Core or . NET Standard project, this option is available when you right-click on the Dependencies node of the project in Solution Explorer and choose Manage Connected Services.) On the Connected Services page, select Add Service Reference.
Ok this answer is for those who are trying to connect to a WCF service from a .net Core project.
Here is the solution to my problem, using the new .net Core WCF syntax/library.
BasicHttpBinding basicHttpBinding = null;
EndpointAddress endpointAddress = null;
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
try
{
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
endpointAddress = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
factory = new ChannelFactory<IAService>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
}
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
// *** ENSURE CLEANUP (this code is at the WCF GitHub page *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
UPDATE
I got the following exception using the code above
This OperationContextScope is being disposed out of order.
Which seems to be something that is broken (or needs addressing) by the WCF team.
So I had to do the following to make it work (based on this GitHub issue)
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
factory = new ChannelFactory<IAService_PortType>(basicHttpBinding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usern";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
try
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
OperationContext.Current = prevOpContext; // Or set to null if you didn't capture the previous context
}
But your requirements will probably be different. So here are the resources you might need to help you connecting to your WCF service are here:
The tests helped me a lot but they where somewhat hard to find (I had help, thank you Zhenlan for answering my wcf github issue)
To consume a SOAP service from .NET core, adding connected service from the project UI does not work.
Option 1: Use dotnet-svcutil CLI. Prerequisite: VS 2017, Version 15.5 or above
Go to app.csproj file and add below references:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="System.ServiceModel.Http" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-svcutil" Version="1.0.*" />
</ItemGroup>
Rebuild solution.
Option 2 In case you need to refer more than one SOAP sevice,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With