Autoriser l'utilisateur à entrer du code HTML dans ASP.NET MVC - ValidateInput ou AllowHtml

120

Comment puis-je autoriser un utilisateur à saisir du code HTML dans un champ particulier à l'aide d'ASP.net MVC.

J'ai un formulaire long avec de nombreux champs qui sont mappés à cet objet complexe dans le contrôleur.

Je voudrais faire en sorte qu'un champ (la description) autorise le HTML sur lequel je préformerai mon propre assainissement plus tard.

Rabbin
la source
3
Pour les futurs visiteurs: les réponses de IMHO, Chris J ou Eugene Bosikov sont meilleures que celles acceptées pour les versions ultérieures d'ASP.NET MVC, surtout si vous ne souhaitez autoriser le HTML que dans un seul champ.
lc.

Réponses:

163

Ajoutez l'attribut suivant l'action (post) dans le contrôleur pour lequel vous souhaitez autoriser le HTML:

[ValidateInput(false)] 

Edit: Selon les commentaires de Charlino :

Dans votre web.config, définissez le mode de validation utilisé. Voir MSDN :

<httpRuntime requestValidationMode="2.0" />

Edit septembre 2014: selon sprinter252 commentaires:

Vous devez maintenant utiliser l' [AllowHtml]attribut. Voir ci-dessous à partir de MSDN :

