首页 > 其他分享 >封装通用.Net5 敏感词过滤类库

封装通用.Net5 敏感词过滤类库

时间:2022-11-17 11:45:38浏览次数:78  
标签:类库 封装 KeywordProvider value var new Net5 public validationContext

封装通用.Net5 敏感词过滤类库

简介

基于.Net5+ToolGood.Words封装,具备敏感词配置热重载,使用方式引用类库,通过services.AddKeywordSetUp();扩展方法注入服务,在需要进行敏感词校验的字段上增肌[KeywordReplace][KeywordCheck]特性即可。

省流:带有演示demo,github源码链接,下载直接用就行,使用起来极其方便,只需要在需要校验的地方添加一个特性即可。

项目结构

单独的类库项目,只有数个clsaa类,简明介绍下每个类的作用即可。

IKeywordCheckValidator.cs:关键词检查接口

public interface IKeywordCheckValidator
{
    ValidationResult IsValid(object value, ValidationContext validationContext);
}

IKeywordReplaceValidator.cs:关键词替换接口

public interface IKeywordReplaceValidator
{
    void Replace(object value, ValidationContext validationContext);
}

KeywordCheckValidator.cs:关键词检查实现

public class KeywordCheckValidator : IKeywordCheckValidator
{
    public ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value is string v)
        {
            if (!String.IsNullOrEmpty(v))
            {
                var obj = KeywordProvider.Instance;
                var o = obj.IllegalWordsSearch;
                o.ContainsAny(v);
                if (KeywordProvider.Instance.IllegalWordsSearch.ContainsAny(v))
                {
                    return new ValidationResult("存在敏感词", new[] { validationContext.MemberName });
                }
                // 检查拼音
                if (KeywordProvider.Instance.IllegalWordsSearch.ContainsAny(WordsHelper.GetPinyin(v)))
                {
                    return new ValidationResult("存在敏感词", new[] { validationContext.MemberName });
                }
                // todo:其他变种
            }
        }
        return ValidationResult.Success;
    }
}

KeywordReplaceValidator.cs关键词替换的实现

public class KeywordReplaceValidator : IKeywordReplaceValidator
{
    public void Replace(object value, ValidationContext validationContext)
    {
        if (value is string v)
        {
            if (!String.IsNullOrEmpty(v))
            {
                v = KeywordProvider.Instance.IllegalWordsSearch.Replace(v);
                SetPropertyByName(validationContext.ObjectInstance, validationContext.MemberName, v);
            }
        }
    }

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

KeywordCheckAttribute.cs:关键词检查特性

/// <summary>
/// 敏感词检查的特性,一匹配就抛异常
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class KeywordCheckAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return validationContext.GetService<IKeywordCheckValidator>().IsValid(value, validationContext);
    }
}

KeywordReplaceAttribute.cs:关键词替换特性

/// <summary>
/// 敏感词替换的特性,一匹配就替换
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class KeywordReplaceAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        validationContext.GetService<IKeywordReplaceValidator>().Replace(value, validationContext);
        return ValidationResult.Success;
    }
}

KeywordProvider.cs

public sealed class KeywordProvider
{
    private static readonly Lazy<KeywordProvider>
       lazy =
           new Lazy<KeywordProvider>
               (() => new KeywordProvider());

    public static KeywordProvider Instance
    { get { return lazy.Value; } }

    private KeywordProvider()
    {
        IllegalWordsSearch = new IllegalWordsSearch();
    }

    public readonly IllegalWordsSearch IllegalWordsSearch;

    public void SetKeys(List<string> keys)
        {
            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);
            }
        }
}

KeywordSettings.cs

/// <summary>
/// 关键词json配置文件模型
/// </summary>
public class KeywordConfig
{
    /// <summary>
    /// 非法词语
    /// </summary>
    public List<string> IllegalKeywords { get; set; } = new List<string>();

    /// <summary>
    /// 非法网址
    /// </summary>
    public List<string> IllegalUrls { get; set; } = new List<string>();
}

KeywordExtension.cs

