Permitir al usuario ingresar HTML en ASP.NET MVC - ValidateInput o AllowHtml

120

¿Cómo puedo permitir que un usuario ingrese HTML en un campo particular usando ASP.net MVC?

Tengo una forma larga con muchos campos que se asignan a este objeto complejo en el controlador.

Me gustaría hacer que un campo (la descripción) permita HTML en el que preformaré mi propio saneamiento en un momento posterior.

Rabino
fuente
3
Para futuros visitantes: las respuestas de IMHO, Chris J o Eugene Bosikov son mejores que las aceptadas para versiones posteriores de ASP.NET MVC, especialmente si solo desea permitir HTML en un campo.
lc.

Respuestas:

163

Agregue el siguiente atributo a la acción (publicación) en el controlador para el que desea permitir HTML:

[ValidateInput(false)] 

Editar: según los comentarios de Charlino :

En su web.config configure el modo de validación utilizado. Ver MSDN :

<httpRuntime requestValidationMode="2.0" />

Editar septiembre de 2014: según los comentarios de sprinter252 :

Ahora deberías usar el [AllowHtml]atributo. Ver abajo de MSDN :

Para las aplicaciones ASP.NET MVC 3, cuando necesite volver a publicar HTML en su modelo, no use ValidateInput (false) para desactivar Validación de solicitud. Simplemente agregue [AllowHtml] a la propiedad de su modelo, así:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }
Kelsey
fuente
1
Si está utilizando .NET 4, también deberá configurarlo <httpRuntime requestValidationMode="2.0" />en su archivo web.config.
Charlino
3
¿Realmente no hay una solución para .NET 4 que no incluya la degradación del modo de validación de solicitud?
bzlm
20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) dice que no debe usar ValidateInpute y tomar AllowHtmlAttribute en su lugar. (No encontré la versión en inglés)
Alexander Schmidt
8
Se realizó una edición para, con suerte, abordar los 3 votos iniciales que se hicieron recientemente ... fue una respuesta de 4 años :)
Kelsey
1
@ djack109 Normalmente, no utiliza su modelo EF como modelo de vista. Escribiría una clase separada que represente los datos reales para sus operaciones CRUD. De esta manera, cuando se regenera su modelo EF6, no se pierde nada. También debe reducir los modelos para tener solo las propiedades que necesita para realizar la tarea en cuestión.
Allen Clark Copeland Jr
131

¿Qué pasa con el [AllowHtml]atributo sobre la propiedad?

cryss
fuente
55
Esto me parece una forma mucho mejor, evitando cambiar cualquier comportamiento global. Acabo de resolver mi problema agregando este atributo a una propiedad en mi modelo.
Jonathan Sayce
2
Totalmente de acuerdo con la solución de Chris aquí, no hay ninguna razón para deshabilitar la validación html para toda la aplicación si solo necesita una propiedad en un modelo para poder aceptar la entrada html. Eliminar la validación en web.config abrirá un gran agujero de seguridad en su aplicación.
Miguel
1
Desafortunadamente, esto no funciona si está utilizando MetadataTypeAttribute
dav_i
@dav_i: esta solución funciona bien MetadataTypeAttributey es preferible ya que solo permite HTML en los campos individuales en lugar de en todo el objeto.
Se fue la codificación el
@TrueBlueAussie, lo he intentado durante horas en mi entorno mvc 4.0 y aunque AllowHtml debería funcionar, no funciona. He tenido que admitir la derrota e ir con una opción menos segura que es el pantalón. AllowHtml simplemente no parece funcionar con el uso de MetadataTypeAttribute
julian guppy
42

Añadir al modelo:

using System.Web.Mvc;

Y a su propiedad

        [AllowHtml]
        [Display(Name = "Body")]
        public String Body { get; set; }

Este código desde mi punto la mejor manera de evitar este error. Si está utilizando el editor HTML, no tendrá problemas de seguridad porque ya está restringido.

Eugene Bosikov
fuente
9

Agregar [AllowHtml]la propiedad específica es la solución recomendada, ya que hay muchos blogs y comentarios que sugieren disminuir el nivel de seguridad, lo que debería ser inaceptable.

Al agregar eso, el marco MVC permitirá que se golpee el controlador y se ejecute el código en ese controlador.

Sin embargo, depende de su código, filtros, etc., cómo se genera la respuesta y si hay alguna validación adicional que pueda desencadenar otro error similar.

