读取JSON字符串数组实现脏话检测功能失效的问题排查
排查脏话检测失效的问题
我帮你梳理下几个可能导致检测完全失效的核心问题,按优先级逐一分析:
1. 结构体属性的私有Setter导致反序列化失败
这是最可能的根本原因:你的ProfanityJson结构体中,badwords属性的setter是private的。Json.NET(也就是你用的JsonConvert)默认无法对私有setter进行赋值,反序列化后profanityJson.badwords会是null或者空数组——这样不管输入什么内容,ProfanityCheck里的badWords.Any(...)都会返回false,自然不会触发检测逻辑。
解决方案
把setter改为public即可:
public struct ProfanityJson { [JsonProperty("badwords")] public string[] badwords { get; set; } // 移除private修饰符 }
如果坚持要保留私有setter,可以给JsonProperty添加访问权限配置:
public struct ProfanityJson { [JsonProperty("badwords", Access = JsonPropertyAccess.Read)] public string[] badwords { get; private set; } }
2. JSON文件路径不正确
你在GetProfanity()里用了相对路径"profanity.json",但程序运行时的工作目录可能和你存放JSON文件的目录不一致,导致读取文件失败,最终json是空字符串,反序列化后badwords同样为空。
解决方案
- 右键项目中的
profanity.json文件,在属性里设置“复制到输出目录”为如果较新则复制,这样文件会被复制到程序运行的输出目录中; - 或者用程序所在目录拼接绝对路径,避免相对路径的问题:
public static string[] GetProfanity() { var jsonPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "profanity.json"); var json = string.Empty; using (var fs = File.OpenRead(jsonPath)) using (var sr = new StreamReader(fs, new UTF8Encoding(false))) json = sr.ReadToEnd(); var profanityJson = JsonConvert.DeserializeObject<ProfanityJson>(json); return profanityJson.badwords ?? Array.Empty<string>(); // 加个空值保护 }
3. 异步方法中误用Thread.Sleep(非检测失效原因,但会引发其他问题)
虽然这个不会导致检测失效,但在Discord.NET的异步命令里用Thread.Sleep(3000)会阻塞当前线程,影响其他命令的响应。应该换成异步的延迟方法:
// 替换Thread.Sleep(3000);为: await Task.Delay(3000).ConfigureAwait(false);
4. 性能优化建议(可选)
每次调用ProfanityCheck都重新读取文件并反序列化,效率很低。可以把脏话数组缓存起来,避免重复IO操作:
private static string[] _cachedBadWords; public static string[] GetProfanity() { if (_cachedBadWords != null) return _cachedBadWords; var jsonPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "profanity.json"); var json = string.Empty; using (var fs = File.OpenRead(jsonPath)) using (var sr = new StreamReader(fs, new UTF8Encoding(false))) json = sr.ReadToEnd(); var profanityJson = JsonConvert.DeserializeObject<ProfanityJson>(json); _cachedBadWords = profanityJson.badwords ?? Array.Empty<string>(); return _cachedBadWords; }
内容的提问来源于stack exchange,提问作者Aarav Navani
相关产品推荐
相关产品推荐

