【问题标题】:AllowHtml works on Create but not on Edit ASP.Net MVC 5AllowHtml 适用于 Create 但不适用于 Edit ASP.Net MVC 5
【发布时间】:2017-01-12 19:42:42
【问题描述】:

这是一个ASP.Net MVC 5 项目

我有一个简单的模型,它的一个属性允许HTML 输入:

public class FooModel {
    //other properties

    [AllowHtml]
    public string BarField { get; set; }
}

还有一个使用模型的控制器如下图:

[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]
public class FooController : Controller {
    //some other codes...

    // GET: Foo/Create
    public ActionResult Create(int? id, int number = 0) {
      //some code
    }

    // POST: Foo/Create
    [HttpPost]
    public ActionResult Create(FooModel fooModel) {
        //some code
    }

    // GET: Foo/Edit/5
    public ActionResult Edit(int? id, int number = 0) {
        //some code
    }

    // POST: Foo/Edit/5
    [HttpPost]
    public ActionResult Edit(FooModel model, FormCollection collection) {
        //some code
    }
}

在阅读了 SO 中的一些帖子后:

  1. AllowHtml attribute not working
  2. AllowHtml attribute doesn't work
  3. AllowHtml not working

我知道必须执行以下操作以确保 AllowHtml 属性起作用:

  1. 在 web.config 中使用 <httpRuntime requestValidationMode="2.0" />
  2. 清除模型传递和使用的控制器的缓存[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]

因此,我的 <system.web> 在 web.config 中有以下完整元素:

  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.6" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0" />
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>
  </system.web>

而且,如您所见,我还在控制器顶部放置了OutputCache 属性:

[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]

现在,这对Create Action 非常有效(也就是说,我可以在BarField 中插入HTML 元素,并且帖子被接受并且Action 被调用没有问题)。

但是当我执行Edit 动作时,甚至没有调用该动作并且错误:

从客户端检测到有潜在危险的 Request.Form 值(此处为 BarField="...words 以及此处<...>

描述:ASP.NET 在请求中检测到具有潜在危险的数据,因为它可能包含 HTML 标记或脚本。这些数据可能表示试图破坏您的应用程序的安全性,例如跨站点脚本攻击。如果这种类型的输入适合您的应用程序,您可以在网页中包含代码以明确允许它。有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkID=212874

显示在页面上。为什么会这样?

【问题讨论】:

  • Edit()方法中移除FormCollection collection参数
  • @StephenMuecke 就是这样!有用!谢谢,Pal... :D 但是为什么FormCollection 会阻碍表单提交?
  • 因为您将发布的值绑定到您的模型(并且[AllowHtml] 处理BarField 属性上的请求),但您还绑定到FormCollectionNameValueCollection)虽然你可以使用[ValidateInput(false)],但没有应用属性(无论如何都不能),但没有理由将相同的值绑定到2个不同的模型,也没有理由在MVC中使用FormCollection /跨度>
  • @StephenMuecke 我明白了……原来如此……再次感谢!你已经帮了我好几次了!我刚刚在您回答的一个问题上悬赏以表达我的感激之情:stackoverflow.com/questions/29142422/…
  • 没有必要,但很感激 :)。我试图为此找到一个合适的骗子,但大多只找到未回答的问题或没有任何解释的答案。如果我没有找到任何东西,我稍后会添加一个答案,然后使用我的欺骗锤关闭一些类似的未回答问题。

标签: c# html asp.net asp.net-mvc validation


【解决方案1】:

由于您在Edit() 方法中包含了一个附加参数FormCollection collection,因此引发了异常。

当您应用[AllowHtml] 属性时,它会将属性ModelMetadataRequestValidationEnabled 属性设置为false。在模型绑定过程中,DefaultModelBinder 会检查这个值,因为它的false,绑定到你的模型时不会抛出异常。

但是,FormCollection 只是一个 NameValueCollection,并通过读取 Request.Form 值来填充。没有模型和关联的元数据,因此抛出异常。如果您要使用,会发生完全相同的情况

var barField= Request["BarField"];

虽然使用RequestUnvalidated 属性会起作用

var barField = Request.Unvalidated.Form["BarField"];

您也可以通过将[ValidateInput(false)] 属性应用于方法来使其工作,但这将应用于整个模型并且是禁用请求验证的最不安全的方法。

删除Edit() 方法中的FormCollection collection 参数将解决问题,无论如何,真的没有理由在MVC 中使用FormCollection(您应该始终绑定到模型)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2022-08-16
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多