从jquery post调用asp.net页面发送html标记时,客户端检测到潜在危险的Request.QueryString值

我使用jQuery的ajax调用一个ASP.NET页面作为我的ajax服务器页面来保存我发送到查询string中的数据。 在ASP.NET页面中,当我正在阅读querystring我得到这个错误:

A potentially dangerous Request.QueryString value was detected from the client... 

我在页面中设置了ValidateRequest="false" 。 不想为所有页面设置它。 所以在页面级别而不是configuration级别:

  var content = "<h3>Sample header</h3><p>sample para</p>" content = encodeURIComponent(content); var url = "../Lib/ajaxhandler.aspx?mode=savecontent&page=home&ltxt=" + content; $.post(url, function (data) { //check return value and do something }); 

并在我的asp.net页面:

  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ajaxhandler.aspx.cs" ValidateRequest="false" Inherits="MyProject.Lib.ajaxhandler" %> 

但是,当我发送纯文本,而不是HTML标记,它工作正常。

如果这是ASP.NET 4,那么ValidateRequest 发生了重大变化 。 有关requestValidationMode更多信息,请参阅此StackOverflow问题 。

已经有一个很好的答案了,在这里我会提供信息,所以你不必点击链接。

运行ASP.NET 4.0时,需要在web.config文件中设置以下参数: RequestValidationMode="2.0"

这个属性是什么?

指示将使用哪个ASP.NET版本特定的validation方法的值。 默认值是4.0。

那么可能的价值是什么?

  • 4.0(默认)。 HttpRequest对象在内部设置一个标志,指示请求validation应该随时触发
    HTTP请求数据被访问。 这保证了请求
    validation在数据(例如cookie和URL)被触发之前触发
    在请求期间被访问。 请求validation设置的
    pages元素(如果有)在configuration文件或@ Page中
    单个页面中的指令被忽略。

  • 2.0。 请求validation仅针对页面启用,而不针对所有HTTP请求。 另外,configuration文件中页面元素(如果有)的请求validation设置或单个页面中的@ Page指令的请求validation设置用于确定要validation哪些页面请求。

从这个msdn网站引用的信息。

如果您想为一个特定的ASP.NET页面或一个或多个查询string参数添加自定义validation逻辑,而不必为整个页面设置ValidateRequest="false" ,则下面的“hacky”解决scheme可能会有用:

 public partial class MyPage : System.Web.UI.Page { private string SomeUnvalidatedValue { get; set; } public override void ProcessRequest(HttpContext context) { var queryString = context.Request.QueryString; var readOnly = queryString.GetType().GetProperty("IsReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); readOnly.SetValue(queryString, false); var unvalidatedValue = context.Request.Unvalidated.QueryString["SomeKey"]; // for RequestValidationMode="2.0" //var unvalidatedValue = context.Request.QueryString["SomeKey"]; // custom logic goes here // you could store unvalidated value here and then remove it from the query string SomeUnvalidatedValue = unvalidatedValue; queryString["SomeKey"] = string.Empty; // or just remove all "potentially dangerous" symbols, for example if (!string.IsNullOrEmpty(unvalidatedValue)) { queryString["SomeKey"] = Regex.Replace(unvalidatedValue, "(\\<+[az!/\\?])|(&\\#)", new MatchEvaluator((m) => { return m.Value.Replace("<", string.Empty).Replace("&#", string.Empty); }), RegexOptions.IgnoreCase); } readOnly.SetValue(queryString, true); // keep other request validation logic as is base.ProcessRequest(context); } } 

由此ASP.NET方法分析的正则expression式: CrossSiteScriptingValidation.IsDangerousString

代码testing与.NET 4.5.2,IIS集成模式,有和没有RequestValidationMode="2.0"

在asp页面的顶部设置ValidateRequest =“false”。

我根据VAV的答案创build了一些可重复使用的方法

  public static string ExtractUnvalidatedValue(HttpRequest request, string key) { var unvalidatedValue = HttpUtility.UrlDecode(request.Unvalidated.QueryString[key]); // for RequestValidationMode="2.0" //var unvalidatedValue = context.Request.QueryString["SomeKey"]; // remove all "potentially dangerous" symbols return ReplacePotentiallyDangerousSymbols(unvalidatedValue, string.Empty); } public static string ReplacePotentiallyDangerousSymbols(string unvalidatedValue, string valueToReplace="") { if (!string.IsNullOrEmpty(unvalidatedValue)) { //The regular expression made as result of this ASP.NET method analyzing: CrossSiteScriptingValidation.IsDangerousString http://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs,3c599cea73c5293b unvalidatedValue = Regex.Replace(unvalidatedValue, "(\\<+[az!/\\?])|(&\\#)", new MatchEvaluator((m) => { return m.Value.Replace("<", valueToReplace).Replace("&#", valueToReplace); }), RegexOptions.IgnoreCase); } return unvalidatedValue; }