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
HandleErrorAttributewhere I detect anHttpRequestValidationExceptionand 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'sOnExceptionoverride is not triggered. - I decorated the specific action with the above attribute
- I implemented
IResultFilterin the above attribute and overrode theOnResultExecuted, to test if the exception is thrown after the view execution. TheResultExecutedContext.Exceptionproperty was null. - I overrode the
BindModelmethod of theDefaultModelBinderjust 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.