2017-03-09 112 views
1

我试图处理好以下几个问题处理,但此错误

的通知用户有潜在危险的Request.Form值从客户端检测到'“是从检测到有潜在危险的Request.Form值在 客户”

不过,我不能找到一个很好的教程,介绍了如何抓住这个错误并处理它。只是为了清楚,我想在填写表单时阻止用户输入任何标记。处理此问题的大多数文章都提示关闭请求验证。这不是我想要做的事情。我想捕捉错误并将错误回放给用户。任何帮助将不胜感激。

+0

也许这会容易的HTML,但只是从输入值剥离任何标记? –

+0

@TiesonT。有很多东西/各种攻击被验证过滤出来 - 认为你可以做得比ASP.Net更好。 – caesay

+0

@caesay我不是建议关闭请求验证。我建议将AllowHtmlAttribute添加到OP正在使用的任何模型中,然后清理输入。 –

回答

2

您可以使用异常过滤器捕获错误。喜欢的东西:

public class RequestValidationExceptionFilter : IExceptionFilter 
{ 
    public void OnException(ExceptionContext filterContext) 
    { 
     if(filterContext.Exception is HttpRequestValidationException) 
     { 
      filterContext.Result = new RedirectResult("/Error"); 
      filterContext.ExceptionHandled = true; 
     } 
    } 
} 

你可以在异常的Message一些更多的信息,如:

从客户端(FILTERNAME =” <脚本>检测到有潜在危险的值的Request.QueryString警报(“!!”)< ...“)。

但是,这不是真的要显示给用户的东西。所以最好的做法是重定向到一些通用的错误页面。或者您可以将它们发回当前页面。

+0

是否有任何向模型状态添加错误的方法,以便我可以将此错误重新发送给用户?但是我会让错误消息更通用。 – tbonejenkins

+0

那么,在这个异常过滤器中,我们已经不在控制器中了。所以我不这么认为。如果您能够替换引发错误的组件,也许可以将该错误添加到模型状态中。 – juunas

+0

或者,如果在引发错误之前运行筛选器,您可以使用内部使用的相同组件验证它,模型状态错误并擦除模型中的值,从而不会引发错误。但如果它在模型绑定期间被抛出,那么这将不起作用。 – juunas

0

刚才我正在做一些快速测试,出于某种原因,当验证异常发生时,动作过滤器和异常过滤器没有得到执行 - 所以我使用Application_Error()快速提取了一些东西。 (您可以在Global.asax.cs创建这个方法,如果它不存在)

protected void Application_Error() 
{ 
    var lastError = Server.GetLastError() as HttpRequestValidationException; 
    if (lastError == null) 
     return; 

    MvcHandler mvcHandler = Context.CurrentHandler as MvcHandler; 
    if (mvcHandler == null) 
     return; 

    RequestContext requestContext = mvcHandler.RequestContext; 
    if (requestContext == null) 
     return; 

    Server.ClearError(); 
    Response.Clear(); 
    Response.TrySkipIisCustomErrors = true; 

    // pick one of the following two options, or maybe more? 
    RedirectToUrl(requestContext); 
    ExecuteActionResult(requestContext, ...); 

} 

void ExecuteActionResult(RequestContext requestContext, ActionResult result) 
{ 
    string controllerName = requestContext.RouteData.GetRequiredString("controller"); 
    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); 
    IController controller = factory.CreateController(requestContext, controllerName); 
    ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller); 
    result.ExecuteResult(controllerContext); 
} 

void RedirectToUrl(RequestContext requestContext) 
{ 
    requestContext.HttpContext.Server.TransferRequest($"~/Error/Something", false); 
} 

我包括如何重定向到任意URL的例子,也是如何对同一控制器执行新的ActionResult为例原始请求已被执行。