AllowHtml не работает для сайта ASP.Net Mvc 3 - PullRequest
5 голосов
/ 11 января 2012

Мы пытаемся использовать украшение [AllowHtml] в одном из наших свойств ViewModel, чтобы избежать YSOD:

Потенциально опасное значение Request.Form было обнаружено из клиент (RequestText = "<br>").

когда мы пытаемся отправить HTML-текст, например: <br>. Затем мы хотим использовать Server.HtmlEncode в действии контроллера для предотвращения атак, но когда мы украшаем свойство с помощью [AllowHtml], оно не оказывает влияния, и если мы пытаемся использовать [ValidateInput(false)] для действия контроллера, оно также не оказывает никакого влияния , Мы видели сообщение StackOverflow , в котором говорится, что в MVC 3 RC2 нужно добавить:

ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider (); на global.asax

Мы тоже это попробовали, хотя мы используем релизную версию MVC 3, а не RC2, но это тоже не дало результата. Кто-нибудь знает как это исправить?

Модель:

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; }
    }
}

Контроллер:

    [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();

Вид:

<%@ 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>

Ответы [ 2 ]

7 голосов
/ 11 января 2012

Ты должен делать что-то не так. К сожалению, поскольку вы не показали свой пример, мы не можем знать, что вы делаете неправильно. Итак, позвольте мне написать вам полный рабочий пример:

Модель:

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

Контроллер:

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);
    }
}

Вид:

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

Так что ты должен делать что-то отличное от того, что я здесь показал. Что это?

2 голосов
/ 12 января 2012

В своем ответе Дарин определенно что-то понимает, когда спрашивает

Так что ты должен делать что-то отличное от того, что я здесь показал. Что это?

Я предполагаю, что у вас есть что-то еще, влияющее на конвейер ASP.NET, который обращается к FormCollection до того, как ваш [AllowHtml] будет учтен. На мой взгляд, некоторые распространенные OSS-библиотеки ASP.NET MVC, которые касаются конвейера: ELMAH , Проблеск , WebActivator , MvcContrib Есть еще много, но вы поняли.

Я должен верить, что вы используете один из инструментов выше или что-то подобное. Предполагая, что вы уверены, что используете последнюю версию каждого из них, и проверьте их открытые отчеты об ошибках.

Наконец, быстрый способ определить, будет ли ваш код, ваш экземпляр MVC или библиотека OSS создавать тестовый проект. Попробуйте создать ванильный проект ASP.NET MVC. Убедитесь, что AllowHtml работает. Затем добавьте ваши различные компоненты OSS, пока он не сломается. Просто убедитесь, что при добавлении компонентов OSS версии совпадают с версиями, которые вы используете в своем текущем проекте.

...