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

UWP中使用Newtonsoft.Json序列化对象数组为JSON并保存时内容缺失及格式异常问题求助

解决UWP中Newtonsoft.Json序列化JSON截断与格式异常的问题

你的代码里有两个核心问题导致了这些异常:异步操作处理不当引发流写入不完整,以及Newtonsoft.Json的默认序列化配置不符合你的键名要求,再加上UWP文件流操作的规范问题,我们一步步来修复:

1. 异步操作未正确等待,导致内容截断

你的SaveModel是同步方法,但调用了异步的openSaveFile却没有等待它完成。这会导致后续文件操作可能在用户还没选好文件就执行,就算文件选中了,流操作也会因为没正确释放资源而截断内容。另外,直接在UWP里用FileStream不是推荐做法,应该用StorageFile提供的异步流API适配沙箱环境。

2. 序列化默认行为导致键名大小写变更

Newtonsoft.Json默认会把C#类的首字母大写属性名直接作为JSON键名,但你需要的是小写键名(比如tag而非Tag),所以要么给类属性加特性指定键名,要么配置序列化器实现统一小写键名。

修正后的完整代码

首先确保你的数据模型类(比如命名为IntentModel)正确配置:

public class IntentModel
{
    [JsonProperty("tag")]
    public string Tag { get; set; }

    [JsonProperty("patterns")]
    public List<string> Patterns { get; set; }

    [JsonProperty("responces")] // 注意你输入里的拼写是responces而非responses
    public List<string> Responces { get; set; }
}

然后修改保存相关方法,正确处理异步和流:

private async void btn_saveModel_Click(object sender, RoutedEventArgs e)
{
    await SaveModelAsync();
}

private async Task<StorageFile> OpenSaveFileAsync()
{
    var savePicker = new Windows.Storage.Pickers.FileSavePicker();
    savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
    savePicker.FileTypeChoices.Add("JSON", new List<string>() { ".json" });
    savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });
    savePicker.SuggestedFileName = "New Data";
    return await savePicker.PickSaveFileAsync();
}

private async Task SaveModelAsync()
{
    var file = await OpenSaveFileAsync();
    if (file != null)
    {
        // 使用UWP推荐的异步流写入方式
        using (var stream = await file.OpenStreamForWriteAsync())
        using (var writer = new StreamWriter(stream))
        using (var jsonWriter = new JsonTextWriter(writer))
        {
            JsonSerializer serializer = new JsonSerializer();
            // 如果你不想给每个属性加JsonProperty,可以用这个配置统一转小写开头
            // serializer.ContractResolver = new CamelCasePropertyNamesContractResolver();
            serializer.Formatting = Formatting.Indented; // 格式化输出,和输入格式一致
            serializer.Serialize(jsonWriter, LoadedIntents);
        }
        // using块会自动释放资源,确保所有内容完整写入文件
    }
}

关键修复点说明

  • 异步方法正确等待:把按钮点击事件改为async void,保存方法改为async Task,确保文件选择完成后再执行写入操作。
  • UWP安全流操作:用OpenStreamForWriteAsync()替代直接创建FileStream,适配UWP沙箱权限模型。
  • 序列化配置:通过JsonProperty特性明确指定JSON键名,或者用CamelCasePropertyNamesContractResolver统一转驼峰式小写开头,解决键名大小写问题。
  • using语句释放资源:确保流、写入器等资源被正确释放,避免内容未完全写入就被截断。

另外你输出里第一个对象的tag变成greetings且patterns多了该值,可能是LoadedIntents数据在保存前被意外修改了,建议检查保存前LoadedIntents的内容是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:12:42