Как избежать исключения HttpRequestValidationException в ASP.NET MVC, отображающего то же представление, которое вызвало исключение - PullRequest
36 голосов
/ 30 октября 2008

Я просто хочу знать, как проверить (или очистить) пользовательский ввод в 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 и попытался поместить в подшивку модели, но я не мог заставить работать.

Ответы [ 6 ]

40 голосов
/ 16 февраля 2009

В последней версии ASP.NET MVC (RC, на момент написания этой статьи) вы можете просто добавить атрибут в ваш класс контроллера или в метод действия, например ::10000

[ValidateInput(false)]
public ActionResult create()
{
    // ...method body
}

Атрибут ValidateInputAttribute находится в System.Web.Mvc.

Но, как уже говорили другие, вам придется самостоятельно выполнять проверку или очистку ввода вручную.

Используя MVC 3, вы также должны убедиться, что это есть в вашем Web.config: <system.web><httpRuntime requestValidationMode="2.0" /></system.web>

11 голосов
/ 10 февраля 2011

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

4 голосов
/ 04 марта 2010

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

}

1 голос
/ 21 июня 2009

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

1 голос
/ 02 ноября 2008

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

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

0 голосов
/ 31 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...