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

.NET MAUI Blazor访问RCL静态文件:Windows正常Android报错求助

跨平台不一致的原因及解决方法

核心原因

Windows和Android平台对RCL(Razor类库)中嵌入资源的打包/读取逻辑存在差异:

  • Windows平台:当你将RCL的静态文件设置为「嵌入资源」+「始终复制」时,MAUI会将这些文件复制到主应用的输出目录中,形成真实的文件路径,因此FileSystem.OpenAppPackageFileAsync能正常找到并读取文件。
  • Android平台:APK打包时,标记为「嵌入资源」的文件会被直接嵌入到RCL的程序集(.dll)中,不会以独立物理文件的形式存在于APK的包目录里。FileSystem.OpenAppPackageFileAsync是用于读取包内物理文件的API,自然找不到嵌入在程序集里的资源,因此抛出异常。

解决方法

根据你的需求(读取流/字节数组),有两种可靠的处理方式:

方式一:直接读取程序集嵌入资源(推荐,因为你已设置为嵌入资源)

既然文件已经是嵌入资源,直接从RCL的程序集中读取即可,跨平台通用:

  1. 确定嵌入资源的完整名称:默认命名规则为[RCL项目命名空间].[目录层级].[文件名],例如你的RCL命名空间是BlazorAppCore,文件路径是wwwroot/sample-data/test.json,则资源名为BlazorAppCore.wwwroot.sample-data.test.json。
  2. 通过RCL中的任意类型获取其程序集,再读取资源流:
using System.Reflection;
using System.IO;

// 用RCL项目中的任意类来获取程序集(替换为你实际的类型)
var rclAssembly = typeof(BlazorAppCore.YourRclClass).Assembly;
// 替换为你的资源完整名称
var resourceFullName = "BlazorAppCore.wwwroot.sample-data.your-file-name.ext";

// 读取嵌入资源流
using var resourceStream = rclAssembly.GetManifestResourceStream(resourceFullName);
if (resourceStream == null)
{
    // 处理资源不存在的情况
    throw new FileNotFoundException("指定的嵌入资源不存在", resourceFullName);
}

// 转换为字节数组(如果需要)
using var memoryStream = new MemoryStream();
await resourceStream.CopyToAsync(memoryStream);
byte[] fileBytes = memoryStream.ToArray();
  1. 验证资源名称:可以通过rclAssembly.GetManifestResourceNames()方法列出该程序集所有嵌入资源,确认你要读取的资源名称是否正确。

方式二:调整文件属性,让Android将文件打包为物理文件

如果你坚持要用FileSystem.OpenAppPackageFileAsync读取,可修改RCL中静态文件的属性:

  • 将「生成操作」从「嵌入资源」改为内容
  • 保持「复制到输出目录」为「始终复制」

这样MAUI在打包Android APK时,会将这些文件复制到APK的assets/wwwroot/sample-data/目录下,此时FileSystem.OpenAppPackageFileAsync("wwwroot/sample-data/your-file-name.ext")就能在Windows和Android上正常工作。

内容的提问来源于stack exchange,提问作者slodki1997

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 07:35:20