Consenti all'utente di inserire HTML in ASP.NET MVC - ValidateInput o AllowHtml


120

Come posso consentire a un utente di inserire HTML in un campo particolare utilizzando ASP.net MVC.

Ho un modulo lungo con molti campi che vengono mappati su questo oggetto complesso nel controller.

Vorrei fare in modo che un campo (la descrizione) consenta l'HTML su cui preformerò la mia igiene personale in un secondo momento.


3
Per i futuri visitatori: le risposte di IMHO, Chris J o Eugene Bosikov sono migliori di quelle accettate per le versioni successive di ASP.NET MVC, soprattutto se si desidera consentire l'HTML in un solo campo.
lc.

Risposte:


163

Aggiungi il seguente attributo l'azione (post) nel controller per cui desideri consentire l'HTML:

[ValidateInput(false)] 

Modifica: come da commenti di Charlino :

Nel tuo web.config imposta la modalità di convalida utilizzata. Vedi MSDN :

<httpRuntime requestValidationMode="2.0" />

Modifica settembre 2014: come da commenti dello sprinter252 :

Ora dovresti usare il file [AllowHtml] attributo. Vedi sotto da MSDN :

Per le applicazioni ASP.NET MVC 3, quando è necessario inviare di nuovo HTML al modello, non utilizzare ValidateInput (false) per disattivare la convalida della richiesta. Aggiungi semplicemente [AllowHtml] alla proprietà del modello, in questo modo:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }

1
Se stai usando .NET 4 dovrai anche impostare <httpRuntime requestValidationMode="2.0" />nel tuo file web.config.
Charlino

3
Non esiste davvero alcuna soluzione per .NET 4 che non includa il downgrade della modalità di convalida della richiesta?
bzlm

20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) dice che non dovresti usare ValidateInpute e prendere invece AllowHtmlAttribute. (Non ho trovato la versione inglese)
Alexander Schmidt

8
Modificato per rispondere, si spera, ai 3 voti negativi che sono stati recentemente fatti ... era una risposta di 4 anni :)
Kelsey

1
@ djack109 In genere, non si utilizza il modello EF come modello di visualizzazione. Dovresti scrivere una classe separata che rappresenta i dati effettivi per le tue operazioni CRUD. In questo modo quando il tuo modello EF6 viene rigenerato, nulla viene perso. Dovresti anche snellire i modelli per avere solo le proprietà necessarie per eseguire l'attività in questione.
Allen Clark Copeland Jr

131

E l' [AllowHtml]attributo sopra la proprietà?


5
Questo mi sembra un modo molto migliore, evitando di cambiare qualsiasi comportamento globale. Ho appena risolto il mio problema aggiungendo questo attributo a una proprietà sul mio modello.
Jonathan Sayce

2
Completamente d'accordo con la soluzione di Chris qui, non c'è motivo di disabilitare la convalida html per l'intera applicazione se hai solo bisogno di una proprietà in un modello per poter accettare l'input html. La rimozione della convalida nel web.config aprirà una grande falla di sicurezza nella tua app.
Miguel

1
Sfortunatamente questo non funziona se stai usando MetadataTypeAttribute
dav_i

@dav_i: questa soluzione funziona bene MetadataTypeAttributeed è preferibile in quanto consente solo l'HTML sui singoli campi piuttosto che sull'intero oggetto.
Codifica andata il

@TrueBlueAussie, ho provato per ore nel mio ambiente mvc 4.0 e sebbene AllowHtml dovrebbe funzionare, non funziona. Ho dovuto ammettere la sconfitta e scegliere un'opzione meno sicura che sono i pantaloni. AllowHtml sembra non funzionare con l'uso di MetadataTypeAttribute
julian guppy

42

Aggiungi al modello:

using System.Web.Mvc;

E alla tua proprietà

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

Questo codice dal mio punto di vista il modo migliore per evitare questo errore. Se utilizzi l'editor HTML non avrai problemi di sicurezza perché è già limitato.


9

L'aggiunta [AllowHtml]della proprietà specifica è la soluzione consigliata poiché ci sono molti blog e commenti che suggeriscono di diminuire il livello di sicurezza, il che dovrebbe essere inaccettabile.

