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

封装通用.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

posted @   AJun816  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2021-11-17 MongoDB
2021-11-17 Ocelot
点击右上角即可分享
微信分享提示