Benutzer darf HTML in ASP.NET MVC eingeben - ValidateInput oder AllowHtml


120

Wie kann ich einem Benutzer erlauben, mit ASP.net MVC HTML in ein bestimmtes Feld einzugeben?

Ich habe eine lange Form mit vielen Feldern, die diesem komplexen Objekt in der Steuerung zugeordnet werden.

Ich möchte, dass ein Feld (die Beschreibung) HTML zulässt, auf das ich zu einem späteren Zeitpunkt meine eigene Hygiene anwenden werde.


3
Für zukünftige Besucher: IMHO, Chris J oder Eugene Bosikovs Antworten sind besser als die für spätere Versionen von ASP.NET MVC akzeptierten, insbesondere wenn Sie nur HTML in einem Feld zulassen möchten.
lc.

Antworten:


163

Fügen Sie dem Controller, für den Sie HTML zulassen möchten, das folgende Attribut der Aktion (Post) hinzu:

[ValidateInput(false)] 

Edit: Wie pro Charlino Kommentare:

Stellen Sie in Ihrer web.config den verwendeten Validierungsmodus ein. Siehe MSDN :

<httpRuntime requestValidationMode="2.0" />

Edit Sept 2014: Gemäß sprinter252 Kommentare:

Sie sollten jetzt das [AllowHtml]Attribut verwenden. Siehe unten von MSDN :

Verwenden Sie für ASP.NET MVC 3-Anwendungen ValidateInput (false) nicht, um die Anforderungsvalidierung zu deaktivieren, wenn Sie HTML zurück in Ihr Modell senden müssen. Fügen Sie einfach [AllowHtml] zu Ihrer Modelleigenschaft hinzu, wie folgt:

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

1
Wenn Sie .NET 4 verwenden, müssen Sie dies auch <httpRuntime requestValidationMode="2.0" />in Ihrer web.config-Datei festlegen.
Charlino

3
Gibt es wirklich keine Lösung für .NET 4, die kein Downgrade des Anforderungsüberprüfungsmodus beinhaltet?
Bzlm

20
Laut MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) sollten Sie ValidateInpute nicht verwenden und stattdessen AllowHtmlAttribute verwenden. (Die englische Version wurde nicht gefunden)
Alexander Schmidt

8
Bearbeitet, um hoffentlich die 3 Abstimmungen zu adressieren, die kürzlich abgegeben wurden ... es war eine 4 Jahre alte Antwort :)
Kelsey

1
@ djack109 Normalerweise verwenden Sie Ihr EF-Modell nicht als Ansichtsmodell. Sie würden eine separate Klasse schreiben, die die tatsächlichen Daten für Ihre CRUD-Operationen darstellt. Auf diese Weise geht bei der Regeneration Ihres EF6-Modells nichts verloren. Sie sollten die Modelle auch verkleinern, um nur die Eigenschaften zu haben, die Sie zur Ausführung der Aufgabe benötigen.
Allen Clark Copeland Jr.

131

Was ist mit [AllowHtml]Attribut über Eigenschaft?


5
Dies scheint mir ein viel besserer Weg zu sein, um zu vermeiden, dass sich ein globales Verhalten ändert. Ich habe gerade mein Problem gelöst, indem ich dieses Attribut einer Eigenschaft in meinem Modell hinzugefügt habe.
Jonathan Sayce

2
Stimmen Sie der Chris-Lösung hier voll und ganz zu. Es gibt keinen Grund, die HTML-Validierung für die gesamte Anwendung zu deaktivieren, wenn Sie nur eine Eigenschaft in einem Modell benötigen, um HTML-Eingaben akzeptieren zu können. Durch Entfernen der Validierung in der Datei web.config wird eine große Sicherheitslücke in Ihrer App geöffnet.
Miguel

1
Leider funktioniert dies nicht, wenn Sie MetadataTypeAttribute
dav_i

@dav_i: Diese Lösung funktioniert gut mit MetadataTypeAttributeund ist vorzuziehen, da nur HTML für die einzelnen Felder und nicht für das gesamte Objekt zulässig ist.
Gone Coding

@TrueBlueAussie, ich habe stundenlang versucht, in meiner MVC 4.0-Umgebung und obwohl AllowHtml funktionieren sollte, funktioniert es nicht. Ich musste mich geschlagen geben und mich für eine weniger sichere Option entscheiden, nämlich die Hose. Das AllowHtml scheint einfach nicht mit der Verwendung von MetadataTypeAttribute zu funktionieren
julian guppy

42

Zum Modell hinzufügen:

using System.Web.Mvc;

Und zu Ihrem Eigentum

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

Dieser Code aus meiner Sicht am besten, um diesen Fehler zu vermeiden. Wenn Sie den HTML-Editor verwenden, treten keine Sicherheitsprobleme auf, da diese bereits eingeschränkt sind.


9

