2009-01-28 14 views
30

Ich habe ein ASP.NET-MVC-Formular, das möglicherweise (in der Regel) eine Antwort sendet, die den Fehler "Eine potenziell gefährliche Request.Form Wert wurde vom Client erkannt" ausgelöst wird.Kann die ValidateRequest-Einstellung einer Seite außer Kraft gesetzt werden?

Um dies zu umgehen, habe ich ein ValidateRequest = "false" in der Seiten-Direktive platziert.

Nur Problem: Ich bekomme immer noch den Fehler!

Nun, alles war gut, bis ich heute Morgen auf den ASP.NET MVC RC aktualisiert, und (nach der readme), stellte die folgenden in den Ansichten web.config:

<pages validateRequest="false" 
     pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" 
     pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" 
     userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> 
    <controls> 
     <add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /> 
    </controls> 
</pages> 

So validateRequest sollte für alle Seiten falsch sein, oder? Was vermisse ich?

+0

Die Ansichten web.config gilt nur beim Surfen direkt in den Ordner Ansichten, richtig? – bzlm

+0

Ja, das ist richtig. –

Antwort

62

In MVC erfolgt die Validierung auf Controller-Ebene, nicht auf Seitenebene. Um zu verstehen, warum dies so ist, sollten Sie bedenken, dass zu dem Zeitpunkt, zu dem die Controller-Aktion ausgeführt wird, wir nicht wissen, welche Ansicht zum Rendern ausgewählt wird. (Tatsächlich wird die Controller-Aktion möglicherweise gar nicht angezeigt. Es könnte stattdessen eine Datei-Download-Eingabeaufforderung auf dem Client geöffnet werden.) Wenn ein Benutzer böswillige Eingaben an den Server sendet, wird die Anzeige sogar wiedergegeben zu spät, um etwas dagegen zu unternehmen. Der Controller hat die gefährliche Eingabe bereits in die Datenbank übernommen.

Stattdessen bitte dekorieren Sie den Controller oder die Aktion mit dem Attribut [ValidateInput (false)]. Dies führt dazu, dass wir die Anforderungsvalidierung für diesen Controller oder diese Aktion unterdrücken.

+0

Das hat sehr geholfen. –

+0

In der Tat, Danke! – Aaron

+0

+1 für nicht nur eine Antwort geben, sondern bieten, warum es so funktioniert. Immer gut zu wissen, wie man etwas macht, aber immer besser zu wissen, warum etwas zu tun ist. – JakeJ

2

Wir haben eine Basis-Controller, die unsere Steuerungen von erben, so dass wir intrinsische ASP.NET Anforderungsüberprüfung global deaktivieren:

protected override void Initialize(RequestContext requestContext) 
    { 
     // no client input will be checked on any controllers 
     ValidateRequest = false; 
     base.Initialize(requestContext); 
    } 

einfach sicher, dass Sie Validieren alle Eingaben vom Client!

17

It`s necesary den Controller oder eine Aktion mit dem Attribut [ValidateInput (false)] dekorieren und fügen requestValidationMode = "2.0" der Datei Web.config: Beispiel:

Der Controller:

[ValidateInput(false)] 
    public class MensajesController : Controller 
    { 
     //or in an action 
     [ValidateInput(false)] 
     [HttpPost] 
     public ActionResult Create(FormCollection collection) 
     { 
     } 
    } 

Die Konfigurationsdatei:

<configuration> 
     <system.web> 
      <httpRuntime requestValidationMode="2.0"/> 
     </system.web> 
    </configuration> 
+3

Ja, der requestValidationMode muss für .NET 4 eingestellt werden. Danke für das Update. –

2

ich hatte ein ähnliches Problem mit ASP.NET MVC 3 mit .NET 4.0 und der Windows Azure Access Control Service-v2, wo ich den Fehler bekommen würde:

System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo..."). 

und fand eine bessere Lösung als das Ausschalten war die Validierung einen benutzerdefinierten RequestValidator zu implementieren, wie in diesem Artikel beschrieben:

http://social.technet.microsoft.com/wiki/contents/articles/windows-identity-foundation-wif-a-potentially-dangerous-request-form-value-was-detected-from-the-client-wresult-quot-lt-t-requestsecurityto-quot.aspx

public class SampleRequestValidator : RequestValidator 
{ 
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) 
    { 
     validationFailureIndex = 0; 
     if (requestValidationSource == RequestValidationSource.Form && collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal)) 
     { 
      SignInResponseMessage message = WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage; 
      if (message != null) 
      { 
       return true; 
      } 
     } 
     return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex); 
    } 
} 

der einzige Grund, warum ich die Validierung ausschalten weiter sah als war, weil ich die Validierung, wenn im Anschluss an diese Anleitung in der Windows Azure Platform Training Kit diese Arbeit gesehen ohne ausschalten hatte:

http://msdn.microsoft.com/en-us/WAZPlatformTrainingCourse_IntroToACSLabsV2

Wie auch immer, dies wird hoffentlich von Nutzen jemand sein und könnte einen detailliertere Ansatz zur Lösung dieses Problems in Zukunft. Es sollte beachtet werden, dass der requestValidationMode = "2.0" nicht erforderlich ist, wenn Sie den benutzerdefinierten RequestValidator implementieren.

Verwandte Themen