現如今大部分服務都會有用戶輸入,為了服務的正常運行,很多時候不得不針對輸入進行敏感詞的檢測、替換,如果人工做這樣的作業,不僅效率低,成本也高,所以,先讓代碼去處理輸入,成為了經濟方便的途徑,水弟在這里寫了一個讓小編姐姐都覺得快的敏感詞組件接入示例,不需要依賴第三方服務,只需兩分鐘即可享受清爽文字,
ToolGood.Words
首先我們要使用的開源組件是 ToolGood.Words

通過簡單的了解,我們可以知道它可以針對敏感詞及其拼音、跳詞等變形進行檢測,在實際的應用場景中能滿足大部分的需求,
具體的用法在這里不做過多的介紹,接下來我們需要做的事情是如何在現有代碼中快速且方便的情況下接入敏感詞組件,很顯然,如果我們按照組件寫的示例去操作,會發現需要在現有的代碼中進行大量重構的操作,這顯然會累垮 VS ,熟悉水弟的朋友首先就會想到使用 AOP 的方式去優化處理,(這里不過多介紹AOP,如果想了解更多,請移步 C# 中使用面向切面編程(AOP)中實踐代碼整潔 )
ValidationAttribute
我們先定義兩個簡單的模型來系結輸入引數,一個是只要輸入含有敏感詞就會報錯,一個是只要輸入含有敏感詞就會把相關的字串替換為 * ,代碼如下:
public class MinganCheckInput
{
[MinGanCheck]
public string Text { get; set; }
}
public class MinganReplaceInput
{
[MinGanReplace]
public string Text { get; set; }
}
其中 [MinGanCheck] 和 [MinGanReplace] 是我們定義的特性標記,將其繼承 ValidationAttribute,就和我們常用的 [Required] 一樣方便,哪里敏感點哪里,
/// <summary>
/// 敏感詞檢查的特性,一匹配就拋例外
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class MinGanCheck : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 敏感詞替換
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class MinGanReplace : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return ValidationResult.Success;
}
}
接下來就是實作 ValidationAttribute 的功能,如果看過水弟寫過的 aop 文章,這時候就不會直接在校驗的方法中直接引入 ToolGood.Words ,這樣會帶來很大的耦合,也不便于我們替換為其他的敏感詞組件或服務,所以我們只要再多一層抽象就可以了,
// 檢查
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return validationContext.GetService<IMinGanCheckValidator>().IsValid(value, validationContext);
}
// 替換
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
validationContext.GetService<IMinGanReplaceValidator>().IsValid(value, validationContext);
return ValidationResult.Success;
}
接著我們分別實作 IMinGanCheckValidator 和 IMinGanReplaceValidator 的功能,也即檢查和替換功能,
// 檢查
public class MinGanCheckValidator : IMinGanCheckValidator
{
public ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value is string v)
{
if (!String.IsNullOrEmpty(v))
{
// 文字檢查
if (MinGanProvider.Instance.IllegalWordsSearch.ContainsAny(v))
{
return new ValidationResult("存在敏感詞", new[] { validationContext.MemberName });
}
// 檢查拼音
if (MinGanProvider.Instance.IllegalWordsSearch.ContainsAny(WordsHelper.GetPinyin(v)))
{
return new ValidationResult("存在敏感詞",new []{ validationContext.MemberName });
}
// todo:其他變種
}
}
return ValidationResult.Success;
}
}
//替換
public class MinGanReplaceValidator : IMinGanReplaceValidator
{
public void Replace(object value, ValidationContext validationContext)
{
if (value is string v)
{
if (!String.IsNullOrEmpty(v))
{
v = MinGanProvider.Instance.IllegalWordsSearch.Replace(v);
SetPropertyByName(validationContext.ObjectInstance,validationContext.MemberName, v);
}
}
}
static bool SetPropertyByName(Object obj, string name, Object value)
{
var type = obj.GetType();
var prop = type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
if (null == prop || !prop.CanWrite) return false;
prop.SetValue(obj, value, null);
return true;
}
}
其中 MinGanProvider.Instance.IllegalWordsSearch 是 ToolGood.Words 中的檢測類單例,這里不詳細展開,這樣我們就有一個大概能用的敏感詞檢測組件了,然而在實際程序中,我們還需要對敏感詞進行管理,特別是需要實時更新敏感詞,
敏感詞熱多載
以 json 組態檔存放敏感詞為例,只需要配置熱多載就行了,
首先是 Program.cs 檔案中讓 json 組態檔熱多載,
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddJsonFile("IllegalKeywords.json", optional: false, reloadOnChange: true);// 配置可熱多載
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
最后是在 Startup.cs 中檔案處理多載事件,
ChangeToken.OnChange(() => Configuration.GetReloadToken(), () =>
{
// 敏感詞多載
var keys= Configuration.GetSection("IllegalKeywords").Get<List<string>>();
if (keys!=null&&keys.Any())
{
var allKeys = new List<string>();
foreach (var k in keys)
{
allKeys.Add(k); // 增加詞匯
allKeys.Add(WordsHelper.ToTraditionalChinese(k)); // 增加繁體
allKeys.Add(WordsHelper.GetPinyin(k)); // 增加拼音
}
IllegalWordsSearch.SetKeywords(allKeys);
}
});
效果


結語
看到這里,可能有些人已經罵罵咧咧退出網站,說好的兩分鐘,光是看文章和復制代碼都需要十幾分鐘,所以為了滿足伸手黨的需求,我寫了一個簡單的示例,只要把對應檔案和代碼復制到代碼就可以使用了,真的不超過2分鐘就能實作敏感詞檢測,
專案地址:https://github.com/jonechenug/ToolGood.Words.Sample

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/285359.html
標籤:.NET Core
