2008-10-30 12 views
36

Solo quiero saber cómo validar (o limpiar) la entrada del usuario en ASP.NET MVC para que no se genere una HttpRequestValidationException independientemente del valores enviados. Por ejemplo, con una entrada de texto, si el usuario ingresa <BR/>, causará una excepción y se mostrará la Pantalla amarilla de la muerte. No quiero eso. Quiero ver la excepción y hacer visible un error fácil de usar en la vista actual, preferiblemente con los controles cargados con los mismos valores enviados.Cómo evitar HttpRequestValidationException en ASP.NET MVC que representa la misma vista que causó la excepción

He encontrado este http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html, pero es inútil para mi propósito. Además, encontré esto http://msdn.microsoft.com/en-us/library/aa973813.aspx y traté de ponerlo dentro de una carpeta modelo, pero no pude hacerlo funcionar.

+2

+1 para YSOD. Bonito. –

Respuesta

38

Con la última versión de ASP.NET MVC (la RC, en el momento de escribir esto) que sólo puede poner un atributo en cualquiera de su clase controlador o su método de acción, por ejemplo:

[ValidateInput(false)] 
public ActionResult create() 
{ 
    // ...method body 
} 

El ValidateInputAttribute está en System.Web.Mvc.

Pero, como han dicho otros, entonces debe realizar su propia validación o limpieza de entrada manual.

Usando MVC 3, también debe asegurarse de que esto es en su Web.config: <system.web><httpRuntime requestValidationMode="2.0" /></system.web>

+3

Sería tan agradable si ValidateInputAttribute aceptara el nombre de un campo (o una lista de nombres), de modo que la validación se pudiera desactivar selectivamente. Todo o nada tiende a apestar, causa duplicación de esfuerzo y generalmente hace que las cosas sean más problemáticas. –

+9

Usando MVC 3, también debe asegurarse de que esté en su Web.config: '' –

0

Ponga put ValidateRequest = "false" en su declaración de vista aspx, pero desinfecte los usuarios ingresen texto dentro de su código, para evitar algunos ataques xss.

+0

Gracias, pero no quiero desactivar ValidateRequest en mi aspx. – eKek0

1

En lugar de detectar el error en global.asax Application_Error, puede detectarlo agregando un controlador de errores para el controlador que detecta explícitamente este error y lo redirecciona a la vista con un mensaje de error y los datos de visualización apropiados.

Encontré esto, algo viejo, post sobre cómo hacer esto con los atributos.

+0

Gracias, lo intentaré por ahora – eKek0

1

ValidateInputAttribute es el método adecuado para deshabilitar validación de solicitudes. El método declarativo dentro de la vista (aspx) no funciona porque el controlador es responsable de recibir la solicitud (no ver/aspx).

4

Para un ejemplo muy detallado de cómo atrapar a este (y otros) excepciones con un filtro ver: http://code.google.com/p/geochat/source/browse/Source/Web/GeoChat.MvcExtensions/ExceptionHandlerAttribute.cs

Esto le permitirá mantener la validación, pero evitar que el usuario vea la "pantalla amarilla de muerte".

Ésta es una (tal vez demasiado simplificado) versión simplificada:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
public class ExceptionHandlerAttribute : FilterAttribute, IExceptionFilter { 

private HandleErrorAttribute attribute = new HandleErrorAttribute(); 

public ExceptionHandlerAttribute() { 
    this.ExceptionType = typeof(Exception); 
    this.Order = 1; 
} 

public string View { 
    get { 
    return attribute.View; 
    } 
    set { 
    attribute.View = value; 
    } 
} 

public Type ExceptionType { 
    get { 
    return attribute.ExceptionType; 
    } 
    set { 
    attribute.ExceptionType = value; 
    } 
} 

public void OnException(ExceptionContext filterContext) { 
    if (this.ExceptionType.IsInstanceOfType(filterContext.Exception)) { 
    string controller = (string)filterContext.RouteData.Values["controller"]; 
    string action = (string)filterContext.RouteData.Values["action"]; 
    if (controller == null) 
     controller = String.Empty; 

    if (action == null) 
     action = String.Empty; 

    HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controller, action); 
    ViewResult result = new ViewResult(); 
    result.ViewName = this.View; 
    result.MasterName = String.Empty; 
    result.ViewData = new ViewDataDictionary<HandleErrorInfo>(model); 

    result.TempData = filterContext.Controller.TempData; 
    filterContext.Result = result; 

    filterContext.ExceptionHandled = true; 
    filterContext.HttpContext.Response.Clear(); 
    filterContext.HttpContext.Response.StatusCode = 500; 
    } 
} 

}

11

En ASP MVC 3 se puede utilizar el atributo [AllowHtml] en individuales campos/propiedades en su modelo/modelo de vista para apagar la validación solo por ese campo, que es bastante agradable. Agregaré este atributo a ciertos campos en mi modelo, y luego usaré la excelente biblioteca AntiXSS (también disponible a través de NuGet) para desinfectar la entrada del usuario llamando al Sanitizer.GetSafeHtmlFragment(mymodel.Description) (donde la propiedad "Descripción" es una propiedad de cadena en mi modelo de vista, que tiene aplicado el atributo [AllowHtml])

Cuestiones relacionadas