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 diff --git a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs index 1be2b1b..2a3846d 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderClient/BeanTraderCallback.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.ServiceModel; using System.Text; using System.Threading.Tasks; 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); 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..91daab7 100644 --- a/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/Program.cs @@ -1,31 +1,67 @@ -using Serilog; +using CoreWCF.Configuration; +using CoreWCF.Description; +using CoreWCF.Security; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +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); + builder.WebHost.ConfigureKestrel(options => { - // 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(); - } + options.ListenAnyIP(8080); + }); + + // Add CoreWCF services to the ASP.NET Core app's DI container + 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 => + { + 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..0be91a7 --- /dev/null +++ b/Samples/BeanTrader/NetCore/BeanTraderServer/wcf.config @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +