Permitir que o usuário insira HTML no ASP.NET MVC - ValidateInput ou AllowHtml

120

Como posso permitir que um usuário insira HTML em um campo específico usando o ASP.net MVC.

Eu tenho um formulário longo com muitos campos que são mapeados para esse objeto complexo no controlador.

Gostaria de fazer com que um campo (a descrição) permita HTML, no qual executarei meu próprio saneamento posteriormente.

Rabino
fonte
3
Para futuros visitantes: as respostas de IMHO, Chris J ou Eugene Bosikov são melhores que as aceitas para versões posteriores do ASP.NET MVC, especialmente se você deseja permitir HTML em apenas um campo.
lc.

Respostas:

163

Adicione o seguinte atributo à ação (post) no controlador para o qual você deseja permitir o HTML:

[ValidateInput(false)] 

Editar: De acordo com os comentários de Charlino :

No seu web.config, defina o modo de validação usado. Consulte MSDN :

<httpRuntime requestValidationMode="2.0" />

Editar setembro de 2014: de acordo com o sprinter252 comentários:

Agora você deve usar o [AllowHtml]atributo Veja abaixo no MSDN :

Para aplicativos ASP.NET MVC 3, quando precisar postar HTML de volta ao seu modelo, não use ValidateInput (false) para desativar a Solicitação de Validação. Simplesmente adicione [AllowHtml] à sua propriedade model, assim:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }
Kelsey
fonte
1
Se você estiver usando o .NET 4, também será necessário definir <httpRuntime requestValidationMode="2.0" />seu arquivo web.config.
Charlino 01/09/10
3
Realmente não existe uma solução para o .NET 4 que não inclua o downgrade do modo de validação de solicitação?
bzlm
20
O MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) diz que você não deve usar ValidateInpute e usar AllowHtmlAttribute. (Não encontrou a versão em inglês)
Alexander Schmidt
8
Edição feita para resolver espero que a 3 para baixo votos que foram feitos recentemente ... foi uma resposta 4 anos :)
Kelsey
1
@ djack109 Normalmente, você não usa seu modelo EF como modelo de visualização. Você escreveria uma classe separada que representa os dados reais para suas operações CRUD. Dessa forma, quando seu modelo EF6 for regenerado, nada será perdido. Você também deve reduzir os modelos para ter apenas as propriedades necessárias para executar a tarefa em mãos.
Allen Clark Copeland Jr
131

E o [AllowHtml]atributo acima da propriedade?

Cryss
fonte
5
Parece-me uma maneira muito melhor, evitando alterar qualquer comportamento global. Acabei de resolver meu problema adicionando esse atributo a uma propriedade no meu modelo.
Jonathan Sayce
2
Concordo totalmente com a solução Chris aqui, não há motivo para desativar a validação de html para todo o aplicativo se você precisar de apenas uma propriedade em um modelo para poder aceitar a entrada de html. A remoção da validação no web.config abrirá uma grande falha de segurança no seu aplicativo.
Miguel
1
Infelizmente isso não funciona se você estiver usando MetadataTypeAttribute
dav_i
@av_i: Esta solução funciona bem MetadataTypeAttributee é preferível, pois permite apenas HTML nos campos individuais, e não no objeto inteiro.
Gone Coding
@TrueBlueAussie, tenho tentado por horas no meu ambiente mvc 4.0 e, embora o AllowHtml deva funcionar, ele não funciona. Eu tive que admitir a derrota e escolher uma opção menos segura, que é a calça. O AllowHtml apenas não parecem funcionar com o uso de MetadataTypeAttribute
guppy Julian
42

Adicionar ao modelo:

using System.Web.Mvc;

E para sua propriedade

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

Este código do meu ponto da melhor maneira evitar esse erro. Se você estiver usando o editor de HTML, não terá problemas de segurança porque ele já está restrito.

Eugene Bosikov
fonte
9

Adicionar [AllowHtml]a propriedade específica é a solução recomendada, pois há muitos blogs e comentários sugerindo diminuir o nível de segurança, o que deve ser inaceitável.