En cualquier caso, agregar [AllowHtml]atributo es la respuesta correcta, ya que permite que html se deserialice en el controlador. Ejemplo en su modelo de vista:

[AllowHtml]
public string MessageWithHtml {get; set;}
diegosasw
fuente
8

Me enfrenté al mismo problema, aunque agregué [System.Web.Mvc.AllowHtml]a la propiedad en cuestión como se describe en algunas respuestas.

En mi caso, tengo una UnhandledExceptionFilterclase que accede al objeto Solicitud antes de que tenga lugar la validación MVC (y, por lo tanto, AllowHtml no tiene efecto) y este acceso aumenta a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Esto significa que el acceso a ciertas propiedades de un objeto Solicitud activa implícitamente la validación (en mi caso, es la Paramspropiedad).

Se documenta una solución para evitar la validación en MSDN

Para deshabilitar la validación de solicitud para un campo específico en una solicitud (por ejemplo, para un elemento de entrada o valor de cadena de consulta), llame al método Request.Unvalidated cuando obtenga el elemento, como se muestra en el siguiente ejemplo

Por lo tanto, si tiene un código como este

var lParams = aRequestContext.HttpContext.Request.Params;
if (lParams.Count > 0)
{
  ...

cámbielo a

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

var lForm = lUnvalidatedRequest.Form;
if (lForm.Count > 0)
{
  ...

o simplemente use la Formpropiedad que no parece activar la validación

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...
ViRuSTriNiTy
fuente
1
¡Gracias! Solicitud. Sin validar fue la única solución que funcionó para mí.
Petter Ivarsson
3

Si necesita permitir la entrada html para el parámetro del método de acción (en oposición a la "propiedad del modelo"), no hay una forma integrada de hacerlo, pero puede lograrlo fácilmente usando un enlazador de modelos personalizado:

public ActionResult AddBlogPost(int userId,
    [ModelBinder(typeof(AllowHtmlBinder))] string htmlBody)
{
    //...
}

El código AllowHtmlBinder:

public class AllowHtmlBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var name = bindingContext.ModelName;
        return request.Unvalidated[name]; //magic happens here
    }
}

Encuentre el código fuente completo y la explicación en mi blog: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/

Alex
fuente
1
No validado parece estar solo disponible en el marco 4.5 y superior.
Ben
@Ben correcto! Por favor verifique esta solución modificada. stackoverflow.com/questions/59483284/…
om-ha
3

La codificación de URL de los datos también funciona para mí

Por ejemplo

var data = '<b> Hola </b>'

En el navegador, llame a encodeURIComponent (datos) antes de publicar

En el servidor, llame a HttpUtility.UrlDecode (recibido_datos) para decodificar

De esa manera puede controlar exactamente qué área de campos puede tener html

smjhunt
fuente
la manera más fácil hasta ahora
N1gthm4r3
1

Me he enfrentado a este problema durante el desarrollo de un sitio de comercio electrónico utilizando NopCommerce, obtuve esta solución de 3 maneras diferentes, como las respuestas anteriores. Pero de acuerdo con la estructura de NopCommerce, no encontré esos tres a la vez. Acabo de ver que allí están usando solo [AllowHtml]y está funcionando bien, excepto cualquier problema. Como previamente se le preguntó pregunta

Personalmente, no prefiero [ValidateInput(false)]porque estoy omitiendo la comprobación total de la entidad modelo, lo cual es inseguro. Pero si alguien solo escribe mira aquí

[AllowHtml] 
public string BlogText {get;set;}

entonces solo omite solo una propiedad, y solo permite una propiedad en particular y verifica apenas todas las demás entidades. Por lo tanto, parece preferible hacia el mío.

gdmanandamohon
fuente
1

En mi caso, el atributo AllowHtml no funcionaba cuando se combinaba con el filtro de acción OutputCache. Esta respuesta resolvió el problema para mí. Espero que esto ayude a alguien.

jd4w9
fuente
1

Puedes usar [AllowHtml]tu proyecto por ejemplo

 [AllowHtml]
 public string Description { get; set; }

Para usar este código en la biblioteca de clases, instale este paquete

Install-Package Microsoft.AspNet.Mvc

Después de usar esto using

using System.Web.Mvc;
Diako Hasani
fuente
0

Desafortunadamente, ninguna de las respuestas aquí funcionó para mí.

Terminé usando Enlace de modelo personalizado y usé un desinfectante de terceros.

Vea mi pregunta contestada aquí .

om-ha
fuente