Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AllowHtml not working for ASP.Net Mvc 3 site

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>
like image 775
Russ Clark Avatar asked Jan 10 '12 20:01

Russ Clark


1 Answers

You gotta be doing something wrong. Unfortunately as you haven't shown your example we cannot know what you are doing wrong. So let me write you a full working example:

Model:

public class MyViewModel
{
    [AllowHtml]
    public string RequestText { get; set; }
}

Controller:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            RequestText = "<strong>Hello World</strong>";
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

View:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.TextAreaFor(x => x.RequestText)
    <button type="submit">OK</button>
}

So you gotta be doing something different than what I showed here. What is it?

like image 73
Darin Dimitrov Avatar answered Sep 27 '22 15:09

Darin Dimitrov