We're trying to use the [AllowHtml] decoration on one of our ViewModel properties so that we can avoid the YSOD:
A potentially dangerous Request.Form value was detected from the client (RequestText=
"<br>"
).
when we try to submit html text, like: <br>
. We want to then use Server.HtmlEncode within the controller action to prevent attacks, but when we decorate the property with [AllowHtml]
it has no affect, and if we try to use [ValidateInput(false)]
on the controller action, it has no effect either. We saw a StackOverflow Post saying that in MVC 3 RC2 that you have to add:
ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider(); to the global.asax
We tried that too, even though we are using the release version of MVC 3, not RC2, but that had no effect either. Does anyone know how to fix this?
Model:
namespace UI.Models.ViewModel
{
public class CustomerRequestSupport
{
/// <summary>
/// Gets or Sets the textual description entered by the Customer for
/// the support requested.
/// </summary>
[AllowHtml]
public string RequestText { get; set; }
}
}
Controller:
[HttpPost]
[TabsActionFilter]
public ActionResult RequestSupport(CustomerRequestSupport collection)
{
if (ModelState.IsValid)
{
Ticket ticket = new Ticket();
ticket.Requestor = LoggedInCustomer;
ticket.Summary = "General Support Ticket";
ticket.Notes = Server.HtmlEncode(collection.RequestText);
var errors = _ticketService.SubmitTicket(ticket);
if (errors.Any())
{
ModelState.AddModelError("collection",
String.Format("An error has occurred in your Request for Support: " +
"{0} Please try again later or call the help desk " +
"for immediate assistance.",
errors.Aggregate((acc, st) => acc + " " + st)));
}
else
{
TempData["FlashMessage"] = String.Format("Your request for support has been " +
"submitted, the Ticket Number is: {0}.", ticket.TicketNumber);
return AutoMapView<CustomerDetails>(View("Details", base.LoggedInCustomer));
}
}
//needed for tabs to show
ViewData.CustomerContactSet(base.LoggedInCustomer);
return View();
View:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<UI.Models.ViewModel.CustomerRequestSupport>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Request Support
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="PageTitle" runat="server">
Request Support
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm())
{ %>
<%= Html.ValidationSummary() %>
<h2>Enter a description of the support needed</h2>
<%: Html.TextAreaFor( m => m.RequestText, 4, 90, null) %>
<input type="submit" value="Submit" />
<% } %>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="JavaScriptContent" runat="server">
</asp:Content>
In his answer Darin is definitely onto something when he asks
So you gotta be doing something different than what I showed here. What is it?
I am guessing you have something else affecting the ASP.NET pipeline that is accessing the FormCollection
prior to your [AllowHtml]
being taken into account. Off the top of my head some common ASP.NET MVC OSS libraries that touch the pipeline are ELMAH, Glimpse, WebActivator, MvcContrib, there are many more but you get the idea.
I have to believe you are using one of the tools above or something similar. Assuming you are make sure you are on the latest release of each and check their open bug reports.
Finally, a quick way to determine if its your code, your MVC instance or an OSS library would be to create a test project. Try creating a vanilla ASP.NET MVC project. Ensure that AllowHtml
works. Then add in your various OSS components until it breaks. Just be sure when you are adding in OSS components that the versions match what you are using in your current project.