Pour les applications ASP.NET MVC 3, lorsque vous devez publier du code HTML dans votre modèle, n'utilisez pas ValidateInput (false) pour désactiver la validation des demandes. Ajoutez simplement [AllowHtml] à votre propriété de modèle, comme ceci:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }
Kelsey
la source
1
Si vous utilisez .NET 4, vous devrez également définir <httpRuntime requestValidationMode="2.0" />dans votre fichier web.config.
Charlino
3
N'existe-t-il vraiment aucune solution pour .NET 4 qui n'inclut pas la rétrogradation du mode de validation des demandes?
bzlm le
20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) dit que vous ne devriez pas utiliser ValidateInpute et prendre AllowHtmlAttribute à la place. (N'a pas trouvé la version anglaise)
Alexander Schmidt
8
Modifié pour, espérons-le, répondre aux 3 votes négatifs qui ont été récemment effectués ... c'était une réponse de 4 ans :)
Kelsey
1
@ djack109 En règle générale, vous n'utilisez pas votre modèle EF comme modèle de vue. Vous écririez une classe distincte qui représente les données réelles pour vos opérations CRUD. De cette façon, lorsque votre modèle EF6 est régénéré, rien n'est perdu. Vous devez également réduire les modèles pour n'avoir que les propriétés dont vous avez besoin pour effectuer la tâche à accomplir.
Allen Clark Copeland Jr
131

Qu'en est-il de l' [AllowHtml]attribut au-dessus de la propriété?

cryss
la source
5
Cela me semble être une bien meilleure façon d'éviter de changer de comportement global. Je viens de résoudre mon problème en ajoutant cet attribut à une propriété sur mon modèle.
Jonathan Sayce
2
Tout à fait d'accord avec la solution de Chris ici, il n'y a aucune raison de désactiver la validation html pour l'ensemble de l'application si vous n'avez besoin que d'une propriété dans un modèle pour pouvoir accepter les entrées html. La suppression de la validation dans le web.config ouvrira une grande faille de sécurité dans votre application.
Miguel
1
Malheureusement, cela ne fonctionne pas si vous utilisez MetadataTypeAttribute
dav_i
@dav_i: Cette solution fonctionne bien avec MetadataTypeAttributeet est préférable car elle n'autorise le HTML que sur les champs individuels plutôt que sur l'objet entier.
Fini le codage
@TrueBlueAussie, j'essaie depuis des heures dans mon environnement mvc 4.0 et même si AllowHtml devrait fonctionner, cela ne fonctionne pas. J'ai dû admettre ma défaite et choisir une option moins sûre qui est le pantalon. Le AllowHtml ne semble tout simplement pas fonctionner avec l'utilisation de MetadataTypeAttribute
julian guppy
42

Ajouter au modèle:

using System.Web.Mvc;

Et à votre propriété

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

Ce code de mon point de vue le meilleur moyen d'éviter cette erreur. Si vous utilisez l'éditeur HTML, vous n'aurez pas de problèmes de sécurité car il est déjà restreint.

Eugène Bosikov
la source
9

L'ajout [AllowHtml]de la propriété spécifique est la solution recommandée car de nombreux blogs et commentaires suggèrent de diminuer le niveau de sécurité, ce qui devrait être inacceptable.

En ajoutant cela, le framework MVC permettra au contrôleur d'être atteint et le code de ce contrôleur à exécuter.

Cependant, cela dépend de votre code, de vos filtres, etc., de la manière dont la réponse est générée et de l'existence d'une validation supplémentaire susceptible de déclencher une autre erreur similaire.

Dans tous les cas, l'ajout d'un [AllowHtml]attribut est la bonne réponse, car il permet de désérialiser le html dans le contrôleur. Exemple dans votre viewmodel:

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

J'ai rencontré le même problème bien que j'aie ajouté [System.Web.Mvc.AllowHtml]à la propriété concernant comme décrit dans certaines réponses.

Dans mon cas, j'ai une UnhandledExceptionFilterclasse qui accède à l'objet Request avant la validation MVC (et donc AllowHtml n'a pas d'effet) et cet accès déclenche un [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Cela signifie que l'accès à certaines propriétés d'un objet Request déclenche implicitement la validation (dans mon cas, c'est la Paramspropriété).

Une solution pour empêcher la validation est documentée sur MSDN

Pour désactiver la validation de demande pour un champ spécifique dans une demande (par exemple, pour un élément d'entrée ou une valeur de chaîne de requête), appelez la méthode Request.Unvalidated lorsque vous obtenez l'élément, comme indiqué dans l'exemple suivant

Par conséquent, si vous avez un code comme celui-ci

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

changez-le en

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

ou utilisez simplement la Formpropriété qui ne semble pas déclencher la validation

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...
ViRuSTriNiTy
la source
1
Merci! Request.Unvalidated était la seule solution qui a fonctionné pour moi.
Petter Ivarsson
3

Si vous devez autoriser l'entrée html pour le paramètre de méthode d' action (par opposition à "propriété du modèle"), il n'y a pas de moyen intégré de le faire, mais vous pouvez facilement y parvenir en utilisant un classeur de modèle personnalisé:

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

Le code 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
    }
}

Trouvez le code source complet et l'explication dans mon article de blog: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/

Alex
la source
1
Non validé semble être disponible uniquement dans le framework 4.5 et supérieur.
Ben
@Ben correct! Veuillez vérifier cette solution modifiée. stackoverflow.com/questions/59483284/…
om-ha
3

L'encodage d'URL des données fonctionne aussi bien pour moi

Par exemple

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

Dans le navigateur, appelez encodeURIComponent (données) avant de publier

Sur le serveur, appelez HttpUtility.UrlDecode (receive_data) pour décoder

De cette façon, vous pouvez contrôler exactement la zone de champs autorisée à avoir du HTML

smjhunt
la source
moyen le plus simple jusqu'à présent
N1gthm4r3
1

J'ai rencontré ce problème lors du développement d'un site E-Commerce utilisant NopCommerce, j'ai obtenu cette solution de 3 manières différentes comme les réponses précédentes. Mais selon la structure NopCommerce, je n'ai pas trouvé ces trois à la fois. Je viens de voir que là-bas, ils utilisent juste [AllowHtml]et ça marche bien sauf aucun problème. Comme question précédemment posée

Personnellement, je ne préfère pas [ValidateInput(false)]parce que je saute la vérification totale de l'entité du modèle, ce qui n'est pas sûr. Mais si quelqu'un vient d'écrire, regarde ici

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

alors il ne fait qu'ignorer une seule propriété, et n'autorise qu'une propriété particulière et ne vérifie presque pas toutes les autres entités. Par conséquent, il semble préférable envers le mien.

gdmanandamohon
la source
1

Dans mon cas, l'attribut AllowHtml ne fonctionnait pas lorsqu'il était combiné avec le filtre d'action OutputCache. Cette réponse a résolu le problème pour moi. J'espère que cela aide quelqu'un.

jd4w9
la source
1

Vous pouvez utiliser [AllowHtml]pour votre projet par exemple

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

Pour utiliser ce code dans la bibliothèque de classes, vous installez ce package

Install-Package Microsoft.AspNet.Mvc

Après utilisation using

using System.Web.Mvc;
Diako Hasani
la source
0

Aucune des réponses ici n'a fonctionné pour moi malheureusement.

J'ai fini par utiliser la liaison de modèle personnalisée et j'ai utilisé un désinfectant tiers.

Voir ma question auto-répondue ici .

om-ha
la source