Tienes pocas opciones.
En el modelo, agregue este atributo a cada propiedad que necesite para permitir HTML: la mejor opción
using System.Web.Mvc;
[AllowHtml]
public string SomeProperty { get; set; }
En la acción del controlador, agregue este atributo para permitir todo HTML
[ValidateInput(false)]
public ActionResult SomeAction(MyViewModel myViewModel)
Fuerza bruta en web.config: definitivamente no se recomienda
En el archivo web.config, dentro de las etiquetas, inserte el elemento httpRuntime con el atributo requestValidationMode = "2.0". También agregue el atributo validateRequest = "false" en el elemento de páginas.
<configuration>
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
<pages validateRequest="false">
</pages>
</configuration>
Más información: http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx
Lo anterior funciona para usos del encuadernador de modelos predeterminado.
ModelBinder personalizado
Parece que una llamada a bindingContext.ValueProvider.GetValue () en el código anterior siempre valida los datos, independientemente de los atributos. Profundizar en las fuentes de ASP.NET MVC revela que DefaultModelBinder primero verifica si se requiere la validación de la solicitud y luego llama al método bindingContext.UnvalidatedValueProvider.GetValue () con un parámetro que indica si la validación es necesaria o no.
Desafortunadamente, no podemos usar ninguno de los códigos del marco porque está sellado, es privado o lo que sea para proteger a los desarrolladores ignorantes de hacer cosas peligrosas, pero no es demasiado difícil crear una carpeta de modelos personalizada que funcione y respete los atributos AllowHtml y ValidateInput:
public class MyModelBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// First check if request validation is required
var shouldPerformRequestValidation = controllerContext.Controller.ValidateRequest && bindingContext.ModelMetadata.RequestValidationEnabled;
// Get value
var valueProviderResult = bindingContext.GetValueFromValueProvider(shouldPerformRequestValidation);
if (valueProviderResult != null)
{
var theValue = valueProviderResult.AttemptedValue;
// etc...
}
}
}
La otra pieza requerida es una forma de recuperar un valor no validado. En este ejemplo usamos un método de extensión para la clase ModelBindingContext:
public static class ExtensionHelpers
{
public static ValueProviderResult GetValueFromValueProvider(this ModelBindingContext bindingContext, bool performRequestValidation)
{
var unvalidatedValueProvider = bindingContext.ValueProvider as IUnvalidatedValueProvider;
return (unvalidatedValueProvider != null)
? unvalidatedValueProvider.GetValue(bindingContext.ModelName, !performRequestValidation)
: bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
}
}
Más información sobre esto en http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/