如何从.NET Framework C# Windows应用触发.NET Core Blazor网页调用LoadData方法
实现Windows应用变更时自动更新Blazor页面数据的方案
下面提供几种实用的实现方式,可根据你的场景需求选择:
方案一:使用SignalR实现实时通知(推荐)
这是适配实时场景的最优方案,SignalR会自动处理连接管理、断线重连等底层细节,无需手动维护复杂的通信逻辑。
步骤1:在Blazor项目中配置SignalR
- 安装NuGet包:
Microsoft.AspNetCore.SignalR - 创建SignalR Hub类,定义通知客户端的方法:
using Microsoft.AspNetCore.SignalR; public class DataUpdateHub : Hub { // 触发所有连接客户端的更新事件 public async Task NotifyDataChanged() { await Clients.All.SendAsync("OnDataChanged"); } }
- 在
Program.cs中注册SignalR服务并配置跨域与端点:
var builder = WebApplication.CreateBuilder(args); // 注册SignalR服务 builder.Services.AddSignalR(); // 配置CORS,允许Windows应用跨域访问 builder.Services.AddCors(options => { options.AddPolicy("AllowWindowsApp", policy => { policy.WithOrigins("http://localhost:你的Windows应用端口") // 替换为实际地址 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); var app = builder.Build(); app.UseCors("AllowWindowsApp"); // 映射SignalR Hub的访问端点 app.MapHub<DataUpdateHub>("/dataUpdateHub"); // 其他中间件配置(如路由、静态文件等) app.Run();
- 在Blazor页面中监听SignalR通知,触发数据更新:
@page "/your-target-page" @inject HubConnectionBuilder HubConnectionBuilder @implements IAsyncDisposable private HubConnection? _hubConnection; protected override async Task OnInitializedAsync() { _hubConnection = HubConnectionBuilder.WithUrl("http://localhost:Blazor项目端口/dataUpdateHub") .Build(); // 监听服务器发来的变更通知 _hubConnection.On("OnDataChanged", async () => { await LoadData(); StateHasChanged(); // 通知页面刷新 }); try { await _hubConnection.StartAsync(); } catch (Exception ex) { Console.WriteLine($"SignalR连接失败:{ex.Message}"); } } private async Task LoadData() { // 你的页面数据加载逻辑 } public async ValueTask DisposeAsync() { if (_hubConnection != null) { await _hubConnection.DisposeAsync(); } }
步骤2:在Windows应用中发送SignalR通知
- 安装NuGet包:
Microsoft.AspNetCore.SignalR.Client - 在Windows应用的变更逻辑(如数据保存、修改完成后)中添加通知代码:
using Microsoft.AspNetCore.SignalR.Client; // 建议全局单例维护连接,避免重复创建 var hubConnection = new HubConnectionBuilder() .WithUrl("http://localhost:Blazor项目端口/dataUpdateHub") .Build(); try { await hubConnection.StartAsync(); } catch (Exception ex) { Console.WriteLine($"连接SignalR服务失败:{ex.Message}"); } // 当数据发生变更时,调用Hub方法通知所有客户端 await hubConnection.InvokeAsync("NotifyDataChanged"); // 应用退出时关闭连接 await hubConnection.DisposeAsync();
方案二:REST API + 客户端轮询(简单场景)
如果不需要强实时性(比如允许几秒延迟),这个方案实现成本更低,无需维护长连接。
步骤1:Blazor项目添加变更标记API
创建API控制器,用于记录数据变更状态:
[ApiController] [Route("api/[controller]")] public class DataChangeController : ControllerBase { // 用静态变量记录最后一次变更时间(生产环境可改用数据库或缓存) private static DateTime _lastChangeTime = DateTime.Now; // 供Windows应用调用,更新变更时间戳 [HttpPost("mark-changed")] public IActionResult MarkChanged() { _lastChangeTime = DateTime.Now; return Ok(); } // 供Blazor页面查询是否有新变更 [HttpGet("has-changed")] public IActionResult HasChanged([FromQuery] DateTime lastCheckTime) { return Ok(_lastChangeTime > lastCheckTime); } }
步骤2:Windows应用触发变更标记
当Windows应用数据发生变更时,调用API更新标记:
using System.Net.Http; var httpClient = new HttpClient(); await httpClient.PostAsync("http://localhost:Blazor项目端口/api/datachange/mark-changed", null);
步骤3:Blazor页面轮询检查变更
在Blazor页面中定时查询API,发现变更则更新数据:
@page "/your-target-page" @inject HttpClient HttpClient @implements IAsyncDisposable private PeriodicTimer? _checkTimer; private DateTime _lastCheckTime = DateTime.Now; protected override async Task OnInitializedAsync() { // 每5秒检查一次(可根据需求调整间隔) _checkTimer = new PeriodicTimer(TimeSpan.FromSeconds(5)); _ = CheckForChangesAsync(); } private async Task CheckForChangesAsync() { while (await _checkTimer.WaitForNextTickAsync()) { var hasChanged = await HttpClient.GetFromJsonAsync<bool>( $"api/datachange/has-changed?lastCheckTime={_lastCheckTime:o}" ); if (hasChanged) { await LoadData(); _lastCheckTime = DateTime.Now; StateHasChanged(); } } } private async Task LoadData() { // 你的页面数据加载逻辑 } public async ValueTask DisposeAsync() { _checkTimer?.Dispose(); }
方案三:自定义WebSocket通信(复杂定制场景)
如果需要完全自定义通信协议或处理逻辑,可以直接使用原生WebSocket:
步骤1:Blazor项目配置WebSocket端点
在Program.cs中添加WebSocket支持:
var app = builder.Build(); app.UseWebSockets(); // 配置WebSocket端点 app.Map("/data-ws", async context => { if (!context.WebSockets.IsWebSocketRequest) { context.Response.StatusCode = StatusCodes.Status400BadRequest; return; } using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); var buffer = new byte[1024 * 4]; // 维护客户端连接列表(生产环境需考虑线程安全) // 此处简化处理,可根据需求扩展为广播逻辑 while (webSocket.State == WebSocketState.Open) { var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); // 收到消息后可转发给其他客户端,或直接在Blazor页面监听 } }); // 其他中间件配置 app.Run();
步骤2:Windows应用作为WebSocket客户端发送消息
using System.Net.WebSockets; using System.Text; var clientSocket = new ClientWebSocket(); await clientSocket.ConnectAsync(new Uri("ws://localhost:Blazor项目端口/data-ws"), CancellationToken.None); // 发送变更通知消息 var messageBytes = Encoding.UTF8.GetBytes("data-updated"); await clientSocket.SendAsync( new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, endOfMessage: true, CancellationToken.None ); // 关闭连接 await clientSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "操作完成", CancellationToken.None);
步骤3:Blazor页面监听WebSocket消息
@page "/your-target-page" @implements IAsyncDisposable private WebSocket? _webSocket; protected override async Task OnInitializedAsync() { _webSocket = new ClientWebSocket(); await _webSocket.ConnectAsync(new Uri("ws://localhost:Blazor项目端口/data-ws"), CancellationToken.None); _ = ListenForUpdatesAsync(); } private async Task ListenForUpdatesAsync() { var buffer = new byte[1024 * 4]; while (_webSocket.State == WebSocketState.Open) { var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); var message = Encoding.UTF8.GetString(buffer, 0, result.Count); if (message == "data-updated") { await LoadData(); StateHasChanged(); } } } private async Task LoadData() { // 你的页面数据加载逻辑 } public async ValueTask DisposeAsync() { if (_webSocket != null && _webSocket.State == WebSocketState.Open) { await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "页面销毁", CancellationToken.None); } }
内容的提问来源于stack exchange,提问作者MHD
相关产品推荐
相关产品推荐

