mvc 提交Html内容的处理

默认

image

方法1

[ValidateInput(false)]

这个方法会完全开放,对于有些字段允许,有些字段不允许的情况,是不会检测的

方法2

[AllowHtml]

此方法只有再使用DefaultModelBinder的时候才有效

public ActionResult Index(FormCollection form)

如使用FormCollection是不起作用的。因为FormCollection与具体的Model并无关联

检测不通过,就报错的方式似乎也并不是很友好,如果输入的文本确实需要包含<script标签,那就没法添加成功了

假设允许输入,但是自动传唤成HtmlEncode形式,是否会更好。

可采用自定义ModelBinder的方式

public class MvcHtmlModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
    {
        var propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
        if (propertyMetadata.RequestValidationEnabled && propertyDescriptor.PropertyType == typeof(string) && value != null && !string.IsNullOrEmpty(value.ToString()))
        {
            value = value.ToString()
                .Replace("<script", "&lt;script")
                .Replace("</script>", "&lt;/script&gt;");
        }
        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
    }
}

在global里

ModelBinders.Binders.Add(typeof(TestModel), new MvcHtmlModelBinder());
image

这样,当更新Model以后,允许html的,还是html,而不允许html的,进行了Encode。

当我们把这样的数据记录到数据库,再读出来时(比如编辑页面)

image

允许html的,和我们输入的一致,而不允许html的,读出来的encode后的,和我们输入的是不一致的。

我们希望在Html.TextBoxFor时,可以再转回来

public class MvcHtmlModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        var meta = base.GetMetadataForProperty(modelAccessor, containerType, propertyDescriptor);
        if (meta.RequestValidationEnabled && meta.ModelType == typeof(string))
        {
            if (meta.Model != null && !string.IsNullOrEmpty(meta.Model.ToString()))
            {
                meta.Model = meta.Model.ToString().Replace("&lt;", "<").Replace("&gt;", ">");
            }
        }
        return meta;
    }
}

global里

ModelMetadataProviders.Current = new MvcHtmlModelMetadataProvider();
之后,我们使用类似这样的代码
public ActionResult Index()
{
    var obj = new TestModel
    {
        Html = "<script>alert(1)</script>",
        Text = "&lt;script>alert(1)&lt;/script&gt;"
    };
    return View(obj);
}

他显示的结果是转回来的

image

但是,如果你是直接输出

@Model.Text

还是转意过的代码

以上代码只为说明,请勿直接用于生产

原文地址:https://www.cnblogs.com/czcz1024/p/3598731.html