public static class KeywordExtension
{
    public static void AddKeywordSetUp(this IServiceCollection services)
    {
        var builder = new ConfigurationBuilder().SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
            .AddJsonFile("IllegalUrls.json", optional: false, reloadOnChange: true)//配置热重载
            .AddJsonFile("IllegalKeywords.json", optional: false, reloadOnChange: true);//配置热重载
        //创建配置根对象
        var configurationRoot = builder.Build();
        var o = configurationRoot.GetConnectionString("IllegalKeywords");
        var list = configurationRoot.GetSection("IllegalKeywords");
        var lists = configurationRoot.GetSection("IllegalKeywords").Get<List<string>>();
        KeywordProvider.Instance.SetKeys(configurationRoot.GetSection("IllegalKeywords").Get<List<string>>());
        ChangeToken.OnChange(() => configurationRoot.GetReloadToken(), () =>
        {
            // 敏感词重载
            KeywordProvider.Instance.SetKeys(configurationRoot.GetSection("IllegalKeywords").Get<List<string>>());
        });
        services.AddSingleton<IKeywordCheckValidator, KeywordCheckValidator>()
            .AddSingleton<IKeywordReplaceValidator, KeywordReplaceValidator>();
    }
}

IllegalKeywords.json,IllegalUrls.json:关键词配置文件

源码地址

源码地址:https://gitee.com/ajun816/keywords-filter.git

标签:类库,封装,KeywordProvider,value,var,new,Net5,public,validationContext
From: https://www.cnblogs.com/AJun816/p/16898954.html

相关文章

  • 封装,继承(super,this,方法重写),多态--JAVA
    一、封装封装:就是把抽象出的数据【属性】和对数据的操作【方法】封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作才能对数据进行操作  publicclass......
  • python-面相对象封装案例-笔记
    目标封装小明爱跑步存放家具01.封装封装 是面向对象编程的一大特点面向对象编程的 第一步 ——将 属性 和 方法 封装 到一个抽象的 类 中外界 使用 类 创建......
  • python-面相对象封装案例Ⅱ-笔记
    目标士兵突击案例身份运算符封装封装 是面向对象编程的一大特点面向对象编程的 第一步 ——将 属性 和 方法 封装 到一个抽象的 类 中外界 使用 类 创建 对......
  • web技术分享| 日期选择限制组件二次封装
    vue3+elementplus的项目项目需求:开始时间限制:存在某天之前的时间禁选结束时间限制:当天之后时间禁选开始时间与结束时间的跨度最大不超过一年使用elementplus的......
  • C++初阶(类的访问权限以及封装+this指针+构造函数+析构函数+拷贝构造函数+参数列表+友
    面向过程与面向对象C语言是面向过程的,关注的是过程(函数),分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠......
  • 小程序封装一个Request 请求
    'usestrict'import{getToken}from'./auth'constbaseUrl1='https://xxx'.//域名地址varRequest=function(url,data,method="get",header,code=2......
  • 封装,继承,多态
    super1.super调用父类的构造方法,必须在构造方法第一个2.super必须只能出现在子类的方法或构造方法中3.super和this不能同时调用构造方法Vsthis:代表......
  • ASEMI整流桥D3KB100参数,D3KB100规格,D3KB100封装
    编辑-ZASEMI整流桥D3KB100参数:型号:D3KB100最大重复峰值反向电压(VRRM):1000VRMS反向电压VR(RMS):700平均整流输出电流(IO):3A峰值正向浪涌电流(IFSM):60A每个元件的典型热阻(Re......
  • 立创商城封装搜索载入插件 AD-LCSC 转载
    AD-LCSC脚本地址:Releases·TimonPeng/AD-LCSC-Addons(github.com)立创商城封装搜索载入插件开源AltiumDesigner立创商城封装搜索载入插件-立创社区(szlcsc.co......
  • vue中 封装axios 以便管理和使用
    1.npm或yarn 安装axios到项目中npminstallaxiosyarnaddaxios2.新建api文件引入服务器的基本IP:端口//所有用户的接口importaxiosfrom"axios";//服......