web-dev-qa-db-fra.com

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

Comment 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 mappés sur cet objet complexe dans le contrôleur.

J'aimerais faire en sorte qu'un champ (la description) autorise HTML sur lequel je vais effectuer mon propre assainissement ultérieurement.

106
Rabbi

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

[ValidateInput(false)] 

Edit: Selon Charlino commentaires:

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

<httpRuntime requestValidationMode="2.0" />

Edit Sept 2014: Conformément à sprinter252 commentaires:

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

Pour les applications ASP.NET MVC 3, lorsque vous devez publier le code HTML dans n’utilisez pas ValidateInput (false) pour désactiver Request Validation. Ajoutez simplement [AllowHtml] à votre propriété de modèle, comme suit:

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

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

124
cryss

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 le meilleur moyen d'éviter cette erreur. Si vous utilisez l'éditeur HTML, vous ne rencontrerez aucun problème de sécurité, car il est déjà limité.

41
Eugene Bosikov

L'ajout de [AllowHtml] sur la propriété spécifique est la solution recommandée, car il existe de nombreux blogs et commentaires suggérant de réduire le niveau de sécurité, ce qui devrait être inacceptable.

En ajoutant cela, la structure MVC permettra au contrôleur d'être touché et au code de ce contrôleur d'être exécuté.

Cependant, cela dépend de votre code, de vos filtres, etc. de la façon dont la réponse est générée et de la validation éventuelle d'une autre erreur similaire.

Dans tous les cas, l'ajout de l'attribut [AllowHtml] est la bonne réponse, car cela permet de désérialiser le code HTML dans le contrôleur. Exemple dans votre modèle de vue:

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

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

Dans mon cas, j'ai une classe UnhandledExceptionFilter qui accède à l'objet Request avant La validation MVC a lieu (et par conséquent, AllowHtml n'a pas d'effet) et cet accès génère 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 propriété Params).

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

Pour désactiver la validation de la 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 illustré 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 propriété Form qui ne semble pas déclencher de validation

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

Si vous devez autoriser l'entrée html pour le paramètre action-method (par opposition à "propriété de modèle"), il n'existe pas de moyen intégré de le faire, mais vous pouvez facilement y parvenir à l'aide d'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/

2
Alex

J'ai rencontré ce problème lors du développement d'un site de commerce électronique utilisant NopCommerce. J'ai obtenu cette solution de 3 manières différentes, comme dans les réponses précédentes. Mais selon la structure NopCommerce, je n’ai pas trouvé ces trois éléments à la fois. Je viens de voir qu’ils n’utilisent que [AllowHtml] et que cela fonctionne très bien, sauf en cas de problème. Comme demandé précédemment question

Personnellement, je ne préfère pas [ValidateInput(false)] car je saute la vérification de l'entité de modèle totale, ce qui n'est pas sécurisé. Mais si quelqu'un écrit juste regardez ici

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

alors, il ne fait que sauter une seule propriété, n'autorise qu'une propriété en particulier et ne vérifie pratiquement pas toutes les autres entités. Par conséquent, cela semble préférable envers le mien. 

1
gdmanandamohon

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

1
jd4w9

URL Encodage des données fonctionne aussi pour moi

Par exemple

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

Dans l'appel du navigateur, encodeURIComponent (data) avant de poster

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

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

0
smjhunt