Reputation: 8922
I have a simple feedback form on our website. When users enter html in the page, they should get a validation error message. But they don't. The exception is thrown and caught in:
void Application_Error(object sender, EventArgs e)
{
...
}
The exception caught here is:
A potentially dangerous Request.Form value was detected from the client
at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)
Here is the Asp.net MVC markup:
<form action="<%=Url.Action("Create") %>" method="post" class="data-entry-form">
<fieldset class="comment">
Your thoughts:
<div class="editor-field">
<%= Html.TextAreaFor(model => model.Comment, 10, 2, new { placeholder="your message" }) %>
<%= Html.ValidationMessageFor(model => model.Comment) %>
</div>
<br />
E-mail address (optional)
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Email, new { placeholder="[email protected]" }) %>
<%= Html.ValidationMessageFor(model => model.Email) %>
</div>
<input type="submit" value="Send" />
</fieldset>
</form>
and here is the generated html:
<form action="/feedback/Create/" method="post" class="data-entry-form">
<fieldset class="comment">
Your thoughts:
<div class="editor-field">
<textarea cols="2" id="Comment" name="Comment" placeholder="your message" rows="10">
</textarea>
</div>
<br />
E-mail address (optional)
<div class="editor-field">
<input id="Email" name="Email" placeholder="[email protected]" type="text" value="" />
</div>
<input type="submit" value="Send" />
</fieldset>
</form>
And here is the controller code:
[HttpPost]
public ActionResult Create(Feedback feedback)
{
if (ModelState.IsValid)
{
FillFeedbackObject(feedback);
feedbackRepository.AddFeedback(feedback);
return View("SuccessMessage", new SuccessMessageModel("Thanks for your message!"));
}
return View(feedback);
}
I also have <add key="ClientValidationEnabled" value="true" />
in the appSettings section of the web.config file and I am including jquery.validate.js. So both client side and server side validation fail.
What is wrong?
Upvotes: 0
Views: 4047
Reputation: 10014
Try adding the [ValidateInput(false)]
attribute to your controller action method.
Source: http://msdn.microsoft.com/en-us/library/system.web.mvc.validateinputattribute.aspx
Edit: If you still want to validate, you should encode the input before sending to the server, for example using HttpUtility.HtmlEncode
. The reason the validation blocks the code is because it could be malicious. By encoding it you can allow it to pass through and still have validation enabled. However you may need to change your validation rules/attributes to account for the encoding. In case it wasn't clear before, this option requires validating on the server side once you get to the controller, adding an error to the ModelState as needed, and returning the same view or partial view as needed in case of errors.
Upvotes: 1
Reputation: 6741
It's not technically a Model's error, that's why you cannot handle it with Model.IsValid
code statement.
If you actually allow html to be submitted in this field or want to sanitize submitted value on server you may annotateComment
property of your model with [AllowHtml] attribute. Also, if you want to notify user that they cannot include tags in the text, you may add an error to ModelState
during feedback parsing on server side with ModelState.AddModelError() method.
Upvotes: 2
Reputation: 684
With MVC 3 and above you can use the AllowHtml attribute with the property that can contain some html
Upvotes: 0
Reputation: 16585
Obviously, leaving request validation in place has it's advantages, and you're correct disabling request validation shouldn't be taken lightly. But there's no graceful way to handle this exception in ASP.NET because it happens so early in the pipeline. It's the actual framework protecting you from yourself.
You can use the Application_Error
event that you pointed out in your original post. The come up with some code like:
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
if (exception is HttpRequestValidationException)
{
// use Response.Redirect to get the user back to the page, and use session/querystring to display an error
}
}
Upvotes: 1