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
相关产品推荐
相关产品推荐

