在 Asp.Net 4 中,ValidateRequest="false" 无效。

160

我有一个表单,使用了ckeditor。这个表单在Asp.Net 2.0和3.5上运行良好,但在Asp.Net 4+上不起作用。我已经添加了ValidateRequest="false"指令。有什么建议吗?


如果有人关心,这里有一篇关于如何正确呈现验证控件的简短文章:.NET 4中的错误验证 - Ian
有人能告诉我使用ValidationRequest=false的缺点吗? - fc123
7个回答

204

在错误页面上找到了解决方案。只需要在web.config中添加requestValidationMode="2.0"即可。

<system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime requestValidationMode="2.0" />
</system.web>

MSDN信息:HttpRuntimeSection.RequestValidationMode 属性


2
太棒了,但有没有人知道如何按页面设置它?另外,我该如何将其放入web.config中,以便仍然适用于.NET 2? - MK.
1
@MK:我不认为有一个页面指令可以设置这个。你不能让它在 .net 2 上运行。我不认为这是必要的。因为你只需要构建一个针对某个框架版本的 Web 应用程序。只需将此行复制到需要它的 .net 4 web.config 文件中即可... - HasanG
2
但是在 .net 4 中,验证方面有什么变化吗?有没有一种方法可以在不改变验证模式的情况下完成它? - Sly
4
@Sly:您可以在此处找到答案:http://www.asp.net/learn/whitepapers/aspnet4/breaking-changes#0.1__Toc256770147。 - HasanG
有没有人能告诉我,在使用requestValidationMode="2.0"的asp.net 4.0应用程序中,为什么这是个好主意? - fc123
1
这对我很有效。在VS中,我可以不用它,但在实际服务器上,我必须使用它才能使网站按预期运行。谢谢,HasanG。 - CodingEE

105

有一种方法可以将验证方式转回到2.0版本,只需在web.config文件中添加以下代码:

<configuration>
    <location path="XX/YY">
        <system.web>
            <httpRuntime requestValidationMode="2.0" />
        </system.web>
    </location>

    ...
    the rest of your configuration
    ...

</configuration>

位置可以是任何路径,并且基于您在树中指定的文件夹下的任何节点。 - DFTR
7
这个解决方案比被接受的答案更好,因为它不是应用程序范围内的解决方案,而只是针对您在位置路径中定义的特定范围。 - Charles Wesley
5
以上的<location ..>声明应该放置在<configuration>声明内部,但不要被进一步嵌套。 - rbassett
1
每页设置似乎对于面向.NET 4.6.1的项目无效。 - Dennis T --Reinstate Monica--
有没有办法为一个操作方法取消请求验证?我试着使用属性,但它没有起作用。 - Sandeep Pandey

59
我知道这是一个旧问题,但如果你在MVC 3中遇到了这个问题,那么你可以在ActionMethod上使用[ValidateInput(false)]进行装饰,并关闭单个ActionMethod的请求验证,这很方便。而且你不需要对web.config文件进行任何更改,所以你仍然可以在其他地方使用.NET 4请求验证。例如:
[ValidateInput(false)]
public ActionMethod Edit(int id, string value)
{
    // Do your own checking of value since it could contain XSS stuff!
    return View();
}

1
@RossCooper 这仅适用于 asp.net MVC。 - mxmissile

28

即使不更改验证模式,这也可以正常工作。

您需要使用来自System.Web.WebPages.dllSystem.Web.Helpers.Validation.Unvalidated助手。它将返回一个UnvalidatedRequestValues对象,允许在没有验证的情况下访问表单和QueryString。

例如,

var queryValue = Server.UrlDecode(Request.Unvalidated("MyQueryKey"));

对于MVC3和.NET 4,这对我有效。


1
请问您能否提供一个使用此方法检索queryString的示例?我尝试将其附加到所有对象时,都会出现“未验证不是...的成员”的错误。我认为我可能漏掉了一个包含文件。 - CodedMonkey
3
var queryValue = Server.UrlDecode(Request.Unvalidated("MyQueryKey"));翻译: var queryValue = 服务器.Url解码(请求.未验证的("MyQueryKey")); - sfuqua
1
这绝对应该是被接受的答案。它保持了安全性,并且非常灵活,因为您可以有选择地使用它。 - cmartin
对于Web表单,您必须替换QueryString集合中的条目,以避免验证错误-参见A potentially dangerous Request.QueryString value was detected from the client when sending html markup from jquery post call to asp.net page - Michael Freidgeim

16

注意,另一种方法是保持4.0验证行为,但定义一个派生自RequestValidator的自定义类,并设置:

<httpRuntime requestValidationType="YourNamespace.YourValidator" />

(其中YourNamespace.YourValidator应该可以猜到是什么...)

这样,您就可以保留4.0行为的优点(特别是在处理过程中更早地进行验证),同时也允许您需要通过的请求通过。


7
知道这点是很好的。但我仍然认为 ASP.Net 的整个请求验证功能是误导的。输入本身并不是问题所在,而是你对它的处理方式。只要在输出或存储到数据库之前正确地进行编码/转义,接受 SQL、HTML 或 JavaScript 代码作为应用程序输入就可以完全合法。 - Jordan Rieger
2
@JordanRieger 我有些同意。OOTB,它至少具有默认安全的优势(不经过思考就会出现错误,而不是被攻击),但它有点麻烦,而且4.0之前的行为非常二选一。 在处理任何其他处理之前使用验证层的能力确实有些用处,例如使用自定义requestValidationType,但很多验证需要更紧密地与其他处理相关联。总的来说,我认为它更多地是保护那些有坏习惯的人免受某些(但不是全部)spl0its的侵害,而不是鼓励好习惯。 - Jon Hanna

-1
我在这里找到了解决方案:https://www.aspsnippets.com/Articles/Solved-ValidateRequest-false-not-working-in-Net-40-and-45-in-ASPNet.aspx 摘要:
  1. 如果您想在页面级别设置此项,请像这样设置ValidateRequest="false" <%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="false" %>
  2. 您还需要修改httpRuntime,将requestValidationMode="2.0"添加到<system.web>中,如下所示
<system.web>
    <httpRuntime maxRequestLength="91200" executionTimeout="9000" requestValidationMode="2.0" />
</system.web>
在.NET 4.8中对我来说可以运行。

-1
迁移我的应用程序从dotnet framework 3.5到4.7之后,我遇到了相同的错误。
通过在system.web下的httpRuntime中添加requestValidationMode="2.0"来解决它。
<httpRuntime maxRequestLength="2097151" requestValidationMode="2.0"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接