2012-06-15 30 views
3

我正在尋找一種方式來從我的自定義驗證代碼返回以下信息:如何從自定義驗證代碼向控制器或視圖返回附加(即不僅僅是field =>錯誤消息)驗證信息?

public enum ValidationErrorTypeFlags 
{ 
    Error_Input = 1 << 0,    // a "field specific" error which is checked both clientside and serverside 
    Error_Input_ServerSide = 1 << 1, // a "field specific" error which can only be checked serverside 
    Error_General = 1 << 2    // serverside general error 
} 

裏面的驗證碼(可以是IValidatableObject或ValidationAttribute),當我發現一個錯誤,我想是能夠將以上錯誤類型之一與ValidationResult相關聯。

然後,我想能夠遍歷Controller或View中的驗證錯誤並區分這些錯誤類型。

我目前使用MVC 3(樂意升級到4)。

NB:

  • ModelState中不保留ValidationResults AFAIK - 你只能在ViewData.ModelState.Values.Items [X] .Errors訪問錯誤 - 這些已經轉換爲System.Web.Mvc。 ModelError
  • 似乎MVC驗證只允許您在驗證完成後訪問[key,'錯誤消息']類型驗證結果。

我使用的是目前這個破解是裝飾錯誤消息的自定義驗證代碼中:

var field = new[] { validationContext.DisplayName }; 
return new ValidationResult("+Invalid format - use yyyy-mm-dd", field); 

,然後尋找與+,開始錯誤信息 - ,*控制器。

+0

我已經在MVC3中統計了很多不同的地方,其中ModelValidationError被轉換爲ModelState,所以我不認爲有一個簡單的方法來做到這一點。 – IanBru

回答

3

從自定義驗證代碼(不知道如何從內置的代碼完成),您可以通過從基礎繼承創建自定義ValidationResult類並從您的自定義驗證屬性返回來實現。

public class CustomValidationResult: ValidationResult 
{ 
    // additional properties 
} 

然後從控制器,你可以施放和檢查驗證結果是你的自定義類型,並採取相應的行動。

更新:

以上想法不工作,因爲ValidationResult類是在DataAnnotations組裝和它們轉換成ModelValidationResult而這一切,我們可以在MVC訪問。

它似乎從數據註釋驗證傳遞額外的信息到MVC看起來不是很容易!

我正在瀏覽源代碼,發現它是ValidatableObjectAdapter,它將IEnumerable<ValidationResult>轉換爲IEnumerable<ModelValidationResult>。我沒有看到擴展此類的好處,但我們可以通過執行ModelValidator並複製Validate代碼輕鬆地創建自定義ValidatableObjectAdapter

我們必須創建一個自定義ModelValidationResult和自定義ValidationResult(這是該自定義ValidationResult我們將b從驗證返回)和ConvertResults方法,我們可以把我們的轉換代碼,需要的附加信息服務。

public class CustomValidatableObjectAdapter : ModelValidator 
{ 
    public CustomValidatableObjectAdapter(ModelMetadata metadata, ControllerContext context) 
     : base(metadata, context) 
    { 
    } 

    public override IEnumerable<ModelValidationResult> Validate(object container) 
    { 
     object model = Metadata.Model; 
     if (model == null) 
     { 
     return Enumerable.Empty<ModelValidationResult>(); 
     } 

     IValidatableObject validatable = model as IValidatableObject; 
     if (validatable == null) 
     { 
     throw new Exception("model is of not type validatable"); 
     } 

     ValidationContext validationContext = new ValidationContext(validatable, null, null); 

     return ConvertResults(validatable.Validate(validationContext)); 
    } 

    private IEnumerable<ModelValidationResult> ConvertResults(IEnumerable<ValidationResult> results) 
    { 
     foreach (ValidationResult result in results) 
     { 
     // iterate the ValidationResult enumeration and cast each into CustomValidationResult 
     // and conver them into enumeration of CustomModelValidationResult. 
     } 
    } 
} 

最後,我們要告訴在Application_Start事件Global.asax.cs中的DataAnnotationsModelValidatorProvider使用這個我們。

DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory((metadata, context) => new CustomValidatableObjectAdapter(metadata, context)); 

所以,你必須創建一個自定義ValidationResult,定製ModelValidationResult和一個自定義ValidatableObjectAdapter

我還沒有測試過這個,但我希望這會起作用。我可能會建議一個比這更好更簡單的解決方案。

+0

感謝您的回覆。我以前嘗試過,但無法找到可以在控制器中訪問的變量,我可以投出該變量。你能指出我正確的方向嗎?我試過ModelState,但如前所述,這隻有ModelError的不ValidationResults。 – Ilan

+0

只需在您的博客http://www.prideparrot.com/blog/archive/2012/4/model_validation_in_asp_net_mvc上閱讀帖子。 IClientValidatable是一個很好的提示 - 它有一些類似的目標,我試圖。 – Ilan

+0

@Illan不知何故,我找到了一種方法..我會在一分鐘內更新答案。 – VJAI

相關問題