MVC數據驗證Membership使用常見錯誤


     在做注冊界面的時候,出現了兩個錯誤,讓我糾結得想死,幸好最后都解決了,只能怪自己對MVC的Membership了解得不深,尤其是有關Web.Config的配置問題。

問題一:Membership.IsValid返回為false

     這個問題一開始讓我很無語,因為在之前也有做過注冊界面,但並不會出現這樣的問題,代碼如下:

[HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if(ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
                if (createStatus == MembershipCreateStatus.Success)
                {

                    FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
                    return RedirectToAction("LogOn", "Account");
                }
                else
                {
                    ModelState.AddModelError("test", ErrorCodeToString(createStatus));
                    return RedirectToAction("Index", "Home");
                }
            }
            

            // If we got this far, something failed, redisplay form

            return View(model);
        }

     這是RegisterModel的代碼:

 public class RegisterModel
    {

       [Required(ErrorMessage = "姓名不能為空!")]
        [Display(Name = "學生名")]
        [StringLength(160)]
        public string UserName { get; set; }

       [Required(ErrorMessage = "密碼不能為空!")]
        [StringLength(160, ErrorMessage = "{0}至少是{2}位數以上!", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "密碼")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "確認密碼")]
        [Compare("Password", ErrorMessage = "密碼不一致,請重新輸入!")]
        public string ConfirmPassword { get; set; }

       [Required(ErrorMessage = "電話不能為空!")]
        [StringLength(160)]
        [DisplayName("電話")]
        public String Phone { get; set; }

       [Required(ErrorMessage = "QQ不能為空!")]
        [StringLength(160)]
        [DisplayName("QQ")]
        public String QQ { get; set; }

       [Required(ErrorMessage = "郵箱不能為空!")]
        [StringLength(160)]
        [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[A-Za-z]{2,4}", ErrorMessage = "Email is not valid")]
        [DataType(DataType.EmailAddress)]
        [DisplayName("電子郵箱")]
        public String Email { get; set; }

       [Required(ErrorMessage = "學號不能為空!")]
        [DisplayName("學號")]
        [StringLength(160)]
        public String Number { get; set; }
    }

     然后是我的視圖代碼:

 <div class="editor-label">
                <%: Html.LabelFor(model => model.UserName)%>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.UserName)%>
                <%: Html.ValidationMessageFor(model => model.UserName)%>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.Number)%>
            </div>
            <div class="editor-field">
               <%: Html.TextBoxFor(model => model.Number)%>
               <%: Html.ValidationMessageFor(model => model.Number)%>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.Password)%>
            </div>
            <div class="editor-field">
               <%: Html.PasswordFor(model => model.Password)%>
               <%: Html.ValidationMessageFor(model => model.Password)%>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.ConfirmPassword)%> 
            </div>
            <div class="editor-field">
                <%: Html.PasswordFor(model => model.ConfirmPassword) %>
                <%: Html.ValidationMessageFor(model => model.ConfirmPassword) %>
            </div>

      如果運行就會出現這樣的錯誤。原因很簡單,就是Model所有字段都有Reguired,也就是要求視圖驗證,但視圖中能賦值的只是其中幾個值,也就是說,能夠驗證的值只有視圖頁顯示的那幾個,其他要求驗證的屬性字段就會返回錯誤信息給ModelState,因為ModelState綁定的是整個Model。
      如果只是想要讓用戶輸入幾個值而已,可以去掉其他屬性字段的Required,否則就要老老實實的在視圖頁中提供其他屬性字段的輸入。

問題二:MembershipCreateStatus的值並不等於Success

      這個問題涉及到Membership的配置。我們想要使用Membership,必須在我們的Web.config中添加下面的配置代碼:

<system.web>
    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="DefaultRoleProvider">
      <providers>
        <add connectionStringName="DefaultConnection" applicationName="/" name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </providers>
    </roleManager>
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
</system.web/>

      如果運行還有錯誤,說明沒有引入System.Web.Providers這個包,需要使用Nuget命令:

Install-Package System.Web.Providers

      導入后,問題就解決了。
      在解決上面的問題中,我也大概摸索出一些調試方法。

      想要獲得ModelState某個屬性字段的錯誤信息,可以使用TempData:

TempData["UserName"] = ModelState["UserName"];

      然后在視圖中添加:

    <p>
        <%= TempData["UserName"] == null ? "" : TempData["UserName"].ToString() %>
    </p>

      ModelState就是錯誤信息的字典值,只要提供相應的鍵值就能獲得對應的錯誤信息。TempData有個好處就是它不需要傳遞給視圖就可以直接使用。
      同樣也可以獲得MembershipCreateStatus的錯誤信息:

TempData["test"] = ErrorCodeToString(createStatus);

      我們也可以將錯誤信息添加進ModelState中:

  ModelState.AddModelError("test", ErrorCodeToString(createStatus));

       調試代碼的第一步就是獲得錯誤信息,連錯誤信息都得不到,又怎能解決問題呢?這時就要想方設法獲得錯誤信息,然后再進行改正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM