I have the following view model, which accepts a password change value. As such, it should accept special characters, including characters that trigger the HttpRequestValidationException
- '<' and '>'. So I added the [AllowHtml]
attribute on the appropriate properties:
public class ChangePasswordModel
{
public bool ShowPassword { get; set; }
public string UserMessage { get; set; }
[Required]
[StringLength(int.MaxValue, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 8)]
[ValidPassword]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[AllowHtml]
public string Password { get; set; }
[DataType(DataType.Password)]
[Required]
[Display(Name = "Confirm password")]
[Compare(nameof(Password), ErrorMessage = "The {1} and {0} do not match.")]
[AllowHtml]
public string ConfirmPassword { get; set; }
}
Here ShowPassword
and UserMessage
are set on the server and used in the view.
When I enter a password such as "<Script/>1234" it all works fine, the model validates, the action is executed, the ViewResult
is executed, and then, somewhere between the ViewResult
and the client, an HttpRequestValidationException
is thrown with this stack trace:
Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
I'm catching it in Global.asax.cs in the Application_Error
event, where it's too late to return any useful information to the user except a generic message.
What I tried:
- I have a global
HandleErrorAttribute
where I detect anHttpRequestValidationException
and return it to the user as a validation message in the view. This works fine with other models and views when the user enters HTML where he is not allowed to, but in this case the attribute'sOnException
override is not triggered. - I decorated the specific action with the above attribute
- I implemented
IResultFilter
in the above attribute and overrode theOnResultExecuted
, to test if the exception is thrown after the view execution. TheResultExecutedContext.Exception
property was null. - I overrode the
BindModel
method of theDefaultModelBinder
just to see if it throws an exception, but it doesn't. - I upgraded Application Insights, mentioned in the stack trace, to the latest version, from 2.16 to 2.20.
- This model has its attributes directly on the properties. I tried moving them to a metadata type, using the
[MetadataType]
attribute. It worked, except that the exception was still thrown.
At this point, I'm out of ideas as to why the exception is thrown, and how to prevent or catch it. Any help is appreciated.