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

MAUI C#跨平台键值存储:修复报错并实现通用存读函数

MAUI 跨平台键值对通用存储实现及JSON异常解决

你碰到的System.Text.Json.JsonException本质是读取的目标文件不存在、内容为空,或是非有效JSON格式——比如首次读取某个键时,还从未写入过对应数据,文件本身就没创建,直接读取自然会触发解析错误。

下面是封装好的跨平台通用存储类,包含泛型的保存/读取方法,自动处理路径、文件存在性、异常捕获等问题:

using System.Text.Json;
using System.IO;

public class StorageService
{
    // JSON序列化配置,支持自定义类、DateTime等更多类型
    private readonly JsonSerializerOptions _jsonOptions = new()
    {
        WriteIndented = true,
        PropertyNameCaseInsensitive = true,
        IncludeFields = true
    };

    // 获取MAUI跨平台应用私有存储路径
    private string GetFilePath(string key)
    {
        var directory = FileSystem.AppDataDirectory;
        return Path.Combine(directory, $"{key}.json");
    }

    /// <summary>
    /// 保存任意类型数据到文件
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="key">唯一标识键</param>
    /// <param name="data">要保存的数据</param>
    public async Task SaveAsync<T>(string key, T data)
    {
        var filePath = GetFilePath(key);
        var json = JsonSerializer.Serialize(data, _jsonOptions);
        await File.WriteAllTextAsync(filePath, json);
    }

    /// <summary>
    /// 通过键读取任意类型数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="key">唯一标识键</param>
    /// <returns>读取到的数据,无数据时返回类型默认值</returns>
    public async Task<T?> LoadAsync<T>(string key)
    {
        var filePath = GetFilePath(key);
        
        // 先检查文件是否存在
        if (!File.Exists(filePath))
            return default;

        try
        {
            var json = await File.ReadAllTextAsync(filePath);
            // 处理空文件情况
            if (string.IsNullOrWhiteSpace(json))
                return default;
            
            return JsonSerializer.Deserialize<T>(json, _jsonOptions);
        }
        catch (JsonException)
        {
            // 若JSON格式损坏,返回默认值(可根据需求调整为删除损坏文件或抛出异常)
            return default;
        }
    }
}

使用示例

  1. 存储/读取自定义类:
// 自定义测试类
public class UserInfo
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime RegisterDate { get; set; }
}

// 实例化存储服务
var storage = new StorageService();

// 保存数据
await storage.SaveAsync("current_user", new UserInfo
{
    Name = "John",
    Age = 30,
    RegisterDate = DateTime.Now
});

// 读取数据
var user = await storage.LoadAsync<UserInfo>("current_user");
if (user != null)
{
    // 使用读取到的user数据
}
  1. 存储/读取简单类型:
// 保存字符串
await storage.SaveAsync("app_theme", "dark");
// 读取字符串
var theme = await storage.LoadAsync<string>("app_theme");

// 保存整数
await storage.SaveAsync("login_count", 5);
// 读取整数
var count = await storage.LoadAsync<int>("login_count");

异常解决关键

  • 先判断文件存在性:读取前必须检查文件是否存在,避免读取不存在的文件触发解析错误
  • 处理空文件/无效JSON:即使文件存在,也可能为空或格式损坏,需捕获JsonException并返回默认值
  • 使用MAUI标准存储路径:用FileSystem.AppDataDirectory确保iOS/Android/Windows等平台路径统一
  • 配置JSON序列化选项:通过JsonSerializerOptions支持自定义类、大小写不敏感、字段序列化等场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 04:32:23