如何给 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; }
}
希望有用
我想在 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; }
}
希望有用