Aggiungendo ciò, il framework MVC consentirà di colpire il controller e di eseguire il codice in quel controller.

Tuttavia, dipende dal codice, dai filtri, ecc. Come viene generata la risposta e se è presente un'ulteriore convalida che potrebbe attivare un altro errore simile.

In ogni caso, l'aggiunta di [AllowHtml]attributi è la risposta giusta, in quanto consente di deserializzare html nel controller. Esempio nel tuo viewmodel:

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

8

Ho affrontato lo stesso problema anche se ho aggiunto [System.Web.Mvc.AllowHtml]alla proprietà in questione come descritto in alcune risposte.

Nel mio caso, ho una UnhandledExceptionFilterclasse che accede all'oggetto Request prima che avvenga la convalida MVC (e quindi AllowHtml non ha effetto) e questo accesso solleva un file [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Ciò significa che l'accesso a determinate proprietà di un oggetto Request attiva implicitamente la convalida (nel mio caso è la Paramsproprietà).

Una soluzione per impedire la convalida è documentata su MSDN

Per disabilitare la convalida della richiesta per un campo specifico in una richiesta (ad esempio, per un elemento di input o un valore di stringa di query), chiamare il metodo Request.Unvalidated quando si ottiene l'elemento, come mostrato nell'esempio seguente

Pertanto, se hai un codice come questo

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

cambiarlo in

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

o semplicemente utilizzare la Formproprietà che non sembra attivare la convalida

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...

1
Grazie! Request.Unvalidated era l'unica soluzione che ha funzionato per me.
Petter Ivarsson

3

Se è necessario consentire l'input html per il parametro del metodo di azione (al contrario di "proprietà del modello") non esiste un modo integrato per farlo, ma è possibile farlo facilmente utilizzando un raccoglitore di modelli personalizzato:

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

Il codice 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
    }
}

Trova il codice sorgente completo e la spiegazione nel mio post sul blog: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/


1
Non convalidato sembra essere disponibile solo nel framework 4.5 e versioni successive.
Ben

@ Ben corretto! Si prega di controllare questa soluzione modificata. stackoverflow.com/questions/59483284/…
om-ha

3

La codifica URL dei dati funziona anche per me

Per esempio

var data = "<b> Hello </b>"

Nel browser chiama encodeURIComponent (data) prima di pubblicare

Su Server chiama HttpUtility.UrlDecode (ricevuti_data) per decodificare

In questo modo puoi controllare esattamente quale area dei campi può avere html


modo più semplice finora
N1gthm4r3

1

Ho affrontato questo problema durante lo sviluppo di un sito di e-commerce utilizzando NopCommerce, ho ottenuto questa soluzione in 3 modi diversi come le risposte precedenti. Ma secondo la struttura di NopCommerce non ho trovato quei tre alla volta. Ho appena visto che lì stanno usando solo [AllowHtml]e funziona bene tranne qualsiasi problema. Come precedentemente chiesto domanda

Personalmente non preferisco [ValidateInput(false)]perché sto saltando il controllo totale dell'entità del modello, il che non è sicuro. Ma se qualcuno scrive, dai un'occhiata qui

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

quindi salta solo una singola proprietà e consente solo una proprietà particolare e controlla a malapena tutte le altre entità. Quindi sembra preferibile al mio.


1

Nel mio caso, l'attributo AllowHtml non funzionava se combinato con il filtro di azione OutputCache. Questa risposta ha risolto il problema per me. Spero che questo aiuti qualcuno.


1

Puoi usare il [AllowHtml]tuo progetto per esempio

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

Per utilizzare questo codice nella libreria di classi, installare questo pacchetto

Install-Package Microsoft.AspNet.Mvc

Dopo l'uso questo using

using System.Web.Mvc;

0

Sfortunatamente, nessuna delle risposte qui ha funzionato per me.

Ho finito per utilizzare Custom Model Binding e ho utilizzato un disinfettante di terze parti.

Vedi la mia domanda di auto-risposta qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.