每当用户在我的web应用程序中的页面中发布包含<或>的内容时,我都会引发此异常。

我不想因为有人在文本框中输入了字符而引发异常或使整个web应用程序崩溃,但我正在寻找一种优雅的方式来处理这一问题。

捕获异常并显示

出现错误,请返回并重新键入整个表单,但这次请不要使用<

我觉得不够专业。

禁用后验证(validateRequest=“false”)肯定可以避免此错误,但这会使页面容易受到许多攻击。

理想情况下:当发生包含HTML限制字符的回发时,表单集合中的回发值将自动进行HTML编码。因此,我的文本框的.Text属性将是&lt;html&gt;

有没有办法让我从处理者那里做到这一点?


当前回答

另一种解决方案是:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}

其他回答

前面的答案很好,但没有人说过如何排除一个字段进行HTML/JavaScript注入的验证。我不知道以前的版本,但在MVC3 Beta版中,您可以这样做:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

这仍然会验证除排除的字段之外的所有字段。这一点的好处是,您的验证属性仍然验证字段,但您没有得到“潜在危险的请求。表单值已从客户端检测到”异常。

我已经用它验证了正则表达式。我制作了自己的ValidationAttribute,以查看正则表达式是否有效。由于正则表达式可以包含类似于脚本的内容,我应用了上面的代码-正则表达式仍然在检查是否有效,但不检查是否包含脚本或HTML。

如果您使用的是ASP.NET MVC,则此错误有一种不同的解决方案:

ASP.NET MVC–pages validateRequest=false不起作用?为什么ValidateInput(False)不工作?ASP.NET MVC RC1,VALIDATEINPUT,一个潜在的危险请求和陷阱

C#示例:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

Visual Basic示例:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function

没有一个答案对我有效。然后我发现,如果我删除了以下代码,我可以让它发挥作用:

//Register action filter via Autofac rather than GlobalFilters to allow dependency injection
builder.RegisterFilterProvider();
builder.RegisterType<OfflineActionFilter>()
    .AsActionFilterFor<Controller>()
    .InstancePerLifetimeScope();

我只能得出结论,Autofac的RegisterFilterProvider中的某些内容破坏或覆盖validateRequest属性

这里的其他解决方案很好,但必须将[AllowHtml]应用于每个Model属性,特别是如果您在一个规模适中的网站上拥有超过100个模型,这有点麻烦。

如果像我一样,你想在整个站点范围内关闭这个(IMHO非常无意义)功能,你可以在基本控制器中重写Execute()方法(如果你还没有基本控制器,我建议你做一个,它们对于应用公共功能非常有用)。

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

只需确保您对从用户输入输出到视图的所有内容进行了HTML编码(无论如何,这是ASP.NET MVC 3中使用Razor的默认行为,因此除非出于某种奇怪的原因,您使用HTML.Raw(),否则不应该需要此功能。

您可以对文本框内容进行HTML编码,但不幸的是,这并不能阻止异常的发生。根据我的经验,没有办法,您必须禁用页面验证。你这样做是在说:“我会小心的,我保证。”