Asp.net mvc 允许用户在ASP.NET MVC-ValidateInput或AllowHtml中输入HTML

Asp.net mvc 允许用户在ASP.NET MVC-ValidateInput或AllowHtml中输入HTML,asp.net-mvc,validation,validate-request,Asp.net Mvc,Validation,Validate Request,如何允许用户使用ASP.net MVC将HTML输入特定字段 我有一个长表单,其中有许多字段映射到控制器中的这个复杂对象 我想创建一个允许HTML的字段(描述),我将在以后对其进行预处理。在控制器中添加以下属性,即您希望允许HTML的操作(post): [ValidateInput(false)] 编辑:根据评论: 在web.config中设置使用的验证模式。见: 属性上方的[allowtml]属性如何?添加到模型: using System.Web.Mvc; 还有你的财产

如何允许用户使用ASP.net MVC将HTML输入特定字段

我有一个长表单,其中有许多字段映射到控制器中的这个复杂对象


我想创建一个允许HTML的字段(描述),我将在以后对其进行预处理。

在控制器中添加以下属性,即您希望允许HTML的操作(post):

[ValidateInput(false)] 
编辑:根据评论:

在web.config中设置使用的验证模式。见:


属性上方的
[allowtml]
属性如何?

添加到模型:

using System.Web.Mvc;
还有你的财产

        [AllowHtml]
        [Display(Name = "Body")]
        public String Body { get; set; }

从我的观点来看,这段代码是避免此错误的最佳方法。如果您使用的是HTML编辑器,您将不会遇到安全问题,因为它已经受到限制。

在特定属性上添加
[allowtml]
是推荐的解决方案,因为有大量的博客和评论建议降低安全级别,这应该是不可接受的

通过添加这一点,MVC框架将允许命中控制器并执行控制器中的代码

但是,这取决于您的代码、过滤器等。响应是如何生成的,以及是否存在可能触发另一个类似错误的进一步验证

在任何情况下,添加
[allowtml]
属性都是正确的答案,因为它允许在控制器中反序列化html。viewmodel中的示例:

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

尽管我在一些答案中描述的相关属性中添加了
[System.Web.Mvc.allowtml]
,但我还是面临着同样的问题

在我的例子中,我有一个
UnhandledExceptionFilter
类,它在进行MVC验证之前访问请求对象(因此AllowHtml无效),并且此访问会引发一个潜在危险的请求
[HttpRequestValidationException]。从客户端检测到表单值

这意味着,访问请求对象的某些属性会隐式触发验证(在我的例子中是
Params
属性)

防止验证的解决方案记录在

要禁用请求中特定字段的请求验证(例如,对于输入元素或查询字符串值),请在获取项目时调用request.Unvalidated方法,如下例所示

因此,如果您有这样的代码

var lParams = aRequestContext.HttpContext.Request.Params;
if (lParams.Count > 0)
{
  ...
换成

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

var lForm = lUnvalidatedRequest.Form;
if (lForm.Count > 0)
{
  ...
或者只使用
表单
属性,该属性似乎不会触发验证

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...

我在使用NopCommerce开发电子商务网站的过程中遇到了这个问题,我通过3种不同的方式得到了这个解决方案,就像前面的答案一样。但是根据NopCommerce的结构,我没有一次找到这三个。我刚刚看到他们只使用了
[allowtml]
,除了有任何问题外,它工作正常。如前所述

我个人不喜欢
[ValidateInput(false)]
,因为我跳过了整个模型实体检查,这是不安全的。但如果有人只是写信


然后它只跳过单个属性,只允许特定属性,几乎不检查所有其他实体。因此,它似乎更适合我的

在我的例子中,AllowHtml属性与OutputCache操作筛选器组合时不起作用。帮我解决了这个问题。希望这对其他人有所帮助。

如果您需要允许对操作方法参数进行html输入(与“模型属性”相对),则没有内置方法,但您可以使用自定义模型绑定器轻松实现这一点:

public ActionResult AddBlogPost(int userId,
    [ModelBinder(typeof(AllowHtmlBinder))] string htmlBody)
{
    //...
}
AllowTMLBinder代码:

public class AllowHtmlBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var name = bindingContext.ModelName;
        return request.Unvalidated[name]; //magic happens here
    }
}

在我的博客文章中找到完整的源代码和解释:

URL编码数据对我来说也很有用

比如说

var data='Hello'

过帐前在浏览器中调用组件(数据)

在服务器上调用HttpUtility.UrlDecode(接收的_数据)进行解码


这样,您就可以准确地控制哪些字段区域允许包含html,例如,您可以在项目中使用
[allowtml]

 [AllowHtml]
 public string Description { get; set; }
若要将此代码用于类库,请安装此软件包

Install-Package Microsoft.AspNet.Mvc
使用此
后使用

using System.Web.Mvc;

不幸的是,这里没有一个答案对我有用

我最终使用了自定义模型绑定,并使用了第三方消毒剂


请参阅我的自我回答问题。

如果您使用的是.NET 4,您还必须在web.config文件中设置
。对于.NET 4,真的没有不包括降级请求验证模式的解决方案吗?MSDN()说,您不应该使用ValidateInput,而应该使用AllowTM属性。(找不到英文版)编辑,希望能解决最近的3张反对票。。。这是一个4年前的答案:)@djack109通常,您不使用EF模型作为视图模型。您将编写一个单独的类来表示CRUD操作的实际数据。这样,当重新生成EF6模型时,不会丢失任何内容。您还应该精简模型,使其仅具有执行手头任务所需的属性。对我来说,这似乎是一种更好的方法,可以避免改变任何全局行为。我刚刚通过将此属性添加到模型的属性中解决了问题。完全同意Chris的解决方案,如果模型中只需要一个属性就可以接受html输入,那么没有理由禁用整个应用程序的html验证。删除web.config中的验证将在你的应用程序中打开一个很大的安全漏洞。不幸的是,如果你使用@dav_i,则此解决方案不起作用:此解决方案适用于
MetadataTypeAttribute
,更可取,因为它只允许在单个字段而不是整个对象上使用HTML。@TrueBlueAusie,我已经在我的MVC4.0环境中尝试了几个小时,虽然AllowTML应该可以工作,但它不能工作。我不得不承认失败
 [AllowHtml]
 public string Description { get; set; }
Install-Package Microsoft.AspNet.Mvc
using System.Web.Mvc;