From 93b32edf7529e01ee6721d9438b69dea667b0f71 Mon Sep 17 00:00:00 2001 From: Mike Rousos Date: Fri, 29 Apr 2022 17:49:24 -0400 Subject: [PATCH 1/5] Update BeanTraderServer in the NetCore folder to target .NET 6 --- .../BeanTraderCommon.csproj | 57 +++---------- .../NetCore/BeanTraderServer/App.config | 37 +-------- .../NetCore/BeanTraderServer/BeanTrader.cs | 2 +- .../BeanTraderServer/BeanTraderServer.csproj | 81 +++++-------------- .../NetCore/BeanTraderServer/Program.cs | 55 +++++++++---- .../NetCore/BeanTraderServer/packages.config | 5 -- .../NetCore/BeanTraderServer/wcf.config | 27 +++++++ 7 files changed, 98 insertions(+), 166 deletions(-) delete mode 100644 Samples/BeanTrader/NetCore/BeanTraderServer/packages.config create mode 100644 Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config diff --git a/Samples/BeanTrader/NetCore/BeanTraderInterfaces/BeanTraderCommon.csproj b/Samples/BeanTrader/NetCore/BeanTraderInterfaces/BeanTraderCommon.csproj index e9694db..fb10bee 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderInterfaces/BeanTraderCommon.csproj +++ b/Samples/BeanTrader/NetCore/BeanTraderInterfaces/BeanTraderCommon.csproj @@ -1,54 +1,19 @@ - - - + - Debug - AnyCPU - {41C7E011-840E-44AB-9B5B-CAF6E7B7DE65} + netstandard2.0 Library - Properties BeanTraderInterfaces BeanTraderInterfaces - v4.7.2 - 512 - true + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - + + + + + + + all + - \ No newline at end of file diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/App.config b/Samples/BeanTrader/NetCore/BeanTraderServer/App.config index c5a1d87..f072f57 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/App.config +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/App.config @@ -1,38 +1,3 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTrader.cs b/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTrader.cs index b8ffe68..1796cb1 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTrader.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTrader.cs @@ -1,12 +1,12 @@ using BeanTrader; using BeanTrader.Models; +using CoreWCF; using Serilog; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; -using System.ServiceModel; using System.Text; using System.Threading; diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTraderServer.csproj b/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTraderServer.csproj index c295414..caaee2a 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTraderServer.csproj +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/BeanTraderServer.csproj @@ -1,72 +1,29 @@ - - - + - Debug - AnyCPU - {C7FE70DF-EF5A-4FED-91BE-9F6488C17135} + net6.0 Exe - BeanTraderServer - BeanTraderServer - v4.7.2 - 512 - true - true + false - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Serilog.2.8.0\lib\net46\Serilog.dll - - - ..\packages\Serilog.Sinks.Console.3.1.1\lib\net45\Serilog.Sinks.Console.dll - - - - - - - - - - - - - - - - - - - + PreserveNewest - - - {41C7E011-840E-44AB-9B5B-CAF6E7B7DE65} - BeanTraderCommon - + + + + + + + + + + + + + + all + - \ No newline at end of file diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs index eaeaab5..67da1d4 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs @@ -1,31 +1,54 @@ -using Serilog; +using CoreWCF.Configuration; +using CoreWCF.Security; +using Microsoft.AspNetCore.Builder; +using Serilog; using System; using System.IO; using System.Security.Cryptography.X509Certificates; -using System.ServiceModel; -using System.ServiceModel.Security; +using System.Threading.Tasks; namespace BeanTraderServer { class Program { - static void Main() + async static Task Main() { ConfigureLogging(); - using (var host = new ServiceHost(typeof(BeanTrader))) + var builder = WebApplication.CreateBuilder(); + + // Set NetTcp port (previously this was done in configuration, + // but CoreWCF requires it be done in code) + builder.WebHost.UseNetTcp(8090); + + // Add CoreWCF services to the ASP.NET Core app's DI container + builder.Services.AddServiceModelServices(); + builder.Services.AddServiceModelConfigurationManagerFile("wcf.config"); + + var app = builder.Build(); + + // Configure CoreWCF endpoints in the ASP.NET Core host + app.UseServiceModel(serviceBuilder => { - // For demo purposes, just load the key from disk so that no one needs to install an untrustworthy self-signed cert - // or load from KeyVault (which would complicate the sample) - var certPath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "BeanTrader.pfx"); - host.Credentials.ServiceCertificate.Certificate = new X509Certificate2(certPath, "password"); - host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; - host.Open(); - Log.Information("Bean Trader Service listening"); - WaitForExitSignal(); - Log.Information("Shutting down..."); - host.Close(); - } + serviceBuilder.ConfigureServiceHostBase(beanTraderServiceHost => + { + // This code is copied from the old ServiceHost setup and configures + // the local cert used for authentication. + // For demo purposes, this just loads the certificate from disk so that no one needs to install an + // untrustworthy self-signed cert or load from KeyVault (which would complicate the sample) + var certPath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "BeanTrader.pfx"); + beanTraderServiceHost.Credentials.ServiceCertificate.Certificate = new X509Certificate2(certPath, "password"); + beanTraderServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; + }); + }); + + await app.StartAsync(); + + Log.Information("Bean Trader Service listening"); + WaitForExitSignal(); + Log.Information("Shutting down..."); + + await app.StopAsync(); } private static void WaitForExitSignal() diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/packages.config b/Samples/BeanTrader/NetCore/BeanTraderServer/packages.config deleted file mode 100644 index 3a67250..0000000 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config b/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config new file mode 100644 index 0000000..70f2c9e --- /dev/null +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From bff878972a287bac2081bf5a67671352766946f4 Mon Sep 17 00:00:00 2001 From: Mike Rousos Date: Wed, 4 May 2022 13:16:32 -0400 Subject: [PATCH 2/5] Enable WSDL endpoint --- .../NetCore/BeanTraderServer/Program.cs | 22 ++++++++++++++++--- .../NetCore/BeanTraderServer/wcf.config | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs index 67da1d4..b75d515 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs @@ -1,6 +1,12 @@ -using CoreWCF.Configuration; +using BeanTrader; +using CoreWCF; +using CoreWCF.Configuration; +using CoreWCF.Description; using CoreWCF.Security; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.IdentityModel.Protocols.WsTrust; using Serilog; using System; using System.IO; @@ -20,13 +26,23 @@ async static Task Main() // Set NetTcp port (previously this was done in configuration, // but CoreWCF requires it be done in code) builder.WebHost.UseNetTcp(8090); + builder.WebHost.ConfigureKestrel(options => + { + options.ListenAnyIP(8080); + }); // Add CoreWCF services to the ASP.NET Core app's DI container - builder.Services.AddServiceModelServices(); - builder.Services.AddServiceModelConfigurationManagerFile("wcf.config"); + builder.Services.AddServiceModelServices() + .AddServiceModelConfigurationManagerFile("wcf.config") + .AddServiceModelMetadata(); var app = builder.Build(); + // Enable getting metadata/wsdl + var serviceMetadataBehavior = app.Services.GetRequiredService(); + serviceMetadataBehavior.HttpGetEnabled = true; + serviceMetadataBehavior.HttpGetUrl = new Uri("http://localhost:8080/metadata"); + // Configure CoreWCF endpoints in the ASP.NET Core host app.UseServiceModel(serviceBuilder => { diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config b/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config index 70f2c9e..0be91a7 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config @@ -3,14 +3,14 @@ - + - + From 531d36b4ebde8898af75f3df33c6353932f115e3 Mon Sep 17 00:00:00 2001 From: Mike Rousos Date: Tue, 18 Feb 2025 16:56:20 -0500 Subject: [PATCH 3/5] Fix-up concurrency mode attributes --- .../BeanTraderClient/BeanTraderCallback.cs | 2 ++ .../ViewModels/TradingViewModel.cs | 32 +++++++++---------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs index 1be2b1b..0b0260c 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.ServiceModel; using System.Text; using System.Threading.Tasks; namespace BeanTraderClient { + [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] public class BeanTraderCallback : BeanTraderServiceCallback { public event Action AddNewTradeOfferHandler; diff --git a/Samples/BeanTrader/NetCore/BeanTraderClient/ViewModels/TradingViewModel.cs b/Samples/BeanTrader/NetCore/BeanTraderClient/ViewModels/TradingViewModel.cs index 7d1e783..d6a68b5 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderClient/ViewModels/TradingViewModel.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderClient/ViewModels/TradingViewModel.cs @@ -49,7 +49,7 @@ public async Task LoadAsync() TradingService.Connected += LoadDataAsync; // Get initial trader info and trade offers - await LoadDataAsync().ConfigureAwait(false); + await LoadDataAsync().ConfigureAwait(true); // Register for service callbacks CallbackHandler.AddNewTradeOfferHandler += AddTradeOffer; @@ -60,8 +60,8 @@ public async Task LoadAsync() public async Task UnloadAsync() { // Stop listening - await TradingService.StopListeningAsync().ConfigureAwait(false); - await TradingService.LogoutAsync().ConfigureAwait(false); + await TradingService.StopListeningAsync().ConfigureAwait(true); + await TradingService.LogoutAsync().ConfigureAwait(true); // Unregister for service callbacks CallbackHandler.AddNewTradeOfferHandler -= AddTradeOffer; @@ -111,7 +111,7 @@ public async Task GetTraderNameAsync(Guid sellerId) if (!traderNames.TryGetValue(sellerId, out string traderName)) { - var names = await TradingService.GetTraderNamesAsync(new Guid[] { sellerId }).ConfigureAwait(false); + var names = await TradingService.GetTraderNamesAsync(new Guid[] { sellerId }).ConfigureAwait(true); traderName = names.ContainsKey(sellerId) ? traderNames.AddOrUpdate(sellerId, names[sellerId], (g, s) => names[sellerId]) : @@ -170,14 +170,14 @@ private void OnPropertyChanged(string propertyName) private async Task UpdateTraderInfoAsync() { - CurrentTrader = await TradingService.GetCurrentTraderInfoAsync().ConfigureAwait(false); + CurrentTrader = await TradingService.GetCurrentTraderInfoAsync().ConfigureAwait(true); } private async Task LoadDataAsync() { - await LoginAsync().ConfigureAwait(false); - await UpdateTraderInfoAsync().ConfigureAwait(false); - await ListenForTradeOffersAsync().ConfigureAwait(false); + await LoginAsync().ConfigureAwait(true); + await UpdateTraderInfoAsync().ConfigureAwait(true); + await ListenForTradeOffersAsync().ConfigureAwait(true); } private Task LoginAsync() @@ -219,8 +219,8 @@ private async void TradeAccepted(TradeOffer offer, Guid buyerId) { if (offer.SellerId == CurrentTrader.Id) { - SetStatus($"Trade ({offer}) accepted by {await GetTraderNameAsync(buyerId).ConfigureAwait(false) ?? buyerId.ToString()}"); - await UpdateTraderInfoAsync().ConfigureAwait(false); + SetStatus($"Trade ({offer}) accepted by {await GetTraderNameAsync(buyerId).ConfigureAwait(true) ?? buyerId.ToString()}"); + await UpdateTraderInfoAsync().ConfigureAwait(true); } } @@ -228,13 +228,13 @@ public async Task CompleteTrade(TradeOffer tradeOffer) { var ownTrade = tradeOffer.SellerId == CurrentTrader.Id; var success = ownTrade ? - await TradingService.CancelTradeOfferAsync(tradeOffer.Id).ConfigureAwait(false) : - await TradingService.AcceptTradeAsync(tradeOffer.Id).ConfigureAwait(false); + await TradingService.CancelTradeOfferAsync(tradeOffer.Id).ConfigureAwait(true) : + await TradingService.AcceptTradeAsync(tradeOffer.Id).ConfigureAwait(true); if (success) { SetStatus($"{(ownTrade ? "Canceled" : "Accepted")} trade ({tradeOffer})"); - await UpdateTraderInfoAsync().ConfigureAwait(false); + await UpdateTraderInfoAsync().ConfigureAwait(true); } else { @@ -261,12 +261,12 @@ public async Task ShowNewTradeOfferDialog() DataContext = newTradeOfferViewModel }; - await DialogCoordinator.ShowMetroDialogAsync(this, newTradeDialog).ConfigureAwait(false); + await DialogCoordinator.ShowMetroDialogAsync(this, newTradeDialog).ConfigureAwait(true); } private async Task CreateTradeOfferAsync(TradeOffer tradeOffer) { - if (await TradingService.OfferTradeAsync(tradeOffer).ConfigureAwait(false) != Guid.Empty) + if (await TradingService.OfferTradeAsync(tradeOffer).ConfigureAwait(true) != Guid.Empty) { SetStatus("New trade offer created"); } @@ -275,7 +275,7 @@ private async Task CreateTradeOfferAsync(TradeOffer tradeOffer) SetStatus("ERROR: Trade offer could not be created. Do you have enough beans?", Application.Current.FindResource("ErrorBrush") as Brush); } - await UpdateTraderInfoAsync().ConfigureAwait(false); + await UpdateTraderInfoAsync().ConfigureAwait(true); } private void SetStatus(string message) => SetStatus(message, Application.Current.FindResource("IdealForegroundColorBrush") as Brush); From 6a4d21b53236ea6c5475c6ae21c9cbcdfd15966b Mon Sep 17 00:00:00 2001 From: Mike Rousos Date: Tue, 18 Feb 2025 17:11:16 -0500 Subject: [PATCH 4/5] Remove callback behavior attribute that doesn't work with early netcore --- .../NetCore/BeanTraderClient/BeanTraderCallback.cs | 1 - Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs index 0b0260c..2a3846d 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs @@ -9,7 +9,6 @@ namespace BeanTraderClient { - [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] public class BeanTraderCallback : BeanTraderServiceCallback { public event Action AddNewTradeOfferHandler; diff --git a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs index b75d515..91daab7 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs @@ -1,12 +1,9 @@ -using BeanTrader; -using CoreWCF; -using CoreWCF.Configuration; +using CoreWCF.Configuration; using CoreWCF.Description; using CoreWCF.Security; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; -using Microsoft.IdentityModel.Protocols.WsTrust; using Serilog; using System; using System.IO; From a1dbd829766445867679a98df9ef251f8a308bb6 Mon Sep 17 00:00:00 2001 From: Mike Rousos Date: Fri, 7 Mar 2025 14:03:51 -0500 Subject: [PATCH 5/5] Update .gitignore to include .vscode files and remove netfx client from sln --- Samples/.gitignore | 1 + Samples/BeanTrader/NetCore/BeanTrader.sln | 9 +-------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Samples/.gitignore b/Samples/.gitignore index 65b2c36..401b625 100644 --- a/Samples/.gitignore +++ b/Samples/.gitignore @@ -21,5 +21,6 @@ packages/ # User-specific files .vs/ +.vscode/ *.suo *.user diff --git a/Samples/BeanTrader/NetCore/BeanTrader.sln b/Samples/BeanTrader/NetCore/BeanTrader.sln index 7e13cc0..066ee5d 100644 --- a/Samples/BeanTrader/NetCore/BeanTrader.sln +++ b/Samples/BeanTrader/NetCore/BeanTrader.sln @@ -1,12 +1,9 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28407.52 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeanTraderServer", "BeanTraderServer\BeanTraderServer.csproj", "{C7FE70DF-EF5A-4FED-91BE-9F6488C17135}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeanTraderClient", "BeanTraderClient\BeanTraderClient.csproj", "{995E758F-D656-4D2C-B679-69B81E58672F}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BeanTraderCommon", "BeanTraderInterfaces\BeanTraderCommon.csproj", "{41C7E011-840E-44AB-9B5B-CAF6E7B7DE65}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BeanTraderClient.Core", "BeanTraderClient\BeanTraderClient.Core.csproj", "{2AECFB26-B510-46D0-91BC-790A9215767E}" @@ -26,10 +23,6 @@ Global {C7FE70DF-EF5A-4FED-91BE-9F6488C17135}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7FE70DF-EF5A-4FED-91BE-9F6488C17135}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7FE70DF-EF5A-4FED-91BE-9F6488C17135}.Release|Any CPU.Build.0 = Release|Any CPU - {995E758F-D656-4D2C-B679-69B81E58672F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {995E758F-D656-4D2C-B679-69B81E58672F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {995E758F-D656-4D2C-B679-69B81E58672F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {995E758F-D656-4D2C-B679-69B81E58672F}.Release|Any CPU.Build.0 = Release|Any CPU {41C7E011-840E-44AB-9B5B-CAF6E7B7DE65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {41C7E011-840E-44AB-9B5B-CAF6E7B7DE65}.Debug|Any CPU.Build.0 = Debug|Any CPU {41C7E011-840E-44AB-9B5B-CAF6E7B7DE65}.Release|Any CPU.ActiveCfg = Release|Any CPU