Подтвердить что ты не робот

Как избежать исключения HttpRequestValidationException в ASP.NET MVC, отображая тот же вид, который вызвал исключение

Я просто хочу знать, как проверить (или очистить) ввод пользователя в ASP.NET MVC, чтобы исключение HttpRequestValidationException не было выбрано независимо от представленных значений. Например, при вводе текста, если пользователь вводит <BR/>, это вызовет исключение, и будет показан желтый экран смерти. Я не хочу этого. Я хочу поймать исключение и сделать видимую удобную для пользователя ошибку в текущем представлении, желательно с элементами управления, загруженными теми же значениями, представленными.

Я нашел это http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html, но для меня это бесполезно. Кроме того, я нашел этот http://msdn.microsoft.com/en-us/library/aa973813.aspx и попытался поместить внутри привязки к модели, но я не мог заставить работать.

4b9b3361

Ответ 1

С последней версией 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>

Ответ 2

В ASP MVC 3 вы можете использовать атрибут [AllowHtml] для отдельных полей/свойств в Model/ViewModel, чтобы отключить проверку только для этого поля, что довольно приятно. Я добавлю этот атрибут к определенным полям в моей модели, а затем использую отличную библиотеку AntiXSS (также доступную через NuGet) для дезинфекции ввода пользователя, вызвав Sanitizer.GetSafeHtmlFragment(mymodel.Description) (где свойство "Описание" является строковым свойством в моей модели представления, которое имеет атрибут [AllowHtml])

Ответ 3

Для очень подробного примера того, как поймать это (и другие) исключения с помощью фильтра, см.: 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;
  }
}

}

Ответ 4

Вместо того, чтобы ловить ошибку в global.asax Application_Error, вы можете поймать ее, добавив обработчик ошибок для контроллера, который явно улавливает эту ошибку и перенаправляет на представление сообщение об ошибке и соответствующие данные вида.

Я нашел это, несколько старым, post о том, как это сделать с атрибутами.

Ответ 5

ValidateInputAttribute - это правильный метод отключения проверки запроса. Декларативный метод в представлении (aspx) не работает, потому что контроллер отвечает за получение запроса (не view/aspx).

Ответ 6

Поместите put ValidateRequest = "false" в ваше объявление представления aspx, но очистите пользователя от ввода текста внутри вашего кода, чтобы избежать некоторых атак xss.