ASP.Net Mvc 3网站中的AllowHtml无法工作

5
我们尝试在ViewModel属性上使用[AllowHtml]修饰符,以避免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

你一定是做错了什么。不幸的是,由于你没有展示你的例子,我们无法知道你做错了什么。因此,让我为你写一个完整的工作示例:

模型:

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

所以你必须做些不同于我在这里展示的事情。那是什么呢?


Darin - 感谢您的帖子,我已经添加了上面的代码。我们在代码中做了一些额外的事情,但我认为它遵循了您为我概述的基本模型。我没有看到任何理由,说明我提交的代码不会起作用。 - Russ Clark
@RussClark,你的代码看起来没有问题。如果你能给我发一个示例VS项目来说明问题,我非常乐意帮助你检查并尝试解决问题。 - Darin Dimitrov
@DarinDimitrov,感谢您的建议,它启发了我的答案(https://dev59.com/6F_Va4cB1Zd3GeqPQSK1#8838807),看起来已经解决了这个问题。 - ahsteele

2
在他的答案中,当Darin问道:

那么你一定要做一些不同于我在这里展示的事情。是什么呢?

我猜测您可能有其他影响ASP.NET管道的东西,这些东西会在考虑您的[AllowHtml]之前访问FormCollection。就我所知,一些常见的ASP.NET MVC OSS库会触及管道,例如ELMAHGlimpseWebActivatorMvcContrib等等。

我相信您正在使用上述工具或类似的东西。假设您正在使用,请确保您使用的每个工具都是最新版本,并检查它们的开放错误报告。

最后,确定是您的代码、MVC实例还是OSS库的快速方法是创建一个测试项目。尝试创建一个普通的ASP.NET MVC项目。确保AllowHtml有效。然后添加各种OSS组件,直到它崩溃。只是确保在添加OSS组件时,版本与您当前项目中使用的版本匹配。


原来我们使用的是 Glimpse 的 0.81 版本,当我们更新到当前版本时,它现在可以正常工作了。 - Russ Clark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接