{"id":39661,"date":"2022-04-28T11:06:25","date_gmt":"2022-04-28T18:06:25","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=39661"},"modified":"2024-12-13T15:21:45","modified_gmt":"2024-12-13T23:21:45","slug":"corewcf-v1-released","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/corewcf-v1-released\/","title":{"rendered":"CoreWCF 1.0 has been Released, WCF for .NET Core and .NET 5+"},"content":{"rendered":"<p>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. Usage in code is similar to WCF, but updated to use ASP.NET Core as the service host, and to work with .NET Core. This is the first major release of the project, and provides WCF functionality for .NET Core, .NET Framework, and .NET 5+.<\/p>\n<p>The 1.0 release of CoreWCF is compatible with .NET Standard 2.0 so that it will work with:<\/p>\n<ul>\n<li>.NET Framework 4.6.2 (and above)<\/li>\n<li>.NET Core 3.1<\/li>\n<li>.NET 5 &amp; 6<\/li>\n<\/ul>\n<p>Support for .NET Framework will enable an easier modernization path to .NET Core. Applications with WCF dependencies can be updated to use CoreWCF in-place on .NET framework, which then will work the same when updated to use .NET Core or .NET 5+.<\/p>\n<p>The assemblies are available on <a href=\"https:\/\/www.nuget.org\/profiles\/corewcf\">Nuget.org<\/a>, as described in the <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/releases\/latest\">Release Notes<\/a>.<\/p>\n<h2>Community Project<\/h2>\n<p>CoreWCF was announced as a <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/supporting-the-community-with-wf-and-wcf-oss-projects\/\">community project<\/a> in June of 2019, and has had many contributors during the last 3 years. As a community project, CoreWCF has had more commits from other contributors than Microsoft employees, and regular contributions from AWS and other organizations.<\/p>\n<p>A special thanks to <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/graphs\/contributors\">all those<\/a> who have contributed code, issues or suggestions. The community support has been critical to getting the project to this point, and we hope it will continue for subsequent versions. I&#8217;d be remiss if I didn&#8217;t make a special callout to <a href=\"https:\/\/github.com\/mconnew\">@mconnew<\/a> who has been the backbone of the project and contributed most of the code.<\/p>\n<p>As a community project, the voices of the community guide the direction of the project. For example, the <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/issues\/234\">Feature Roadmap Vote issue<\/a> is highly influential to the planning process for what to work on next. If you are a WCF user, please provide feedback on what you would like to see in subsequent releases.<\/p>\n<h2>Features<\/h2>\n<p>CoreWCF is a subset of the functionality from WCF, but represents what we believe are the most used features, including:<\/p>\n<ul>\n<li>Http &amp; NetTCP transports<\/li>\n<li>Bindings:\n<ul>\n<li>BasicHttpBinding<\/li>\n<li>NetHttpBinding<\/li>\n<li>NetTcpBinding &#8211; some WS-* features not supported<\/li>\n<li>WebHttpBinding<\/li>\n<li>WSHttpBinding &#8211; some WS-* features not supported<\/li>\n<\/ul>\n<\/li>\n<li>Security:\n<ul>\n<li>Transport<\/li>\n<li>NetTcpBinding supports Certificate and Windows authentication<\/li>\n<li>Http bindings require authentication to be configured in ASP.NET Core<\/li>\n<li>Transport With Message Credentials<\/li>\n<li>Username, Certificate and Windows Authentication are supported<\/li>\n<li>WS Federation<\/li>\n<\/ul>\n<\/li>\n<li>WSDL generation<\/li>\n<li>Partial configuration support including services &amp; endpoints<\/li>\n<li>Extensibility (IServiceBehavior and IEndpointBehavior) &#8211; most extensibility is available<\/li>\n<\/ul>\n<p>Major WCF features not yet implemented include:<\/p>\n<ul>\n<li>Transports other than Http and NetTCP.<\/li>\n<li>Message security beyond Transport &amp; Transport with Message Credentials<\/li>\n<li>Distributed transactions<\/li>\n<li>Message Queueing<\/li>\n<\/ul>\n<h2>Who should use CoreWCF?<\/h2>\n<p>CoreWCF is intended for customers who have been using WCF on .NET Framework and need WCF support in .NET Core to facilitate modernizing the application. While there is nothing stopping you from adopting CoreWCF in greenfield projects, we would recommend you consider more modern alternatives to SOAP such as <a href=\"https:\/\/docs.microsoft.com\/aspnet\/core\/grpc\/?view=aspnetcore-6.0\">gRPC<\/a>. The sweet spot for CoreWCF is to make it easier to modernize server and clients that have a strong dependency on WCF and SOAP.<\/p>\n<h2>Microsoft Support<\/h2>\n<p>We recognize how important support is to enterprise customers, and so we are pleased to announce that Microsoft Product Support will be available for CoreWCF customers.<\/p>\n<p>Support for CoreWCF 1.x will depend on the support status for the underlying .NET platforms it runs on.<\/p>\n<table>\n<thead>\n<tr>\n<th><strong>Runtime Version<\/strong><\/th>\n<th><strong>Support dependency duration<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>.NET Framework 4.x<\/td>\n<td>The specific version of <a href=\"https:\/\/dotnet.microsoft.com\/platform\/support\/policy\/dotnet-framework\">.NET Framework<\/a>, and <a href=\"https:\/\/dotnet.microsoft.com\/platform\/support\/policy\/aspnet\">ASP.NET Core 2.1.<\/a><\/td>\n<\/tr>\n<tr>\n<td>.NET Core 3.1<\/td>\n<td>.NET 3.1 LTS &#8211; December 3, 2022<\/td>\n<\/tr>\n<tr>\n<td>.NET 5<\/td>\n<td>.NET 5 &#8211; May 8, 2022<\/td>\n<\/tr>\n<tr>\n<td>.NET 6<\/td>\n<td>.NET 6 LTS &#8211; November 8, 2024<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>CoreWCF will use Major.Minor versioning strategy:<\/p>\n<ul>\n<li>1.0 will be the first major release of CoreWCF<\/li>\n<li>Minor releases will be numbered 1.x, and will have the same underlying platform requirements as 1.0.<\/li>\n<li>Minor version releases (1.x) will be API compatible with the 1.0 release.<\/li>\n<li>Support will be primarily for the latest major.minor release of each supported major version.\n<ul>\n<li>When new major or minor versions are released, then the previous release will be supported for 6 months from the date of the new release, provided the underlying runtime dependency being used is still within support.<\/li>\n<\/ul>\n<\/li>\n<li>Subsequent major versions, such as 2.0, may reduce the map of runtimes that are supported. In that case 1.x will continue to be supported beyond the 6 months on the runtimes that are not supported by 2.0, and support duration will be limited only by the underlying platform.\n<ul>\n<li>This will most likely apply to .NET Framework, and means that 1.x will be supported as long as both ASP.NET Core 2.1 and .NET Framework 4.x are under support.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>More Support<\/h4>\n<p>Other organizations\/companies may choose to provide support for CoreWCF in conjunction with the use of their products and services.<\/p>\n<h2>Getting started<\/h2>\n<p>The definition and implementation of data and service contracts is the same as WCF. The major difference is in the definition of the host which is now based on ASP.NET Core, and the ceremony of how a service is exposed. The following is based on .NET 6, but the same steps apply to other versions of .NET.<\/p>\n<h3>Defining the service<\/h3>\n<h4> 1. Create an ASP.NET Core Empty application, this provides the host for the service.<\/h4>\n<p><em>Visual Studio:<\/em><br>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/04\/image1.png\" alt=\"Project Template\" \/><\/p>\n<p><em>Command Line:<\/em><\/p>\n<pre><code class=\"language-cli\">mkdir CoreWCFDemoServer\r\ndotnet new web -n CoreWCFDemoServer -o CoreWCFDemoServer<\/code><\/pre>\n<h4>2. Add references to the CoreWCF Nuget Packages<\/h4>\n<p><em>Visual Studio:<\/em><\/p>\n<p>Using the package Manager console, add: <\/p>\n<ul>\n<li>Primitives<\/li>\n<li>Http<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/04\/image2.png\" alt=\"Package Manager Console\" \/><\/p>\n<p><em>Command Line:<\/em><\/p>\n<p><p>Edit the project file and add:<\/p>\n<pre><code class=\"language-xml\">&lt;ItemGroup&gt;\r\n  &lt;PackageReference Include=\"CoreWCF.Http\" Version=\"1.0.0\" \/&gt;\r\n  &lt;PackageReference Include=\"CoreWCF.Primitives\" Version=\"1.0.0\" \/&gt;\r\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<h4>3. Create the Service Contract and Data Contract definitions<\/h4>\n<p>These are defined the same as with WCF. When modernizing projects, this code can remain largely unchanged.<\/p>\n<p><strong>File: IEchoService.cs<\/strong><\/p>\n<pre><code class=\"language-C#\">using System.Diagnostics.CodeAnalysis;\r\nusing System.Runtime.Serialization;\r\nusing CoreWCF;\r\n\r\nnamespace CoreWCfDemoServer\r\n{\r\n    [DataContract]\r\n    public class EchoFault\r\n    {\r\n        [AllowNull]\r\n        private string _text;\r\n\r\n        [DataMember]\r\n        [AllowNull]\r\n        public string Text\r\n        {\r\n            get { return _text; }\r\n            set { _text = value; }\r\n        }\r\n    }\r\n\r\n    [ServiceContract]\r\n    public interface IEchoService\r\n    {\r\n        [OperationContract]\r\n        string Echo(string text);\r\n\r\n        [OperationContract]\r\n        string ComplexEcho(EchoMessage text);\r\n\r\n        [OperationContract]\r\n        [FaultContract(typeof(EchoFault))]\r\n        string FailEcho(string text);\r\n\r\n    }\r\n\r\n    [DataContract]\r\n    public class EchoMessage\r\n    {\r\n        [AllowNull]\r\n        [DataMember]\r\n        public string Text { get; set; }\r\n    }\r\n}\r\n<\/code><\/pre>\n<p><strong>File: EchoService.cs<\/strong><\/p>\n<pre><code class=\"language-c#\">using CoreWCF;\r\n\r\nnamespace CoreWCfDemoServer\r\n{\r\n    public class EchoService : IEchoService\r\n    {\r\n        public string Echo(string text)\r\n        {\r\n            System.Console.WriteLine($\"Received {text} from client!\");\r\n            return text;\r\n        }\r\n\r\n        public string ComplexEcho(EchoMessage text)\r\n        {\r\n            System.Console.WriteLine($\"Received {text.Text} from client!\");\r\n            return text.Text;\r\n        }\r\n\r\n        public string FailEcho(string text)\r\n            =&gt; throw new FaultException&lt;EchoFault&gt;(new EchoFault() { Text = \"WCF Fault OK\" }, new FaultReason(\"FailReason\"));\r\n\r\n    }\r\n}<\/code><\/pre>\n<h4>4. The Service host needs to be told which services to expose via which bindings.<\/h4>\n<p> Update Program.cs to expose the Bindings:<\/p>\n<pre><code class=\"language-c#\">using CoreWCF;\r\nusing CoreWCF.Configuration;\r\nusing CoreWCF.Description;\r\nusing CoreWCfDemoServer;\r\n\r\nvar builder = WebApplication.CreateBuilder(args);\r\nbuilder.WebHost.ConfigureKestrel((context, options) =&gt;\r\n{\r\noptions.AllowSynchronousIO = true;\r\n});\r\n\r\n\/\/ Add WSDL support\r\nbuilder.Services.AddServiceModelServices().AddServiceModelMetadata();\r\nbuilder.Services.AddSingleton&lt;IServiceBehavior, UseRequestHeadersForMetadataAddressBehavior&gt;();\r\n\r\nvar app = builder.Build();\r\napp.UseServiceModel(builder =&gt;\r\n{\r\nbuilder.AddService((serviceOptions) =&gt; { })\r\n\/\/ Add a BasicHttpBinding at a specific endpoint\r\n.AddServiceEndpoint&lt;EchoService, IEchoService&gt;(new BasicHttpBinding(), \"\/EchoService\/basichttp\")\r\n\/\/ Add a WSHttpBinding with Transport Security for TLS\r\n.AddServiceEndpoint&lt;EchoService, IEchoService&gt;(new WSHttpBinding(SecurityMode.Transport), \"\/EchoService\/WSHttps\");\r\n});\r\nvar serviceMetadataBehavior = app.Services.GetRequiredService();\r\nserviceMetadataBehavior.HttpGetEnabled = true;\r\n\r\napp.Run();\r\n<\/pre>\n<p><\/code><\/p>\n<h4>5. Update the appsettings.json to specify fixed ports for the service to listen on<\/h4>\n<p>Add the following line before the \"Logging\" line in appsettings.json:<\/p>\n<p><code><\/p>\n<pre>\"Urls\": \"http:\/\/localhost:5000;https:\/\/localhost:5001\",<\/code><\/pre>\n<h4>6. Run the project so that the services can be called<\/h4>\n<\/p>\n<h3>To consume the service:<\/h3>\n<h4>1. Create a console application<\/h4>\n<h4>2. Add a Service Reference<\/h4>\n<p><em>Visual Studio<\/em><\/p>\n<p>Use the \"Add Service Reference\" command, and select \"WCF Web Service\" as the service type.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2022\/04\/image3.png\" alt=\"Add Service Reference Dialog\" \/><\/p>\n<p>Use <code>http:\/\/localhost:5000\/EchoService\/basichttp<\/code> as the URL for WSDL discovery.<\/p>\n<p><em>Command line<\/em><\/p>\n<p>From the Command Line, the same code can be generated using svcutil:<\/p>\n<pre><code class=\"language-cli\">dotnet tool install --global dotnet-svcutil\r\ndotnet-svcutil --roll-forward LatestMajor http:\/\/localhost:5000\/EchoService\/basichttp?wsdl<\/code><\/pre>\n<h4>3. Replace the code of the console app with:<\/h4>\n<pre><code class=\"language-C#\">using ServiceReference1;\r\n\/\/ Instantiate the Service wrapper specifying the binding and optionally the Endpoint URL. The BasicHttpBinding could be used instead.\r\nvar client = new EchoServiceClient(EchoServiceClient.EndpointConfiguration.WSHttpBinding_IEchoService, \"https:\/\/localhost:5001\/EchoService\/WSHttps\");\r\n\r\nvar simpleResult = await client.EchoAsync(\"Hello\");\r\nConsole.WriteLine(simpleResult);\r\n\r\nvar msg = new EchoMessage() { Text = \"Hello2\" };\r\nvar msgResult = await client.ComplexEchoAsync(msg);\r\nConsole.WriteLine(msgResult);\r\n<\/code><\/pre>\n<h2>Other Samples<\/h2>\n<p>Other samples, including samples for desktop framework are available at <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/tree\/main\/src\/Samples\">CoreWCF\/src\/Samples<\/a><\/p>\n<h2>See it in action<\/h2>\n<p>On an <a href=\"https:\/\/www.youtube.com\/watch?v=dom2O19fGAo\">recent episode<\/a> of <a href=\"https:\/\/docs.microsoft.com\/shows\/on-net\/\">On .NET<\/a>, Matthew Connew joined James Montemagno to walk through all of the new features and roadmap for CoreWCF:\n<iframe width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/dom2O19fGAo\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h2>Summary<\/h2>\n<p>We are pleased to see the community investment in the CoreWCF project, and congratulate them on this release. The project is ongoing and they welcome your feedback via <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/issues\">issues<\/a> and <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/discussions\">discussions<\/a> in GitHub, in particular which features you think should be worked on <a href=\"https:\/\/github.com\/CoreWCF\/CoreWCF\/issues\/234\">next<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CoreWCF 1.0 has been released, the first major release of the project, and provides WCF functionality for .NET Core, .NET Framework and .NET 5+.<\/p>\n","protected":false},"author":8635,"featured_media":39662,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7257],"tags":[7632,7339],"class_list":["post-39661","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-wcf","tag-corewcf","tag-wcf"],"acf":[],"blog_post_summary":"<p>CoreWCF 1.0 has been released, the first major release of the project, and provides WCF functionality for .NET Core, .NET Framework and .NET 5+.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/39661","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/8635"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=39661"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/39661\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/39662"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=39661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=39661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=39661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}