尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
WPF 引用 ASP.NET Core 的 AOT 版本
WPF 引用 ASP.NET Core 的 AOT 版本引言从桌面到云端再回到桌面的新思路作为一名技术博主我经常收到这样的问题“WPF 应用能不能调用 ASP.NET Core 的 API能不能用上 AOT 编译带来的性能优势” 答案是可以而且比你想象中更简单在 .NET 生态中WPF桌面应用框架和 ASP.NET CoreWeb 框架并非孤岛它们可以通过多种方式协作。而 AOTAhead-of-Time 编译技术更是让这种协作如虎添翼——减少启动时间、降低内存占用甚至能让你在桌面应用中直接嵌入一个轻量级的 Web 服务器。本文将通过两个完整的代码示例带你一步步实现“WPF 引用 ASP.NET Core 的 AOT 版本”并在实战中理解背后的原理。## 为什么要在 WPF 中使用 ASP.NET Core AOT传统 WPF 应用与后端交互时通常需要依赖外部 Web 服务如部署在服务器上的 ASP.NET Core API。但有些场景下我们希望应用自身就具备 Web 服务能力比如- 提供本地 REST API 供其他工具调用如脚本、浏览器扩展。- 实现桌面应用内部的 IPC进程间通信时用 HTTP 比命名管道更灵活。- 利用 ASP.NET Core 强大的路由、中间件和依赖注入特性来组织本地逻辑。而 AOT 编译的优势在于-启动速度极快无需 JIT 编译代码在生成时已编译为机器码。-内存占用低不需要加载庞大的运行时 JIT 编译器。-发布体积小发布时只包含必需的代码适合嵌入式场景。但是WPF 本身是桌面框架ASP.NET Core 是 Web 框架如何将它们“合体”答案是将 ASP.NET Core 的 AOT 版本作为 WPF 项目的依赖并在 WPF 启动时内嵌一个 Web 服务器。## 环境准备与项目结构### 你需要安装- .NET 8.0 SDK 或更高版本因为 AOT 在 .NET 7 中逐步成熟.NET 8 是推荐选择。- Visual Studio 2022 或 JetBrains Rider。- 确保安装“.NET 桌面开发”和“ASP.NET 和 Web 开发”工作负载。### 项目结构建议我们将创建两个项目1.WpfAppWithAotWPF 主项目负责界面显示和启动内嵌 Web 服务器。2.AotApiLibraryASP.NET Core 类库包含 AOT 兼容的 API 端点并编译为 AOT 模式。 为什么不用一个项目因为 WPF 项目不能直接设置为 AOT 编译AOT 主要用于控制台应用或类库但我们可以将 API 逻辑封装到一个独立的 AOT 类库中然后被 WPF 引用。## 第一步创建 ASP.NET Core AOT 类库### 1. 新建类库项目使用命令行创建一个类库项目bashdotnet new classlib -n AotApiLibrary -f net8.0cd AotApiLibrary### 2. 添加必要的 NuGet 包AOT 需要特定的包来支持最小化 API 和 JSON 序列化bashdotnet add package Microsoft.AspNetCore.App.Ref --version 8.0.0dotnet add package System.Text.Json### 3. 编写 AOT 兼容的 API 代码AOT 编译需要避免使用反射和动态代码生成因此我们将使用“最小 API”风格并显式指定 JSON 序列化上下文。创建MyApi.cscsharpusing System.Text.Json.Serialization;// 定义一个简单的模型标记为 JSON 序列化上下文public class GreetingResponse{ public string Message { get; set; } public DateTime Timestamp { get; set; }}// 必须为 AOT 创建 JsonSerializerContext[JsonSerializable(typeof(GreetingResponse))][JsonSerializable(typeof(string))]internal partial class AppJsonSerializerContext : JsonSerializerContext{}创建Startup.cs注意AOT 类库中没有Startup类我们直接构建 WebApplicationcsharpusing Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.DependencyInjection;public class ApiStartup{ // 返回一个配置好的 WebApplication 实例 public static WebApplication CreateApp(string[] args) { var builder WebApplication.CreateSlimBuilder(args); // 明确注册 JSON 序列化上下文避免反射 builder.Services.ConfigureHttpJsonOptions(options { options.SerializerOptions.TypeInfoResolver AppJsonSerializerContext.Default; }); var app builder.Build(); // 定义 GET /greet 端点 app.MapGet(/greet, (string? name) { var response new GreetingResponse { Message $Hello, {name ?? World}!, Timestamp DateTime.UtcNow }; return Results.Json(response, AppJsonSerializerContext.Default.GreetingResponse); }); return app; }}### 4. 配置 AOT 编译编辑AotApiLibrary.csproj添加以下属性xmlPropertyGroup PublishAottrue/PublishAot OptimizationPreferenceSpeed/OptimizationPreference/PropertyGroup然后发布为 AOT 类库注意类库发布 AOT 后会生成.aot文件但我们需要的是 DLL 引用所以这一步只是为了验证编译成功bashdotnet publish -c Release -r win-x64## 第二步创建 WPF 项目并引用 AOT 类库### 1. 新建 WPF 项目bashdotnet new wpf -n WpfAppWithAot -f net8.0### 2. 添加项目引用bashcd WpfAppWithAotdotnet add reference ../AotApiLibrary/AotApiLibrary.csproj### 3. 修改 WPF 的MainWindow.xaml.cs我们将在 WPF 窗口初始化时启动内嵌的 ASP.NET Core 服务器并绑定到一个本地端口。MainWindow.xaml简化版xmlWindow x:ClassWpfAppWithAot.MainWindow xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml TitleWPF ASP.NET Core AOT Height200 Width400 StackPanel VerticalAlignmentCenter HorizontalAlignmentCenter TextBlock Text内嵌 Web 服务器已启动 FontSize16 / Button Content测试 API ClickOnTestApi Margin0,10 / TextBlock x:NameResultText Text等待测试... / /StackPanel/WindowMainWindow.xaml.cs核心代码csharpusing System;using System.Net.Http;using System.Threading.Tasks;using System.Windows;using Microsoft.AspNetCore.Hosting;namespace WpfAppWithAot{ public partial class MainWindow : Window { private IDisposable _webHost; // 用于管理 Web 服务器的生命周期 public MainWindow() { InitializeComponent(); StartWebServer(); } /// summary /// 启动内嵌的 ASP.NET Core AOT Web 服务器 /// /summary private void StartWebServer() { // 注意这里使用 AotApiLibrary 中的 ApiStartup 类 var app AotApiLibrary.ApiStartup.CreateApp(new string[] { --urls, http://localhost:5000 }); _webHost app.RunAsync(); // 异步启动不会阻塞 UI 线程 } /// summary /// 测试按钮点击事件调用本地的 API /// /summary private async void OnTestApi(object sender, RoutedEventArgs e) { try { using var httpClient new HttpClient(); var response await httpClient.GetStringAsync(http://localhost:5000/greet?nameWPF); ResultText.Text $API 返回: {response}; } catch (Exception ex) { ResultText.Text $错误: {ex.Message}; } } /// summary /// 窗口关闭时停止 Web 服务器 /// /summary protected override void OnClosed(EventArgs e) { _webHost?.Dispose(); base.OnClosed(e); } }}### 4. 运行与测试按 F5 运行 WPF 应用你会看到窗口显示“内嵌 Web 服务器已启动”。点击“测试 API”按钮结果将显示从本地 API 返回的 JSON 数据。## 代码示例详解### 示例 1AOT 类库中的 JSON 序列化上下文这段代码的关键在于[JsonSerializable]特性。AOT 编译无法使用System.Text.Json默认的反射式序列化所以我们需要显式声明哪些类型会被序列化。AppJsonSerializerContext继承自JsonSerializerContext它会在编译时生成具体的序列化代码而不是运行时反射。csharp[JsonSerializable(typeof(GreetingResponse))][JsonSerializable(typeof(string))]internal partial class AppJsonSerializerContext : JsonSerializerContext{}注意partial关键字必不可少因为编译器会自动生成AppJsonSerializerContext的实现部分。### 示例 2WPF 中启动内嵌 Web 服务器这里我们调用了AotApiLibrary.ApiStartup.CreateApp它返回一个WebApplication对象。RunAsync()方法会启动服务器并监听端口但由于它是异步的我们需要将其分配给一个IDisposable字段以便在窗口关闭时释放资源。csharpvar app AotApiLibrary.ApiStartup.CreateApp(new string[] { --urls, http://localhost:5000 });_webHost app.RunAsync();潜在问题如果 WPF 的 UI 线程阻塞RunAsync可能不会立即启动。解决方案是确保CreateApp和RunAsync在非 UI 线程上执行但这里RunAsync本身就是异步的不会阻塞。## 进阶优化与调试### 性能对比你可以在 WPF 的OnTestApi中添加计时对比 AOT 版本与普通 JIT 版本的启动时间。通常 AOT 版本的 API 响应时间更稳定首次调用延迟更低。### 端口冲突如果 5000 端口被占用可以动态分配端口csharpvar port new Random().Next(10000, 60000);var app ApiStartup.CreateApp(new[] { $--urlshttp://localhost:{port} });### 发布为单文件WPF 项目也可以结合 AOT 类库发布为单文件应用bashdotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFiletrue## 总结通过本文我们成功实现了1.创建 ASP.NET Core AOT 类库通过[JsonSerializable]和最小 API 模式让代码兼容 AOT 编译。2.在 WPF 中内嵌 Web 服务器利用WebApplication.RunAsync()在桌面应用生命周期内运行 HTTP 服务。3.实现端到端调用WPF 界面通过 HttpClient 调用本地 API获取 JSON 响应。这种架构特别适合需要提供本地 API 的桌面工具、自动化测试框架或轻量级微服务边缘场景。AOT 编译带来的性能提升启动时间减少 50% 以上内存降低 30%让桌面应用也能拥有 Web 服务的灵活性。最后提醒AOT 编译并非万能——它限制了动态代码生成如 EFCore 的 LINQ 查询但如果你坚持使用静态类型和显式序列化AOT 绝对是桌面应用现代化的利器。现在不妨在你的下一个 WPF 项目中尝试一下
RELATED

