简体   繁体   English

MVC3中的AllowHTML和自定义IValueProvider

[英]AllowHTML and custom IValueProviders in MVC3

I have a custom IValueProvider that I wrote to handle json values. 我有一个编写的自定义IValueProvider,用于处理json值。 It is registered in the globa.asax via 它通过以下方式在globa.asax中注册

ValueProviderFactories.Factories.Insert(0, new JsonValueProviderFactory());

It works fine, but I just recently needed to post a model back that contains HTML. 它工作正常,但是我最近需要发布一个包含HTML的模型。 By default this spawns the old 默认情况下会生成旧的

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

Error message. 错误信息。 It looks like the way to get around that normally is to decorate the model property with an AllowHtml attribute. 看起来解决该问题的方法通常是使用AllowHtml属性装饰model属性。 The problem is my value provider is still throwing the error. 问题是我的价值提供者仍在抛出错误。 Any idea how to get my value provider to respect the AllowHtml attribute? 任何想法如何让我的价值提供者尊重AllowHtml属性?

Here is the relevant code: 以下是相关代码:

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

You cannot use validated request data (eg Request.Form , Request.QueryString ) within your custom value provider if you need to handle "potentially dangerous" data. 如果需要处理“潜在危险”数据,则不能在自定义值提供程序中使用经过验证的请求数据(例如Request.FormRequest.QueryString )。

Instead you should use methods or properties such as Request.Unvalidated , HttpContext.Request.Unvalidated() or HttpContext.Request.InputStream . 相反,您应该使用诸如Request.UnvalidatedHttpContext.Request.Unvalidated()HttpContext.Request.InputStream类的方法或属性。

If you implement IUnvalidatedValueProvider on your custom ValueProvider , then it can also work nicely with DefaultModelBinder / AllowHtml . 如果您在自定义ValueProvider上实现IUnvalidatedValueProvider ,则它也可以与DefaultModelBinder / AllowHtml一起很好地工作。

IUnvalidatedValueProvider has an overloaded GetValue method to tell the provider whether to skip validation (which is what ultimately gets set by AllowHtml ). IUnvalidatedValueProvider有一个重载的GetValue方法,用于告知提供程序是否跳过验证(这最终由AllowHtml设置)。

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

In your implementation, if skipValidation is true, then you should retrieve unvalidated request data. 在您的实现中,如果skipValidation为true,则应检索未验证的请求数据。 Obviously within your ContainsPrefix you cannot access validated data (eg Request.Form ). 显然,在ContainsPrefix您无法访问经过验证的数据(例如Request.Form )。

Having said that it may be easiest to inherit from NameValueCollectionValueProvider which is already "unvalidated" aware. 话虽如此,从已经“未验证”的NameValueCollectionValueProvider继承可能是最容易的。 Most of the built in value providers inherhit from it. 大多数内置的价值提供者都从中继承。 I have linked to the MVC source code...take a look at how the sub-types are implemented. 我已经链接到MVC源代码...看一下如何实现子类型。

Allow html works only for model binder IIRC. Allow html仅适用于模型活页夹IIRC。 You can obtain unvalidated form and query strings using ValidationUtility from Microsoft.Web.Infrastructure.DynamicValidationHelper but keep in mind that all values won't be validated, not only those with AllowHtml! 您可以使用Microsoft.Web.Infrastructure.DynamicValidationHelper ValidationUtility获取未经验证的表单和查询字符串,但请记住, 不仅使用AllowHtml的那些值都不会被验证的所有值!

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM