送信された値に関係なくHttpRequestValidationExceptionがスローされないように、ASP.NET MVCでユーザー入力を検証(またはクリーン)する方法を知りたいだけです。たとえば、テキスト入力の場合、ユーザーが<BR/>
、例外が発生し、死の黄色の画面が表示されます。それは欲しくない。例外をキャッチし、現在のビューでユーザーフレンドリーなエラーを表示します。できれば、送信された同じ値でコントロールをロードします。
私はこれを発見しました http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html ですが、それは私の目的には役に立ちません。また、これを見つけました http://msdn.Microsoft.com/en-us/library/aa973813.aspx モデルバインダーの内部に配置しようとしましたが、機能させることができませんでした。
ASP.NET MVCの最新バージョン(これを書いている時点ではRC)を使用すると、コントローラークラスまたはアクションメソッドのいずれかに属性を配置できます。例:
[ValidateInput(false)]
public ActionResult create()
{
// ...method body
}
ValidateInputAttributeはSystem.Web.Mvcにあります。
しかし、他の人が言ったように、あなたはあなた自身の手動入力検証またはクリーニングを実行しなければなりません。
MVC 3を使用して、これがWeb.configにあることも確認する必要があります:<system.web><httpRuntime requestValidationMode="2.0" /></system.web>
ASP MVC 3では、Model/ViewModelの個々のフィールド/プロパティで_[AllowHtml]
_属性を使用して、そのフィールドのみの検証をオフにすることができます。これは非常に便利です。追加します。この属性をモデルの特定のフィールドに適用し、優れた AntiXSS ライブラリ(NuGetからも利用可能)を使用して、Sanitizer.GetSafeHtmlFragment(mymodel.Description)
を呼び出してユーザー入力をサニタイズします(「説明」 propertyは、ビューモデルの文字列プロパティで、_[AllowHtml]
_属性が適用されています)
この(およびその他の)例外をフィルターでキャッチする方法の非常に詳細な例については、以下を参照してください。 http://code.google.com/p/geochat/source/browse/Source/Web/GeoChat.MvcExtensions/ ExceptionHandlerAttribute.cs
これにより、検証をオンに保つことができますが、ユーザーに「死の黄色の画面」が表示されなくなります。
これは簡略化された(おそらく簡略化された)バージョンです。
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public class ExceptionHandlerAttribute : FilterAttribute, IExceptionFilter {
private HandleErrorAttribute attribute = new HandleErrorAttribute();
public ExceptionHandlerAttribute() {
this.ExceptionType = typeof(Exception);
this.Order = 1;
}
public string View {
get {
return attribute.View;
}
set {
attribute.View = value;
}
}
public Type ExceptionType {
get {
return attribute.ExceptionType;
}
set {
attribute.ExceptionType = value;
}
}
public void OnException(ExceptionContext filterContext) {
if (this.ExceptionType.IsInstanceOfType(filterContext.Exception)) {
string controller = (string)filterContext.RouteData.Values["controller"];
string action = (string)filterContext.RouteData.Values["action"];
if (controller == null)
controller = String.Empty;
if (action == null)
action = String.Empty;
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controller, action);
ViewResult result = new ViewResult();
result.ViewName = this.View;
result.MasterName = String.Empty;
result.ViewData = new ViewDataDictionary<HandleErrorInfo>(model);
result.TempData = filterContext.Controller.TempData;
filterContext.Result = result;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
}
}
}
ValidateInputAttributeは、リクエストの検証を無効にするための適切なメソッドです。コントローラーがリクエストの受信を担当しているため(ビュー/ aspxではなく)、ビュー(aspx)内の宣言メソッドは機能しません。
Global.asax Application_Errorでエラーをキャッチする代わりに、このエラーを明示的にキャッチし、エラーメッセージと適切なビューデータでビューにリダイレクトするコントローラーのエラーハンドラーを追加することで、エラーをキャッチできます。
私はこれをやや古い、属性でこれを行う方法について post を見つけました。
ValidateRequest = "false"をaspxビュー宣言に配置しますが、一部のxss攻撃を回避するために、コード内のユーザー入力テキストをサニタイズします。