现如今大部分服务都会有用户输入,为了服务的正常运行,很多时候不得不针对输入进行敏感词的检测、替换。如果人工做这样的工作,不仅效率低,成本也高。所以,先让代码去处理输入,成为了经济方便的途径。水弟在这里写了一个让小编姐姐都觉得快的敏感词组件接入示例,不需要依赖第三方服务,只需两分钟即可享受清爽文字。

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;
}

接着我们分别实现 IMinGanCheckValidatorIMinGanReplaceValidator 的功能,也即检查和替换功能。

// 检查
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.IllegalWordsSearchToolGood.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

.Net 中两分钟集成敏感词组件的更多相关文章

  1. (转)两种高效过滤敏感词算法--DFA算法和AC自动机算法

    原文:https://blog.csdn.net/u013421629/article/details/83178970 一道bat面试题:快速替换10亿条标题中的5万个敏感词,有哪些解决思路? 有十 ...

  2. java实现敏感词过滤(DFA算法)

    小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...

  3. js检测文章敏感词

    在一些博客或者论坛中,文章中的敏感词需要显示出来和高亮显示起到提示用户的作用.这个功能实现的方法有很多,下面是js的实现方式. //将文章中匹配到的敏感词罗列出来 <span style=&qu ...

  4. 转,敏感词过滤,PHP实现的Trie树

    原文地址:http://blog.11034.org/2012-07/trie_in_php.html 项目需求,要做敏感词过滤,对于敏感词本身就是一个CRUD的模块很简单,比较麻烦的就是对各种输入的 ...

  5. [转载]敏感词过滤,PHP实现的Trie树

    原文地址:http://blog.11034.org/2012-07/trie_in_php.html 项目需求,要做敏感词过滤,对于敏感词本身就是一个CRUD的模块很简单,比较麻烦的就是对各种输入的 ...

  6. 5分钟Serverless实践 | 构建无服务器的敏感词过滤后端系统

    前言 在上一篇“5分钟Serverless实践”系列文章中,我们介绍了什么是Serverless,以及如何构建一个无服务器的图片鉴黄Web应用,本文将延续这个话题,以敏感词过滤为例,介绍如何构建一个无 ...

  7. 5分钟构建无服务器敏感词过滤后端系统(基于FunctionGraph)

    摘要:开发者通过函数工作流,无需配置和管理服务器,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统.托管函数具备以毫秒级弹性伸缩.免运维.高可靠的方式运行,极大地提高了开发和运维效率,减小 ...

  8. vue中检测敏感词,锚点

    当发布文章的时候,标题有敏感词 则检测有敏感词的接口成功的时候,写锚点 eg: _this .$alert("检测到标题有敏感词,请修改后再发布", "提示", ...

  9. Unity中使用的一套敏感词过滤方式

    当项目中的敏感词数量不是很多的时候,直接用数组来遍历过滤其实也可以,但是具体的数量有多大,这个肯定不好说,因此,对.txt中的敏感词合理组织后再进行过滤就显得非常有必要了. 如上图,左边是txt中配置 ...

随机推荐

  1. BZOJ_2844 albus就是要第一个出场 【线性基】

    一.题目 albus就是要第一个出场 二.分析 非常有助于理解线性基的一题. 构造线性基$B$后,如果$|A| > |B|$,那么就意味着有些数可以由$B$中的数异或出来,而多的数可以取或者不取 ...

  2. POJ_1227 Jack Straws 【二维平面判两线段相交】

    一 题面 POJ1127 二 分析 在平面几何中,判断两线段相交的方法一般是使用跨立实验.但是这题考虑了非严格相交,即如何两个线段刚好端点相交则也是相交的,所以还需要使用快速排斥实验. 这里参考并引用 ...

  3. 2019 GDUT Rating Contest I : Problem A. The Bucket List

    题面: A. The Bucket List Input file: standard input Output file: standard output Time limit: 1 second Me ...

  4. DEV表格设置列不可编辑

    现在是可编辑的 Run Designer--Columns--Column options下的AllowEdit属性改为false即可

  5. python3 byte,int,str转换

    1 # bytes 与 int 2 b=b'\x01\x02' 3 num=int.from_bytes(b,'little') 4 print('bytes转int:',num) 5 6 b1=nu ...

  6. 一些DevTools的小技巧-让你不止会console.log()

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文参考:https://www.sitepoint.com/beyond-console-log-leve ...

  7. 【FreeRTOS】cpu利用率统计

    目录 前言 概念 作用 必看点 实现 添加几个宏定义 源码 FreeRTOS STM32 定时器 简要说明 前言 本笔记基于 stm32+FreeRTOS. 主要参考野火.安富莱. 概念 简单概要: ...

  8. Netflix业务运维分析和总结

    目录 Netflix工作环境的分析和思考 为什么Netflix会做得如此极致? 海量业务规模下的技术架构和挑战 更加合理的组织架构和先进的工具体系及理念 自由与责任并存的企业文化 当前问题: 精选提问 ...

  9. B. 【例题2】雷达装置

    B . [ 例 题 2 ] 雷 达 装 置 B. [例题2]雷达装置 B.[例题2]雷达装置 题目解析 求最少所需的雷达数,考虑贪心算法. 以这张图为例.以一个城市为中心,作一个半径为 d d d的圆 ...

  10. Google不兼容ShowModalDialog()弹出对话框的解决办法

    <script type="text/javascript"> //弹窗函数 function openDialog() { var url = "https ...