如何给 Class 的所有 属性 添加 Xss 属性?

How to add Xss Attribute on All property of Class?

我想在 class 的 header 上添加 xss 属性并应用于所有 属性。 喜欢这个代码

[CustomAttribute]
public class Class1
{
    public string Name { get; set; }
    public string LastName { get; set; }
}

并致力于继承

我尝试并从这些代码中得到了我想要的结果

 [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class AntiXssAttributeForClass : ValidationAttribute
{
    const string DefaultValidationMessageFormat = "The {0} property failed AntiXss validation";
    private readonly string errorMessage;
    private readonly string errorMessageResourceName;
    private readonly Type errorMessageResourceType;
    private readonly string allowedStrings;
    private readonly string disallowedStrings;
    private readonly Dictionary<string, string> allowedStringsDictionary;

    /// <summary>
    /// Initializes a new instance of the <see cref="AntiXssAttribute"/> class.
    /// </summary>
    /// <param name="errorMessage">The error message.</param>
    /// <param name="errorMessageResourceName">Name of the error message resource.</param>
    /// <param name="errorMessageResourceType">Type of the error message resource.</param>
    /// <param name="allowedStrings">A comma separated string allowed characters or words.</param>
    /// <param name="disallowedStrings">A comma separated string disallowed characters or words.</param>
    public AntiXssAttributeForClass(
        string errorMessage = null,
        string errorMessageResourceName = null,
        Type errorMessageResourceType = null,
        string allowedStrings = null,
        string disallowedStrings = null)
    {
        this.errorMessage = errorMessage;
        this.errorMessageResourceName = errorMessageResourceName;
        this.errorMessageResourceType = errorMessageResourceType;
        this.allowedStrings = allowedStrings;
        this.disallowedStrings = disallowedStrings;
        allowedStringsDictionary = new Dictionary<string, string>();
    }

    public override bool IsValid(object value)
    {
        return true;
    }

    protected override ValidationResult IsValid(object values, ValidationContext validationContext)
    {
        foreach (PropertyInfo propertyInfo in values.GetType().GetProperties())
        {
            var PropertyType = propertyInfo.PropertyType.Name;
            if (PropertyType == "String")
            {

                var PropertyValue = propertyInfo.GetValue(values);
                if (PropertyValue != null)
                {
                    if (propertyInfo.CustomAttributes != null && propertyInfo.CustomAttributes.Count()> 0)
                    {
                        var CustomAttributes = propertyInfo.CustomAttributes.Where(w=>w.AttributeType!=null && w.AttributeType.Name.Equals("AntiXssAttributeForClass")).FirstOrDefault();
                        if(CustomAttributes!=null && CustomAttributes.ConstructorArguments!=null && CustomAttributes.ConstructorArguments.Count>0 && CustomAttributes.ConstructorArguments[3]!=null && CustomAttributes.ConstructorArguments[3].Value!=null && !string.IsNullOrWhiteSpace(CustomAttributes.ConstructorArguments[3].Value.ToString()))
                        SetupAllowedStringsDictionary(CustomAttributes.ConstructorArguments[3].Value.ToString());
                    }
                // return base.IsValid(null, validationContext);

                var encodedValue = AntiXssEncoder.HtmlEncode(PropertyValue.ToString(), false);

                if (EncodedStringAndValueAreDifferent(PropertyValue, encodedValue))
                {
                    SetupAllowedStringsDictionary();

                    foreach (var allowedString in allowedStringsDictionary)
                    {
                        encodedValue = encodedValue.Replace(allowedString.Value, allowedString.Key);
                    }

                    if (EncodedStringAndValueAreDifferent(PropertyValue, encodedValue))
                    {
                        return new ValidationResult(SetErrorMessage(validationContext));
                    }
                }

                if (!string.IsNullOrWhiteSpace(disallowedStrings) && disallowedStrings.Split(',').Select(x => x.Trim()).Any(x => value.ToString().Contains(x)))
                {
                    return new ValidationResult(SetErrorMessage(validationContext));
                }

                }
             

            }
        }

        return base.IsValid(values, validationContext);
    }

    private static bool EncodedStringAndValueAreDifferent(object value, string encodedValue)
    {
        return !value.ToString().Equals(encodedValue);
    }

    private void SetupAllowedStringsDictionary()
    {
        if (string.IsNullOrWhiteSpace(allowedStrings))
        {
            return;
        }

        foreach (var allowedString in allowedStrings.Split(',').Select(x => x.Trim())
            .Where(allowedString => !allowedStringsDictionary.ContainsKey(allowedString)))
        {
            allowedStringsDictionary.Add(allowedString,
                AntiXssEncoder.HtmlEncode(allowedString, false));
        }
    }
    private void SetupAllowedStringsDictionary(string allowedStrings)
    {
        if (string.IsNullOrWhiteSpace(allowedStrings))
        {
            return;
        }

        foreach (var allowedString in allowedStrings.Split(',').Select(x => x.Trim())
            .Where(allowedString => !allowedStringsDictionary.ContainsKey(allowedString)))
        {
            allowedStringsDictionary.Add(allowedString,
                AntiXssEncoder.HtmlEncode(allowedString, false));
        }
    }

    private string SetErrorMessage(ValidationContext validationContext)
    {
        if (IsResourceErrorMessage())
        {
            var resourceManager = new ResourceManager(errorMessageResourceType);
            return resourceManager.GetString(errorMessageResourceName, CultureInfo.CurrentCulture);
        }

        if (!string.IsNullOrEmpty(errorMessage))
        {
            return errorMessage;
        }

        return string.Format(DefaultValidationMessageFormat, validationContext.DisplayName);
    }

    private bool IsResourceErrorMessage()
    {
        return !string.IsNullOrEmpty(errorMessageResourceName) && errorMessageResourceType != null;
    }
}

并且您可以像这样使用它

  [AntiXssAttributeForClass]
public  class TestXSS
{
    [AntiXssAttributeForClass(allowedStrings: "<br />,<p>")]
    public string name { get; set; }
    public string Lastname { get; set; }
    public Guid guid { get; set; }
    public int id { get; set; }

}

而且在继承中也有效

 public  class TestXSSInheritance : TestXSS
{
    public string testIn { get; set; }
    [AntiXssAttributeForClass(allowedStrings: "<br />,<p>")]
    public string testIn2 { get; set; }
}

希望有用