天天看點

mvc基礎系列說談(6)——資料驗證(上)

(一)基本驗證

通過htmlhelper來驗證。

以Customer為例:

在建立(Create)視圖中,如果應用了驗證:

<%= Html.ValidationSummary("Create was unsuccessful. 

Please correct the errors and try again.") %>

    <% using (Html.BeginForm("Create", "Customer", 

       FormMethod.Post, new {enctype = "application/x-www-form-urlencoded" }))

   {%>

    <fieldset>

    <legend>Fields</legend>

    <p>

      <label for="FirstName">FirstName:</label>

      <%= Html.TextBox("FirstName") %>

      <%= Html.ValidationMessage("FirstName", "*") %>

    </p>

      <label for="LastName">LastName:</label>

      <%= Html.TextBox("LastName") %>

      <%= Html.ValidationMessage("LastName", "*") %>

      <input type="submit" value="Create" />

    </fieldset>

<% } %>

以名字(FirstName)與姓氏(LastName)來說,

<%= Html.TextBox("FirstName") %>

<%= Html.ValidationMessage("FirstName", "*") %>

通過helper的ValidationMessage來驗證FirstName文本框,然後如果驗證不通過,則文本框後加顯示*符号(就像平常注冊的一樣,必填項有些類似,當然做為字元串,可以改的)

然後在控制器的動作中,通過ModelState來驗證:

if (customer.FirstName == string.Empty)

{

    ModelState.AddModelError("FirstName", "名字不能為空!");

}

if (customer.LastName == string.Empty)

    ModelState.AddModelError("LastName", "姓氏不能為空!");

if (Convert.ToInt32(customer.FirstName) > 10)

    ModelState.AddModelError("FirstName", "名字不能大于!");

if (!ModelState.IsValid)

    return View();

這個ModelState是Controller的一個屬性:

public ModelStateDictionary ModelState

    get

    {

        return base.ViewData.ModelState;

    }

從這裡可以看出:控制器的ModelState屬性其實是ViewData的一個屬性。看來ViewData用處真大(Model部分其實也是放到了這個屬性中)。而ViewData是一個ViewDataDictionary 類型的。然後,這個類型的一個屬性:就是ModelState,這個屬性就是一個ModelStateDictionary 類型。它的方法很多,其中之一就是:

public void AddModelError(string key, string errorMessage)

    this.GetModelStateForKey(key).Errors.Add(errorMessage);

就是程式中用到的。其中GetModelStateForKey方法是得到一個ModelState類執行個體,ModelState類定義為:

public class ModelState

    // Fields

    private ModelErrorCollection _errors;

    [CompilerGenerated]

    private ValueProviderResult <Value>k__BackingField; 

    // Methods

    public ModelState(); 

    // Properties

    public ModelErrorCollection Errors { get; }

    public ValueProviderResult Value { [CompilerGenerated] get; [CompilerGenerated] set; }

當調用ModelState.AddModelError方法時:

·調用Controller的ModelState屬性

·調用Controller的ModelState屬性就是調用Controller的ViewData屬性的ModelState

·其實調用的就是ViewDataDictionary類的ModelState屬性

·當添加錯誤資訊時,就是調用ModelState屬性的AddModelError方法,

其中ModelState屬性是ModelStateDictionary類型

·當添加錯誤資訊時,就是向ModelState類執行個體中Errors屬性中添加kv對,也就是對ModelErrorCollection

添加錯誤資訊

然後再提一下IsValid屬性:

public bool IsValid

        return this.Values.All<ModelState>(delegate (ModelState modelState) 

        {

            return (modelState.Errors.Count == 0);

        });

這下就一目了然了:驗證資料後,會在ModelState

當Post送出過來的資料被驗證時,當有錯誤資訊時,被添加到ModelState類執行個體的ModelErrorCollection集合屬性中,然後控制器的ModelState屬性的Values屬性(ModelState類型),如果這個ModelState中的錯誤的資訊的數目為0時,則驗證通過,否則驗證不通過。

當驗證不通過時,不會執行建立動作中的IsValid之後的邏輯,而直接傳回視圖。這時,錯誤資訊已經添加到了控制器的ViewData中。然後,在視圖中顯示。

(二)通過實作IDataErrorInfo接口

IDataErrorInfo 接口定義:

public interface IDataErrorInfo

    string Error { get; }

    string this[string columnName] { get; }

如果要實作這個接口:

·在partial類型的類實體中繼承這個接口

·實作這個接口

·對資料進行驗證時,隻要實作[On屬性Changing]即可

例如:我是直接在LinqToSql檔案的Customer類中添加的接口(因為做了一個partial類,在别的地方寫也是可以的,它表示可分寫。)

public partial class Customer : INotifyPropertyChanging, 

                                INotifyPropertyChanged, IDataErrorInfo

實作部分為:

#region IDataErrorInfo 成員

private Dictionary<string, string> _errors = new Dictionary<string, string>(); 

partial void OnFirstNameChanging(string value)

    if (value.Trim().Length == 0)

        _errors.Add("FirstName", "名字不能為空.");

    else

        if (Convert.ToInt32(value.Trim()) > 10)

           _errors.Add("FirstName", "不能大于10");

partial void OnLastNameChanging(string value)

        _errors.Add("LastName", "姓氏不能為空.");   

public string Error

        return string.Empty;

public string this[string columnName]

       if (_errors.ContainsKey(columnName))

            return _errors[columnName];

       return string.Empty;

#endregion

這部分相當容易實作,一個Error屬性,一個實作索引,添加對驗證字段(文本框)的方法。即可,然後在控制器中:

//if (customer.FirstName == string.Empty)

//{

//    ModelState.AddModelError("FirstName", "名字不能為空!");

//}

這些部分就可以不要了。

部落格園大道至簡

<a href="http://www.cnblogs.com/jams742003/" target="_blank">http://www.cnblogs.com/jams742003/</a>

轉載請注明:部落格園