Adicionando isso, a estrutura MVC permitirá que o Controlador seja atingido e o código nesse controlador seja executado.

No entanto, depende do seu código, filtros, etc., como a resposta é gerada e se existe alguma validação adicional que possa desencadear outro erro semelhante.

De qualquer forma, adicionar [AllowHtml]atributo é a resposta certa, pois permite que o html seja desserializado no controlador. Exemplo no seu viewmodel:

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

Eu enfrentei o mesmo problema, embora eu tenha adicionado [System.Web.Mvc.AllowHtml]à propriedade em questão, conforme descrito em algumas respostas.

No meu caso, eu tenho uma UnhandledExceptionFilterclasse que acessa o objeto Request antes que a validação do MVC ocorra (e, portanto, AllowHtml não tem efeito) e esse acesso gera a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Isso significa que acessar determinadas propriedades de um objeto Request dispara implicitamente a validação (no meu caso, é a Paramspropriedade).

Uma solução para impedir a validação está documentada no MSDN

Para desativar a validação de solicitação para um campo específico em uma solicitação (por exemplo, para um elemento de entrada ou valor da cadeia de caracteres de consulta), chame o método Request.Unvalidated quando você obtiver o item, conforme mostrado no exemplo a seguir

Portanto, se você tiver um código como este

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

mude para

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

ou apenas use a Formpropriedade que parece não acionar a validação

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...
ViRuSTriNiTy
fonte
1
Obrigado! Request.Unvalidated foi a única solução que funcionou para mim.
Petter Ivarsson
3

Se você precisar permitir a entrada html para o parâmetro do método de ação (ao contrário de "propriedade do modelo"), não há uma maneira integrada de fazer isso, mas você pode facilmente conseguir isso usando um fichário de modelo personalizado:

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

O 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
    }
}

Encontre o código fonte completo e a explicação na minha postagem no blog: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/

Alex
fonte
1
Não validado parece estar disponível apenas na estrutura 4.5 e acima.
Ben
@Ben correto! Por favor, verifique esta solução modificada. stackoverflow.com/questions/59483284/…
om-ha
3

A codificação de URL dos dados também funciona para mim

Por exemplo

var data = '<b> Olá </b>'

Na chamada do navegador, encodeURIComponent (data) antes de postar

No servidor, chame HttpUtility.UrlDecode (received_data) para decodificar

Dessa forma, você pode controlar exatamente qual área de campos pode ter html

smjhunt
fonte
maneira mais fácil até agora
N1gthm4r3
1

Eu enfrentei esse problema durante o desenvolvimento de um site de comércio eletrônico usando o NopCommerce, obtive essa solução de três maneiras diferentes, como nas respostas anteriores. Mas, de acordo com a estrutura do NopCommerce, não encontrei esses três por vez. Acabei de ver que lá eles estão usando apenas [AllowHtml]e está funcionando bem, exceto qualquer problema. Como anteriormente solicitado questão

Pessoalmente, não prefiro [ValidateInput(false)]porque estou ignorando a verificação total de entidades do modelo, o que é inseguro. Mas se alguém escrever, dê uma olhada aqui

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

depois, pule apenas uma propriedade única e permita apenas uma propriedade específica e verifique quase todas as outras entidades. Portanto, parece preferível ao meu.

gdmanandamohon
fonte
1

No meu caso, o atributo AllowHtml não estava funcionando quando combinado com o filtro de ação OutputCache. Esta resposta resolveu o problema para mim. Espero que isso ajude alguém.

jd4w9
fonte
1

Você pode usar o [AllowHtml]seu projeto por exemplo

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

Para usar este código na biblioteca de classes, você instalou este pacote

Install-Package Microsoft.AspNet.Mvc

Após o uso using

using System.Web.Mvc;
Diako Hasani
fonte
0

Infelizmente, nenhuma das respostas aqui funcionou para mim.

Acabei usando o Custom Model Binding e usei um Sanitizer de terceiros.

Veja minha pergunta auto-respondida aqui .

om-ha
fonte