diff --git a/samples/todoapp/Samples.TodoApp.sln b/samples/todoapp/Samples.TodoApp.sln index eb01ab7f..c079eda2 100644 --- a/samples/todoapp/Samples.TodoApp.sln +++ b/samples/todoapp/Samples.TodoApp.sln @@ -23,6 +23,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.iOS", "Tod EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.Browser", "TodoApp.Avalonia\TodoApp.Avalonia.Browser\TodoApp.Avalonia.Browser.csproj", "{E8BB1310-477D-44B0-B13E-77F09433D0A3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{E0CB420D-EEFC-415C-B10A-A01233115A3C}" + ProjectSection(SolutionItems) = preProject + ..\Directory.Packages.props = ..\Directory.Packages.props + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{AF5C479C-1BDE-4783-8707-A3440FC0B89D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Clients", "Clients", "{32025F6A-2D8A-4BA2-93BE-B989DFD216FC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,22 +68,6 @@ Global {D783EDE7-D3A2-44D3-8C97-38AFFF9A4555}.Release|x86.ActiveCfg = Release|x86 {D783EDE7-D3A2-44D3-8C97-38AFFF9A4555}.Release|x86.Build.0 = Release|x86 {D783EDE7-D3A2-44D3-8C97-38AFFF9A4555}.Release|x86.Deploy.0 = Release|x86 - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|ARM64.Build.0 = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|x64.ActiveCfg = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|x64.Build.0 = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|x86.ActiveCfg = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Debug|x86.Build.0 = Debug|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|Any CPU.Build.0 = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|ARM64.ActiveCfg = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|ARM64.Build.0 = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x64.ActiveCfg = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x64.Build.0 = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x86.ActiveCfg = Release|Any CPU - {2AC73FBE-9E76-4702-B551-B5884383CC68}.Release|x86.Build.0 = Release|Any CPU {E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|Any CPU.Build.0 = Debug|Any CPU {E67734DD-B397-4A65-AA50-D62F37EF05DD}.Debug|ARM64.ActiveCfg = Debug|Any CPU @@ -216,7 +209,11 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2AC73FBE-9E76-4702-B551-B5884383CC68} = {7183ECEC-9F44-48CE-BB97-AA2445170D5E} + {D783EDE7-D3A2-44D3-8C97-38AFFF9A4555} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC} + {E67734DD-B397-4A65-AA50-D62F37EF05DD} = {AF5C479C-1BDE-4783-8707-A3440FC0B89D} + {00430043-04C5-4F8F-87A9-98ECC0051808} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC} + {A0996FB8-890D-4E90-A881-01F9EF709711} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC} + {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC} {539C6E0F-8F23-4AE0-B8E6-7E72C53B890A} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E} {9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E} {3D741850-6FAA-4F36-BD58-F6ECE0CE55D7} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E} diff --git a/samples/todoapp/TodoApp.WPF/Database/AppDbContext.cs b/samples/todoapp/TodoApp.WPF/Database/AppDbContext.cs index b00f3b1c..24752368 100644 --- a/samples/todoapp/TodoApp.WPF/Database/AppDbContext.cs +++ b/samples/todoapp/TodoApp.WPF/Database/AppDbContext.cs @@ -2,39 +2,50 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#undef OFFLINE_SYNC_ENABLED + using CommunityToolkit.Datasync.Client.Http; using CommunityToolkit.Datasync.Client.Offline; using Microsoft.EntityFrameworkCore; +using TodoApp.WPF.Services; namespace TodoApp.WPF.Database; +#if OFFLINE_SYNC_ENABLED +public class AppDbContext(DbContextOptions options) : OfflineDbContext(options) +#else public class AppDbContext(DbContextOptions options) : DbContext(options) +#endif { public DbSet TodoItems => Set(); - //protected override void OnDatasyncInitialization(DatasyncOfflineOptionsBuilder optionsBuilder) - //{ - // HttpClientOptions clientOptions = new() - // { - // Endpoint = new Uri("https://YOURSITEHERE.azurewebsites.net/"), - // HttpPipeline = [new LoggingHandler()] - // }; - // _ = optionsBuilder.UseHttpClientOptions(clientOptions); - //} +#if OFFLINE_SYNC_ENABLED + protected override void OnDatasyncInitialization(DatasyncOfflineOptionsBuilder optionsBuilder) + { + HttpClientOptions clientOptions = new() + { + Endpoint = new Uri("https://YOUR_SITE_HERE.azurewebsites.net/"), + HttpPipeline = [new LoggingHandler()] + }; + _ = optionsBuilder.UseHttpClientOptions(clientOptions); + } +#endif public async Task SynchronizeAsync(CancellationToken cancellationToken = default) { - //PushResult pushResult = await this.PushAsync(cancellationToken); - //if (!pushResult.IsSuccessful) - //{ - // throw new ApplicationException($"Push failed: {pushResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}"); - //} - - //PullResult pullResult = await this.PullAsync(cancellationToken); - //if (!pullResult.IsSuccessful) - //{ - // throw new ApplicationException($"Pull failed: {pullResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}"); - //} +#if OFFLINE_SYNC_ENABLED + PushResult pushResult = await this.PushAsync(cancellationToken); + if (!pushResult.IsSuccessful) + { + throw new ApplicationException($"Push failed: {pushResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}"); + } + + PullResult pullResult = await this.PullAsync(cancellationToken); + if (!pullResult.IsSuccessful) + { + throw new ApplicationException($"Pull failed: {pullResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}"); + } +#endif } } diff --git a/samples/todoapp/TodoApp.WPF/Services/LoggingHandler.cs b/samples/todoapp/TodoApp.WPF/Services/LoggingHandler.cs new file mode 100644 index 00000000..51312c0d --- /dev/null +++ b/samples/todoapp/TodoApp.WPF/Services/LoggingHandler.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Net.Http; + +namespace TodoApp.WPF.Services; + +/// +/// A delegating handler that logs the request/response to stdout. +/// +public class LoggingHandler : DelegatingHandler +{ + public LoggingHandler() : base() + { + } + + public LoggingHandler(HttpMessageHandler innerHandler) : base(innerHandler) + { + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + Debug.WriteLine($"[HTTP] >>> {request.Method} {request.RequestUri}"); + await WriteContentAsync(request.Content, cancellationToken); + + HttpResponseMessage response = await base.SendAsync(request, cancellationToken); + + Debug.WriteLine($"[HTTP] <<< {response.StatusCode} {response.ReasonPhrase}"); + await WriteContentAsync(response.Content, cancellationToken); + + return response; + } + + private static async Task WriteContentAsync(HttpContent? content, CancellationToken cancellationToken = default) + { + if (content is not null) + { + Debug.WriteLine($"[HTTP] >>> {await content.ReadAsStringAsync(cancellationToken)}"); + } + } +} diff --git a/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj b/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj index ba2e20d4..aa575cda 100644 --- a/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj +++ b/samples/todoapp/TodoApp.WPF/TodoApp.WPF.csproj @@ -1,8 +1,8 @@ - + WinExe - net8.0-windows + net9.0-windows enable enable true @@ -19,7 +19,7 @@ - - + +