在MVC3中允许HTML和自定义IValueProviders

时间:2011-08-04 17:58:25

标签: c# asp.net-mvc-3

我有一个自定义的IValueProvider我写的处理json值。它通过

在globa.asax中注册
ValueProviderFactories.Factories.Insert(0, new JsonValueProviderFactory());

它工作正常,但我最近需要发布一个包含HTML的模型。默认情况下,这会产生旧的

A potentially dangerous Request.Form value was detected from the client

错误讯息。看起来通常的方法是使用AllowHtml属性来装饰模型属性。问题是我的价值提供者仍在抛出错误。知道如何让我的价值提供者尊重AllowHtml属性吗?

以下是相关代码:

public class JsonValueProvider : IValueProvider, IValueDeserializer
{
    private ControllerContext context;

    public JsonValueProvider(ControllerContext controllerContext)
    {
        this.context = controllerContext;
    }

    public bool ContainsPrefix(string prefix)
    {
        return context.HttpContext.Request.Form.AllKeys.FirstOrDefault(i => i.StartsWith(prefix)) != null; //<!------- The error is thrown here
    }
    .....

2 个答案:

答案 0 :(得分:1)

如果您需要处理“有潜在危险”的数据,则无法在自定义值提供程序中使用经过验证的请求数据(例如Request.FormRequest.QueryString)。

相反,您应该使用Request.UnvalidatedHttpContext.Request.Unvalidated()HttpContext.Request.InputStream等方法或属性。

如果您在自定义IUnvalidatedValueProvider上实施ValueProvider,那么它也可以与DefaultModelBinder / AllowHtml很好地协作。

IUnvalidatedValueProvider有一个重载的GetValue方法告诉提供商是否跳过验证(最终由AllowHtml设置)。

    public interface IUnvalidatedValueProvider : IValueProvider
    {
        ValueProviderResult GetValue(string key, bool skipValidation);
    }

在您的实现中,如果skipValidation为真,那么您应该检索未经验证的请求数据。显然,在ContainsPrefix内,您无法访问经过验证的数据(例如Request.Form)。

说过从NameValueCollectionValueProvider继承已经“未经验证”的方法可能最容易。大多数内置价值提供者都是从中继承的。我已链接到MVC源代码......看看子类型是如何实现的。

答案 1 :(得分:0)

允许html仅适用于模型绑定器IIRC。您可以使用ValidationUtility中的Microsoft.Web.Infrastructure.DynamicValidationHelper获取未经验证的表单和查询字符串,但请注意,所有值都不会被验证,不仅仅是那些使用AllowHtml的值!

Func<NameValueCollection> formGetter;
Func<NameValueCollection> queryStringGetter;

ValidationUtility.GetUnvalidatedCollections(HttpContext.Current, out formGetter, out queryStringGetter);

var form = formGetter();
var queryString = queryStringGetter();