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

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

捕获异常并显示

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

我觉得不够专业。

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

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

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


当前回答

这个问题的答案很简单:

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

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

其他回答

对于那些不使用模型绑定、从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之间的差异

如果您确实需要特殊字符,如,>,<等,请禁用页面验证。然后确保在显示用户输入时,数据是HTML编码的。

页面验证存在安全漏洞,因此可以绕过它。此外,不应仅依赖页面验证。

参见:http://web.archive.org/web/20080913071637/http://www.procheckup.com:80/PDFs/bypassing-dot-NET-ValidateRequest.pdf

我也遇到了这个错误。

在我的案例中,用户在角色名称中输入了重音字符á(关于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引擎不会再阻止请求。

这些建议对我都不起作用。无论如何,我不想关闭整个网站的这个功能,因为99%的时间我不希望我的用户在web表单上放置HTML。我刚刚创建了自己的变通方法,因为我是唯一一个使用这个特定应用程序的人。我在后面的代码中将输入转换为HTML并将其插入数据库。

您可以在自定义模型活页夹中自动对字段进行HTML编码。我的解决方案有些不同,我将错误放在ModelState中,并在字段附近显示错误消息。很容易修改此代码以自动编码

 public class AppModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            try
            {
                return base.CreateModel(controllerContext, bindingContext, modelType);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }
        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
            PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            try
            {
                return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }

        protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
        {
            var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
            if (valueProviderCollection != null)
            {
                ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            }

            string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
                     bindingContext.ModelMetadata.DisplayName);

            bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
        }
    }

在应用程序启动中:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

请注意,它仅适用于表单字段。危险值未传递到控制器模型,但存储在ModelState中,可以在表单上重新显示错误消息。

URL中的危险字符可以这样处理:

private void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpContext httpContext = HttpContext.Current;

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        var httpCode = httpException.GetHttpCode();
        switch (httpCode)
        {
            case (int)HttpStatusCode.BadRequest /* 400 */:
                if (httpException.Message.Contains("Request.Path"))
                {
                    httpContext.Response.Clear();
                    RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
                    requestContext.RouteData.Values["action"] ="InvalidUrl";
                    requestContext.RouteData.Values["controller"] ="Error";
                    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
                    IController controller = factory.CreateController(requestContext, "Error");
                    controller.Execute(requestContext);
                    httpContext.Server.ClearError();
                    Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
                }
                break;
        }
    }
}

错误控制器:

public class ErrorController : Controller
 {
   public ActionResult InvalidUrl()
   {
      return View();
   }
}