2

TL;DR I have an existing WCF service hosted as a Windows Service which I want to modify so that it can be called by an existing .NET Framework 4.7 app as well as a new .NET Core 2.2 app. What's the simplest approach to solving this problem?

Full Explanation: I have an existing Web App (call it 'A') running on .NET Framework 4.7. It talks to an existing WCF Service 'B' (a Windows Service) also on .NET 4.7. They communicate over a NetTcpBinding.

I'm building a new Web App 'C' on .NET Core 2.2. I need it to talk to the existing service B. I can modify A and B as much as needed, but time and money are limited. Also, B consumes an API that runs only on .NET Framework, so it can not be converted to run on .NET Core, much to my frustration.

Service B is tiny. It's entire exposed contract is 5 methods. Security is really minimal. It's an intranet-only app at a tiny company.

What is the fastest, simplest way to modify the existing WCF Service B (and A if needed) so that it can talk to both apps A and C?

I'm guessing I should just change the WCF Binding on apps A and B to something I can easily talk to using an HttpClient on C; if so, which binding is that and how do I use the HttpClient to interface with it? Also, are there any hidden "gotchas" to changing the WCF Binding from NetTcpBinding to something else that are going to bite me?

pbristow
  • 1,997
  • 4
  • 26
  • 46

2 Answers2

1

Yes, we could publish the service with Basichttpbinding and WebHttpBinding, given that the Core is not well compatible with WS-binding.
Using basichttpbinding to create the service is simple, just replace the System.servicemodel section with the below code snippets.

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpBinding" scheme="http" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Then we could call the service by adding service reference. enter image description here
Or we publish restful style service by using Webhttpbinding, just like Asp.Net WebAPI.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/wcf-web-http-programming-model
Then we could call the service by constructing an HTTP request, GET/POST/PUT/Delete, with a request body. It is supported by both Core and .netframework since Http protocol is generic.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • Thank you. Do you recommend BasicHttpBinding or WebHttpBinding? – pbristow Jun 06 '19 at 10:47
  • It's up to you, but objectively speaking, building restful services is not the strength of wcf, and perhaps it would be better to build with webapi. If you want to keep wcf service, use basichtttpbinding, which is easy, and you can also use certificates to authenticate clients and ensure communication security. feel free to let me know if there is anything I can help with. – Abraham Qian Jun 07 '19 at 03:00
  • Is the WebHttpBinding compatible with the Add Service Reference feature you used above? It generated code for me, but there was no WebHttpBinding I could find to use from the .NET Core code that made it useful. It seemed to be a dead-end. – pbristow Jun 12 '19 at 21:08
  • The WCF service created by webhttpbinding is called Restful style service, it could be consumed by the way we construct a http request with http client. for example, the method decorated by [WebGet] could be called by typing the service address in the browser address bar. https://stackoverflow.com/questions/53200663/how-can-i-use-a-wcf-service/53203436#53203436 https://code-maze.com/different-ways-consume-restful-api-csharp/ – Abraham Qian Jun 13 '19 at 01:53
  • Besides, it also could be invoked by generating a client proxy(adding service reference), there might be some differences from traditional SOAP service. https://stackoverflow.com/questions/54018130/wcf-there-was-no-endpoint-listening-at-that-could-accept-the-message/54068160#54068160 – Abraham Qian Jun 13 '19 at 01:53
1

.NET Core includes client-side support for calling WCF services with the System.ServiceModel.* NuGet packages. Client wrappers can be generated for services using the Connected Services and Service Reference UI in Visual Studio. From the command line, the dotnet-svcutil tool can be used to generate the same wrapper code

CoreWCF uses the same host and builder model, but with extra middleware that implements WCF services and provides WSDL generation through metadata.

System.ServiceModel.* is deprecated in .NET Core , so we don't have full feature of WCF. As of April 2022, CoreWCF is officially supported by Microsoft. However, for an alternative to WCF, consider gRPC

var builder = WebApplication.CreateBuilder();
builder.Services.AddServiceModelServices();
builder.Services.AddServiceModelMetadata();
builder.Services.AddSingleton<IServiceBehavior,
UseRequestHeadersForMetadataAddressBehavior>();
var app = builder.Build();
app.UseServiceModel(bld =>
{
    bld.AddService<Service>();
    bld.AddServiceEndpoint<Service, IService>(new BasicHttpBinding(
        BasicHttpSecurityMode.Transport), "/Service.svc");
    var mb = app.Services.GetRequiredService<ServiceMetadataBehavior>();
    mb.HttpsGetEnabled = true;
});
app.Run();
pbristow
  • 1,997
  • 4
  • 26
  • 46