2

序言:我已经阅读了许多关于修复“潜在危险请求”错误的问题:

在许多其他人中。我知道如何以几种不同的方式修复它,但是我不想关闭请求验证。


我想为站点范围内的所有字符串视图模型属性添加表单验证,以防止出现“潜在危险请求”异常,因为如果用户可以更正输入,则抛出异常并不理想。我只能想到两种不同的解决方案:

  1. 向每个接受string数据类型的视图模型属性添加一个正则表达式验证器,该数据类型在浏览器上执行。这将阻止表单提交,但对于我们的应用程序而言,编码方面的工作量很大

  2. 不知何故,神奇地添加了一个验证器,该验证器在执行此验证的所有字符串视图模型属性上触发的每个请求上执行,并为用户提供比末日黄屏 (tm) 更友好的消息。

无论解决方案如何,表单字段都应显示的验证消息应类似于:

X 字段包含有潜在危险的字符。删除所有“<”字符,或确保在它们之前出现空格或标点符号。

或者有什么影响。基本上,我想要一个验证消息来帮助用户解决问题,而不是把整个应用程序炸得天花乱坠,这会导致他们丢失所有将数据输入表单的工作。

我确实想出了一个解决方案,它涉及为字符串属性添加一个自定义模型绑定器,该绑定器在不触发验证的情况下获取属性的值,然后使用正则表达式对其进行测试。然后,正则表达式上的匹配会导致将新的模型状态错误添加到该属性中。

public class MaliciousStringInputModelBinder : IModelBinder
{
    private static readonly Regex maliciousStringPattern = new Regex(@"<[a-zA-Z0-9]");
    private const string validationMessageFormat = "The {0} field contains potentially dangerous characters. Either remove the '<' characters, or ensure a space or puncuation character immediately follows them.";

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Call extension method to safely get model value without
        // triggering any validations
        var valueResult = controllerContext.GetValueFromProvider(bindingContext);

        if (valueResult == null || valueResult.AttemptedValue == null)
        {
            return null;
        }
        else if (valueResult.AttemptedValue == string.Empty)
        {
            return string.Empty;
        }
        else if (maliciousStringPattern.IsMatch(valueResult.AttemptedValue))
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format(validationMessageFormat, bindingContext.ModelMetadata.DisplayName));
        }

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueResult);

        return valueResult.AttemptedValue;
    }
}

这行得通,但感觉就像一个黑客。我没有绑定模型属性,我正在验证它。

我一直在研究 ASP.NET MVC 动作过滤器,但我又一次在没有明确解决方案的情况下跳过了很多圈。

如何在 ASP.NET MVC 中向站点范围内的所有字符串视图模型属性添加通用表单验证,以向用户显示验证消息而不是引发异常?

4

0 回答 0