每当用户在我的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;
    }
}

其他回答

这个问题的答案很简单:

var varname = Request.Unvalidated["parameter_name"];

这将禁用特定请求的验证。

我也遇到了这个错误。

在我的案例中,用户在角色名称中输入了重音字符á(关于ASP.NET成员资格提供程序)。

我将角色名传递给一个方法,将用户授予该角色,而$.ajaxpost请求失败得很惨。。。

我这样做是为了解决问题:

而不是

data: { roleName: '@Model.RoleName', users: users }

这样做

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

@Html.Raw成功了。

我得到的角色名称是HTML值roleName=“Cadastro b&#225;s”。此值与HTML实体&#225;被ASP.NET MVC阻止。现在我得到了roleName参数值,它应该是:roleName=“Cadastro Básico”,ASP.NET MVC引擎不会再阻止请求。

最后但同样重要的是,请注意ASP.NET数据绑定控件在数据绑定期间自动编码值。这将更改ItemTemplate中包含的所有ASP.NET控件(TextBox、Label等)的默认行为。以下示例演示了(ValidateRequest设置为false):

aspx

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
    <form runat="server">
        <asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                <asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
                <asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
            </ItemTemplate>
        </asp:FormView>
    </form> 

代码隐藏

public partial class _Default : Page
{
    S s = new S();

    protected void Button1_Click(object sender, EventArgs e)
    {
        s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
        FormView1.DataBind();
    }

    public S FormView1_GetItem(int? id)
    {
        return s;
    }
}

public class S
{
    public string Text { get; set; }
}

案例提交值:&#39;

标签1.文本值:&#39;

TextBox2.文本值:&amp#39;

案例提交值:<script>alert('attack!')</脚本>

标签1.文本值:<script>alert('attack!')</脚本>

TextBox2.文本值:&lt;脚本&gt;警报(&#39;攻击!&#39;)&lt/脚本&gt;

您还可以使用JavaScript的转义(字符串)函数来替换特殊字符。然后服务器端使用server.URLDecode(字符串)将其切换回来。

这样,您就不必关闭输入验证,其他程序员将更清楚地知道字符串可能包含HTML内容。

对于那些不使用模型绑定、从Request.Form中提取每个参数、确信输入文本不会造成伤害的人,还有另一种方法。这不是一个很好的解决方案,但它可以解决问题。

从客户端,将其编码为uri,然后发送。例如:

encodeURIComponent($("#MsgBody").val());  

在服务器端,接受它并将其解码为uri。例如:

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form["MsgBody"]) : 
null;  

or

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Uri.UnescapeDataString(HttpContext.Current.Request.Form["MsgBody"]) : 
null; 

请查找UrlDecode和UnescapeDataString之间的差异