You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI桌面应用中如何让wwwroot内新生成的图片即时显示?

MAUI/Razor桌面应用图片生成后无法即时显示的解决办法

问题描述

我有一个面向桌面应用的MAUI/Razor项目,点击「Create Chart」按钮后,会在wwwroot/chart/目录下生成新的图片,但该图片无法在应用中即时显示,只有重启应用后才会出现。如何让图片在生成后立即显示?是否需要重载wwwroot?

现有代码

Razor页面代码

@page "/notfallberechnung"

<div class="row">
    <div class="row">
        <div class="col-5">
            <button @onclick="CreateChartAsync">Create Chart</button>
        </div>
    </div>
    <br />
    <br />
    <div class="row">
        <div class="col-5">            
            <ImageViewer Url="@currentChartPath" FitMode="ObjectFitMode.Fill" />
        </div>
    </div>
</div>

C#后台代码

using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components;
using System.Drawing;

namespace Expo.Pages
{
    public partial class Notfallberechnung : ComponentBase
    {
        private string currentChartPath = "./chart/Mode-5000.bmp";
        public async void CreateChartAsync()
        {
            var n = new Bitmap(314, 314);
            using (var g = Graphics.FromImage(n))
            {                   
                g.DrawString("hallo test", new System.Drawing.Font("Tahoma", 8), new SolidBrush(System.Drawing.Color.Red), 200, 200);
            }
            int length = AppDomain.CurrentDomain.BaseDirectory.LastIndexOf(AppDomain.CurrentDomain.FriendlyName) + AppDomain.CurrentDomain.FriendlyName.Length + 1;
            string sub = AppDomain.CurrentDomain.BaseDirectory.Substring(0, length);
            var fileName = sub + "wwwroot\\chart\\Mode-5000.bmp";
            n.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);              
            StateHasChanged();
        }
    }
}

问题原因

  1. WebView缓存机制:Blazor WebView会缓存静态资源,即使文件已更新,仍会加载缓存版本,只有重启应用才会重新读取文件。
  2. 组件未触发更新:currentChartPath的值没有变化,ImageViewer组件不会主动重新请求资源。
  3. wwwroot特性限制:MAUI/Razor中wwwroot是静态资源目录,运行时不会自动监测文件变化并重载,无需也无法直接重载整个wwwroot。

解决办法

方法1:添加随机参数规避缓存

在图片URL后添加时间戳或随机字符串,让WebView认为是新资源,强制重新加载:

public async Task CreateChartAsync() // 修正异步方法签名,替换async void为async Task
{
    var n = new Bitmap(314, 314);
    using (var g = Graphics.FromImage(n))
    {                   
        g.DrawString("hallo test", new System.Drawing.Font("Tahoma", 8), new SolidBrush(System.Drawing.Color.Red), 200, 200);
    }
    // 优化路径获取方式,避免硬编码错误
    var fileName = Path.Combine(AppContext.BaseDirectory, "wwwroot", "chart", "Mode-5000.jpg");
    n.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
    // 添加时间戳参数,触发资源重新加载
    currentChartPath = $"./chart/Mode-5000.jpg?t={DateTime.Now.Ticks}";
    StateHasChanged();
}

注:原代码中保存格式是Jpeg但路径后缀是bmp,建议统一后缀避免混淆。

方法2:使用Base64直接传递图片(更高效)

无需保存到文件系统,直接将图片转为Base64字符串传递给组件,跳过缓存和文件读取问题:

private string currentChartBase64;

public async Task CreateChartAsync()
{
    using var n = new Bitmap(314, 314);
    using (var g = Graphics.FromImage(n))
    {                   
        g.DrawString("hallo test", new System.Drawing.Font("Tahoma", 8), new SolidBrush(System.Drawing.Color.Red), 200, 200);
    }
    // 将图片转为Base64格式
    using var ms = new MemoryStream();
    n.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    var bytes = ms.ToArray();
    currentChartBase64 = $"data:image/jpeg;base64,{Convert.ToBase64String(bytes)}";
    StateHasChanged();
}

修改Razor中的ImageViewer:

<ImageViewer Url="@currentChartBase64" FitMode="ObjectFitMode.Fill" />

方法3:优化路径获取方式(可选)

原代码中获取wwwroot路径的方式复杂易出错,可通过注入IWebHostEnvironment获取标准路径:

[Inject]
private IWebHostEnvironment Env { get; set; }

public async Task CreateChartAsync()
{
    // ... 生成图片代码 ...
    var fileName = Path.Combine(Env.WebRootPath, "chart", "Mode-5000.jpg");
    n.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
    // ... 更新路径代码 ...
}

问题效果对比

图片已生成但未显示(原问题)

图片已生成但未显示1
图片已生成但未显示2
图片已生成但未显示3
图片已生成但未显示4

重启应用后显示(原正常效果)

重启后显示1
重启后显示2


内容的提问来源于stack exchange,提问作者Üh Lieh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 18:22:36