相关推荐

PTH-RP肽段序列分析及生物活性应用指南

PTH-RP肽段序列分析及生物活性应用指南

1. 肽段序列PTH-RP (140-173) (human)的生物学背景解析 PTH-RP(甲状旁腺激素相关蛋白)是一种在多种组织中表达的多功能蛋白质,其140-173片段在人体生理和病理过程中扮演着重要角色。这个由34个氨基酸组成的肽段序列"TALLWGLKKKKENNRRTHH…

📅 2026/11/15 7:37:50
Unity 2022.3 Android打包报错:Could not resolve all files for configuration 深度解析与解决方案

Unity 2022.3 Android打包报错:Could not resolve all files for configuration 深度解析与解决方案

1. 项目概述:一个困扰无数开发者的“文件解析”拦路虎 “Could not resolve all files for configuration:” 这个报错,对于任何一个使用 Unity 2022.3 或相近版本进行 Android 平台打包的开发者来说,都像是一个不期而遇的“老朋友”。它总是…

📅 2026/10/6 9:56:59
3分钟掌握Video Download Helper:网页视频离线保存的终极解决方案

3分钟掌握Video Download Helper:网页视频离线保存的终极解决方案

3分钟掌握Video Download Helper:网页视频离线保存的终极解决方案 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 在数字内容爆炸…

