2011-08-04 83 views
1

我有一個自定義的IValueProvider,我寫處理json值。它在globa.asax中註冊通過MVC3允許HTML和自定義IValueProviders

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

回答

0

允許HTML僅適用於模型粘結劑IIRC。您可以從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(); 
1

,如果你需要處理「潛在的危險」數據,則不能使用自定義值提供商內部的驗證請求數據(例如Request.FormRequest.QueryString)。

相反,您應該使用方法或屬性,如Request.Unvalidated,HttpContext.Request.Unvalidated()HttpContext.Request.InputStream

如果您在自定義ValueProvider上執行IUnvalidatedValueProvider,那麼它也可以與DefaultModelBinder/AllowHtml很好地配合使用。

IUnvalidatedValueProvider有一個超載的GetValue方法告訴提供程序是否跳過驗證(這是最終由AllowHtml設置的內容)。

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

在您的實現,如果skipValidation是真實的,那麼你應該取回未經驗證的請求數據。顯然,在您的ContainsPrefix中,您無法訪問驗證的數據(例如Request.Form)。

話雖如此,可能最容易從NameValueCollectionValueProvider繼承,這是已知「未驗證」意識。大多數內置價值提供者都會從中繼承。我已經鏈接到MVC源代碼...看看如何實現子類型。