Das Hinzufügen [AllowHtml]der spezifischen Eigenschaft ist die empfohlene Lösung, da es zahlreiche Blogs und Kommentare gibt, die darauf hinweisen, die Sicherheitsstufe zu verringern, was inakzeptabel sein sollte.

Durch Hinzufügen des MVC-Frameworks kann der Controller getroffen und der Code in diesem Controller ausgeführt werden.

Es hängt jedoch von Ihrem Code, Ihren Filtern usw. ab, wie die Antwort generiert wird und ob eine weitere Validierung vorliegt, die einen weiteren ähnlichen Fehler auslösen könnte.

In jedem Fall ist das Hinzufügen von [AllowHtml]Attributen die richtige Antwort, da HTML in der Steuerung deserialisiert werden kann. Beispiel in Ihrem Ansichtsmodell:

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

8

Ich hatte das gleiche Problem, obwohl ich [System.Web.Mvc.AllowHtml]die betreffende Eigenschaft wie in einigen Antworten beschrieben ergänzt habe.

In meinem Fall habe ich eine UnhandledExceptionFilterKlasse, die auf das Request-Objekt zugreift, bevor die MVC-Validierung stattfindet (und daher hat AllowHtml keine Auswirkung), und dieser Zugriff löst a aus [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Dies bedeutet, dass der Zugriff auf bestimmte Eigenschaften eines Request-Objekts implizit die Validierung auslöst (in meinem Fall ist es die ParamsEigenschaft).

Eine Lösung zur Verhinderung der Validierung ist in MSDN dokumentiert

Um die Anforderungsüberprüfung für ein bestimmtes Feld in einer Anforderung zu deaktivieren (z. B. für ein Eingabeelement oder einen Abfragezeichenfolgenwert), rufen Sie die Methode Request.Unvalidated auf, wenn Sie das Element erhalten, wie im folgenden Beispiel gezeigt

Daher, wenn Sie Code wie diesen haben

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

ändere es auf

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

oder verwenden Sie einfach die FormEigenschaft, die keine Validierung auszulösen scheint

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

1
Vielen Dank! Request.Unvalidated war die einzige Lösung, die für mich funktioniert hat.
Petter Ivarsson

3

Wenn Sie eine HTML-Eingabe für den Parameter der Aktionsmethode zulassen müssen (im Gegensatz zu "Modelleigenschaft"), gibt es keine integrierte Möglichkeit, dies zu tun. Sie können dies jedoch einfach mit einem benutzerdefinierten Modellordner erreichen:

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

Der AllowHtmlBinder-Code:

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

Den vollständigen Quellcode und die Erklärung finden Sie in meinem Blogbeitrag: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/


1
Unvalidated scheint nur in Framework 4.5 und höher verfügbar zu sein.
Ben

@ Ben richtig! Bitte überprüfen Sie diese modifizierte Lösung. stackoverflow.com/questions/59483284/…
om-ha

3

Die URL-Codierung der Daten funktioniert auch bei mir

Beispielsweise

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

Rufen Sie im Browser encodeURIComponent (Daten) vor dem Posten auf

Rufen Sie auf dem Server HttpUtility.UrlDecode (receive_data) auf, um zu dekodieren

Auf diese Weise können Sie genau steuern, in welchem ​​Feldbereich HTML zulässig ist


bisher einfachster weg
N1gthm4r3

1

Ich habe dieses Problem bei der Entwicklung einer E-Commerce-Website mit NopCommerce festgestellt. Ich habe diese Lösung auf drei verschiedene Arten erhalten, wie in den vorherigen Antworten. Aber laut der NopCommerce-Struktur habe ich diese drei nicht gleichzeitig gefunden. Ich habe gerade gesehen, dass sie dort nur verwenden [AllowHtml]und es funktioniert gut, außer bei jedem Problem. Wie zuvor gestellte Frage

Persönlich bevorzuge ich es nicht, [ValidateInput(false)]weil ich die Überprüfung der gesamten Modellentität überspringe, was unsicher ist. Aber wenn jemand nur schreibt , schauen Sie hier

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

dann wird nur eine einzelne Eigenschaft übersprungen, nur eine bestimmte Eigenschaft zugelassen und kaum alle anderen Entitäten überprüft. Daher scheint es mir vorzuziehen.


1

In meinem Fall funktionierte das AllowHtml-Attribut in Kombination mit dem OutputCache-Aktionsfilter nicht. Diese Antwort löste das Problem für mich. Hoffe das hilft jemandem.


1

Sie können [AllowHtml]zum Beispiel für Ihr Projekt verwenden

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

Zur Verwendung dieses Codes für die Klassenbibliothek installieren Sie dieses Paket

Install-Package Microsoft.AspNet.Mvc

Nach Gebrauch Dies using

using System.Web.Mvc;

0

Keine der Antworten hier hat bei mir leider funktioniert.

Am Ende habe ich Custom Model Binding verwendet und einen Sanitizer von Drittanbietern verwendet.

Siehe meine selbst beantwortete Frage hier .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.