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

从jquery post调用向asp.net页面发送html标记时,从客户端检测到潜在危险的Request.QueryString值,asp.net,jquery,ajax,security,asp.net-ajax,Asp.net,Jquery,Ajax,Security,Asp.net Ajax,我使用jQuery对ASP.NET页面进行ajax调用,该页面充当我的ajax服务器页面,以将发送给它的数据保存在查询字符串中。在ASP.NET页面中,当我尝试读取查询字符串时,我遇到以下错误: A potentially dangerous Request.QueryString value was detected from the client... 我已经在我的页面中设置了ValidateRequest=“false”。不想为所有页面设置它。因此,它是在页面级别而不是配置级别执行的:

我使用jQuery对ASP.NET页面进行ajax调用,该页面充当我的ajax服务器页面,以将发送给它的数据保存在查询字符串中。在ASP.NET页面中,当我尝试读取查询字符串时,我遇到以下错误:

A potentially dangerous Request.QueryString value was detected from the client...
我已经在我的页面中设置了
ValidateRequest=“false”
。不想为所有页面设置它。因此,它是在页面级别而不是配置级别执行的:

  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
   });
var content=“样本标题样本段落

” 内容=组件(内容); var url=“../Lib/ajaxhandler.aspx?mode=savecontent&page=home<xt=“+content; $.post(url,函数(数据){ //检查返回值并执行某些操作 });
在我的asp.net页面中:

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


但是当我发送纯文本而不是html标记时,它工作得很好。

如果这是ASP.NET 4,则会出现一个带有
验证请求的问题。有关asp页面顶部的
requestValidationMode
设置ValidateRequest=“false”的更多信息,请参阅。

已经有了一个很好的答案,我将在这里提供信息,这样您就不必点击链接

运行ASP.NET 4.0时,需要在web.config文件
RequestValidationMode=“2.0”
中设置以下内容

这房子是干什么用的

一个值,指示特定于ASP.NET版本的方法 将使用验证。默认值为4.0

那么,可能的价值是什么

  • 4.0(默认设置)。HttpRequest对象在内部设置了一个标志,指示在任何
    访问HTTP请求数据。这保证了请求
    验证是在cookies和URL等数据被删除之前触发的
    在请求期间访问。
    配置文件或@Page的pages元素(如果有)
    忽略单个页面中的指令

  • 2.0。请求验证仅对页面启用,而不是对所有HTTP请求启用。此外,页面的请求验证设置 配置文件或@Page指令中的元素(如果有) 在单个页面中,用于确定要发送的页面请求 验证


如果要为一个特定ASP.NET页面或一个或多个查询字符串参数添加自定义验证逻辑,而不为整个页面设置
ValidateRequest=“false”
,则以下“黑客”解决方案可能会很有用:

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,
                "(\\<+[a-z!/\\?])|(&\\#)", 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);
    }
}
公共部分类MyPage:System.Web.UI.Page
{
私有字符串SomeUnvalidatedValue{get;set;}
公共覆盖无效ProcessRequest(HttpContext上下文)
{
var queryString=context.Request.queryString;
var readOnly=queryString.GetType().GetProperty(“IsReadOnly”,
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
SetValue(queryString,false);
var unvalidatedValue=context.Request.Unvalidated.QueryString[“SomeKey”];
//对于RequestValidationMode=“2.0”
//var unvalidatedValue=context.Request.QueryString[“SomeKey”];
//这里是自定义逻辑
//您可以在此处存储未验证的值,然后将其从查询字符串中删除
SomeUnvalidatedValue=未验证的值;
queryString[“SomeKey”]=string.Empty;
//或者只是删除所有“潜在危险”的符号,例如
如果(!string.IsNullOrEmpty(unvalidatedValue))
{
queryString[“SomeKey”]=Regex.Replace(unvalidatedValue,

“(\\我基于

public静态字符串提取unvalidatedvalue(HttpRequest请求,字符串键)
{
var unvalidatedValue=HttpUtility.UrlDecode(request.Unvalidated.QueryString[key]);
//对于RequestValidationMode=“2.0”
//var unvalidatedValue=context.Request.QueryString[“SomeKey”];
//删除所有“潜在危险”符号
返回替换潜在危险符号(未验证的值,string.Empty);
}
公共静态字符串替换潜在危险的符号(字符串未验证的值,字符串值替换=“”)
{
如果(!string.IsNullOrEmpty(unvalidatedValue))
{
//作为此ASP.NET方法分析结果生成的正则表达式:CrossSiteScriptingValidation.IsDangerUserStringhttp://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs,3c599cea73c5293b
unvalidatedValue=Regex.Replace(unvalidatedValue,

(\\n您是否完全确定已将ValidateRequest=“false”放在正确的页面上?哦,是的。我仔细检查了。可能是重复的哦,是的。这个问题是在我将框架版本升级到4.0时出现的。它昨天与2.0一起工作。
   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,
                    "(\\<+[a-z!/\\?])|(&\\#)",
                    new MatchEvaluator((m) => { return m.Value.Replace("<", valueToReplace).Replace("&#", valueToReplace); }), RegexOptions.IgnoreCase);
            }
            return unvalidatedValue;
        }