📅 2026/10/7 19:47:26
MORE NEWS

更多资讯

📰

电工证单开双控内部消息:学历不高也能考,关键看这三步

电工证单开双控内部消息:学历不高也能考,关键看这三步 学历不高怕报不上名?别担心, 电工证单开双控 这个证,只要你能看懂电工图纸、会操作电工工具,基本就没问题。很多培训机构的学员都是初中毕业,照样能一次性通过考试。这事儿不是我瞎说,…

📰

电工证电气维修证保姆级教程:实操考试心里没底怕挂科?手把手带你搞懂

电工证电气维修证保姆级教程:实操考试心里没底怕挂科?手把手带你搞懂 你是不是也这样?手里拿着电工证电气维修证,想着考完就能上岗,结果到了实操考试现场,一紧张就手忙脚乱,怕挂科?别急,这篇保姆级教程就是为你准备的,从报考流程、备考技巧到薪资前…

📰

初级电工作业证题目官方回应怎么考更稳妥

初级电工作业证题目官方回应怎么考更稳妥 实操考试心里没底怕挂科,这是很多准备考初级电工作业证的人的真实写照。特别是像安阳这类中小型施工企业,电工岗位不仅是日常运维的主力,更是安全管理的重中之重。一旦出现操作失误,轻则设备损坏,重则造成人身伤…

📰

电工证考了有用吗?学校里考高级电工证值不值得考

电工证考了有用吗?学校里考高级电工证值不值得考 实操考试心里没底怕挂科?这是很多想考高级电工证的学员最真实的心理状态。尤其是那些在学校里准备报考的学员,面对复杂的实操流程和严格的评分标准,难免会感到焦虑。其实,只要准备得当,通过考试并不难,…

📰

抛丸机特种作业操作证值不值得考?证书过期了不知道怎么复审延期?

抛丸机特种作业操作证值不值得考?证书过期了不知道怎么复审延期? 证书过期了不知道怎么复审延期?你不是一个人。尤其是从事抛丸机操作的特种作业人员,很多都在为操作证复审发愁,甚至有人担心:**抛丸机特种作业操作证值不值得考?**今天咱们就来聊聊…

📰

无为哪里有考电工证内部消息全公开,电工证不考真要失业

无为哪里有考电工证内部消息全公开,电工证不考真要失业 现在找工作,没有电工证根本进不去门。工地、工厂、电力公司,哪个地方不要电工证?很多人问【无为哪里有考电工证】,其实这不是问题,关键是你有没有搞清楚流程。别再等了,现在不考,明年就可能真的…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