2017-07-06 85 views
0

我一直在嘗試修復窗體上的驗證一段時間,但無法使其正常工作。驗證工作正常,除非我輸入有效的電子郵件地址。如果我這樣做,那麼由於某種原因,它會跳過所有其他驗證。無法修復ASP.NET MVC驗證

此外,將不勝感激關於如果我正在與控制器中的所有東西的分裂正確的做法。如果有2個動作(1個用於GET,只需加載空表單,1個用於POST時用戶提交)?我在那裏做錯了什麼?

編輯:更正:如果我輸入一個有效的電子郵件地址,表單提交罰款,並忽略其他驗證。如果我沒有有效的電子郵件地址,驗證會檢查一切。

這裏是我的模型類:

public class User 
{ 
    public int ID { get; set; } 

    [DisplayName("Name")] 
    [Required(ErrorMessage = "Name is required")] 
    public string Name { get; set; } 

    [DisplayName("Email")] 
    [DataType(DataType.EmailAddress)] 
    [Required(ErrorMessage = "Email is required")] 
    [RegularExpression(
     @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + 
      @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", 
     ErrorMessage = "Invalid email")] 
    public string Email { get; set; } 

    [DisplayName("Password")] 
    [DataType(DataType.Password)] 
    [Required(ErrorMessage = "Password required")] 
    [MinLength(6, ErrorMessage = "Min 6 characters")] 
    public string Password { get; set; } 
} 

這裏是我的控制器:

public ActionResult Register() 
    { 
     ViewBag.LoggedIn = false; 

     return View(); 
    } 

    [HttpPost] 
    public ActionResult Register(User user) 
    { 
     ViewBag.LoggedIn = false; 

     user.Password = PasswordHash.CreateHash(user.Password); 

     using (var context = new FoundationContext()) 
     { 
      // if user exists 
      if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 

      context.Users.Add(user); 
      context.SaveChanges(); 
     } 

     return View("~/Views/Home.Index.cshtml"); 
    } 

這裏是我的表格:

身體
@using (Html.BeginForm()) 
    { 
     @Html.AntiForgeryToken() 

     <div class="form-horizontal"> 
      @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
      <div class="form-group"> 
       @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       <div class="col-md-10 text-center"> 
        <input type="submit" value="Register" class="btn btn-primary" /> 
       </div> 
      </div> 
     </div> 
    } 

當然底部包括:

@Scripts.Render("~/bundles/jquery") 
@Scripts.Render("~/bundles/jqueryval") 
@Scripts.Render("~/bundles/bootstrap") 
@RenderSection("scripts", required: false) 
+0

你不檢查,看看是否模型在HttpPost行動是有效的'ModelState.IsValid '。 – Scrobi

回答

1

爲了檢查發佈模型是否有效,您需要檢查發佈操作中的ModelState.IsValid(請參閱下面的示例)。

此外,將不勝感激關於如果我正在與控制器中的所有東西的分割正確的建議。如果有2個動作(1個用於GET,只需加載空表單,1個用於POST時用戶提交)?我在那裏做錯了什麼?

該方法是正確的,但你做的方式不是。

假設您有一個Register.cshtml視圖(不是局部視圖): 由於視圖有一個模型,您應該始終提供它。所以,你的GET方法應該是這樣的:

public ActionResult Register() 
{ 
    ViewBag.LoggedIn = false; 
    var model = new User(); 
    return View(model); 
} 

對於POST方法有2種方法:

  1. POST-REDIRECT-GET模式(PRG) - 更復雜一點(但在我認爲這是更正確的做法)。 Post方法而不是返回視圖應該在錯誤和成功的情況下都返回重定向結果。對於處理無效的模型狀態可以使用所描述here

  2. 你的方式一些方法

    [HttpPost] 
    public ActionResult Register(User user) 
    { 
        ViewBag.LoggedIn = false; 
        if(!this.ModelState.IsValid) 
        { 
        return View(user); 
        //this will render a view with preserved invalid model state so all the values with the corresponding error messages will be shown. 
        } 
    
        user.Password = PasswordHash.CreateHash(user.Password); 
    
        using (var context = new FoundationContext()) 
        { 
         // if user exists 
         if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 
    
         context.Users.Add(user); 
         context.SaveChanges(); 
        } 
    
        return RedirectToAction("Index", "Home"); 
    } 
    
2

使用Modelstate.IsValid。它會告訴您是否有任何模型錯誤已添加到ModelState中。

public ActionResult Register(User user) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(); 
    } 

    //your code 
} 
0

首先,您的結構看起來是正確的,要將動作分成不同的Get和Post動作是正確的,並且是一種很好的方法。

我無法測試,但我認爲問題在於您不能在控制器中正確處理驗證;你應該檢查ModelState是否有效。

[HttpPost] 
    public ActionResult Register(User user) 
    { 
     if (ModelState.IsValid) 
     { 
      ViewBag.LoggedIn = false; 

      user.Password = PasswordHash.CreateHash(user.Password); 

      using (var context = new FoundationContext()) 
      { 
       // if user exists 
       if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 

       context.Users.Add(user); 
       context.SaveChanges(); 
      } 

      return View("~/Views/Home.Index.cshtml"); 
     } 
     return View(user); 
    } 

這樣,如果模型中有錯誤(根據您使用DataAnnotations的規則)。

而且我不知道你的DataAnnotations屬性是正確的: 一些從那些在這篇文章中使用的不同:

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation

希望這有助於。