翼度科技»论坛 编程开发 .net 查看内容

在 WPF 中集成 ASP.NET Core 和 WebView2 用于集成 SPA 应用

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
背景

我们有些工具在 Web 版中已经有了很好的实践,而在 WPF 中重新开发也是一种费时费力的操作,那么直接集成则是最省事省力的方法了。
修改项目文件

我们首先修改项目文件,让 WPF 项目可以包含 ASP.NET Core 的库,以及引用 WebView2 控件。
  1. <Project Sdk="Microsoft.NET.Sdk">
  2.   <PropertyGroup>
  3.         <OutputType>WinExe</OutputType>
  4.         <TargetFramework>net8.0-windows</TargetFramework>
  5.         <Nullable>enable</Nullable>
  6.         <ImplicitUsings>enable</ImplicitUsings>
  7.         <UseWPF>true</UseWPF>
  8.   </PropertyGroup>
  9.   <ItemGroup>
  10.    
  11.         <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2478.35" />
  12.    
  13.         <FrameworkReference Include="Microsoft.AspNetCore.App" />
  14.   </ItemGroup>
  15.   <ItemGroup>
  16.    
  17.         <None Update="wwwroot\**">
  18.           <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  19.         </None>
  20.   </ItemGroup>
  21. </Project>
复制代码
修改 App.xaml 和 App.xaml.cs 以使用 ASP.NET Core 的 WebApplication.CreateBuilder()

这里为了全局使用依赖注入,我们将 WebApplication.CreateBuilder() 放在 App.xaml.cs 中全局使用。为了使用依赖注入应注释掉默认启动窗口,并接管 Startup 事件。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:WpfAircraftViewer"
  5.              Startup="ApplicationStartup">
  6.    
  7.     <Application.Resources>
  8.          
  9.     </Application.Resources>
  10. </Application>
复制代码
然后通过修改 Startup 事件的代码来实现相应的加载动作。
  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.StaticFiles;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using System.Windows;
  5. namespace WpfAircraftViewer
  6. {
  7.     /// <summary>
  8.     /// Interaction logic for App.xaml
  9.     /// </summary>
  10.     public partial class App : Application, IAsyncDisposable
  11.     {
  12.         public WebApplication? WebApplication { get; private set; }
  13.         public async ValueTask DisposeAsync()
  14.         {
  15.             if (WebApplication is not null)
  16.             {
  17.                 await WebApplication.DisposeAsync();
  18.             }
  19.             GC.SuppressFinalize(this);
  20.         }
  21.         
  22.         private async void ApplicationStartup(object sender, StartupEventArgs e)
  23.         {
  24.             // 这里是创建 ASP.NET 版通用主机的代码
  25.             var builder = WebApplication.CreateBuilder(Environment.GetCommandLineArgs());
  26.             // 注册主窗口和其他服务
  27.             builder.Services.AddSingleton<MainWindow>();
  28.             builder.Services.AddSingleton(this);
  29.             var app = builder.Build();
  30.             // 这里是文件类型映射,如果你的静态文件在浏览器中加载报 404,那么需要在这里注册,这里我加载一个 3D 场景文件的类型
  31.             var contentTypeProvider = new FileExtensionContentTypeProvider();
  32.             contentTypeProvider.Mappings[".glb"] = "model/gltf-binary";
  33.             app.UseStaticFiles(new StaticFileOptions
  34.             {
  35.                 ContentTypeProvider = contentTypeProvider,
  36.             });
  37.             // 你如果使用了 Vue Router 或者其他前端路由了,需要在这里添加这句话让路由返回前端,而不是 ASP.NET Core 处理
  38.             app.MapFallbackToFile("/index.html");
  39.             WebApplication = app;
  40.             // 处理退出事件,退出 App 时关闭 ASP.NET Core
  41.             Exit += async (s, e) => await WebApplication.StopAsync();
  42.             // 显示主窗口
  43.             MainWindow = app.Services.GetRequiredService<MainWindow>();
  44.             MainWindow.Show();
  45.             await app.RunAsync().ConfigureAwait(false);
  46.         }
  47.     }
  48. }
复制代码
此时,我们已经可以正常开启一个默认界面的 MainWindow 了。
使用 WebView2 控件

这时我们就可以先将 SPA 文件从 npm 项目的 dist 复制到 wwwroot 了,在编辑 MainWindow 加入 WebView2 控件后就可以查看了。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:WpfAircraftViewer"
  5.              Startup="ApplicationStartup">
  6.    
  7.     <Application.Resources>
  8.          
  9.     </Application.Resources>
  10. </Application>           
复制代码
我们可以继续编辑窗口的信息,让他可以关联 ASP.NET Core 的监听地址。
  1. using Microsoft.AspNetCore.Hosting.Server;
  2. using Microsoft.AspNetCore.Hosting.Server.Features;
  3. using System.Windows;
  4. namespace WpfAircraftViewer
  5. {
  6.     /// <summary>
  7.     /// Interaction logic for MainWindow.xaml
  8.     /// </summary>
  9.     public partial class MainWindow : Window
  10.     {
  11.         public string SourceUrl { get; set; }
  12.         public MainWindow(IServer server)
  13.         {
  14.             InitializeComponent();
  15.             // 这里通过注入的 IServer 对象来获取监听的 Url
  16.             var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses;
  17.             SourceUrl = addresses is not null ? (addresses.FirstOrDefault() ?? "http://localhost:5000") : "http://localhost:5000";
  18.             // 无 VM,用自身当 VM
  19.             DataContext = this;
  20.         }
  21.     }
  22. }
复制代码
这时我们就可以看到窗口打开了我们的 SPA 页面了。


来源:https://www.cnblogs.com/aobaxu/p/18186785
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具