簡體   English   中英

無法修復ASP.NET MVC驗證

[英]Can't Fix ASP.NET MVC Validation

我一直在嘗試在表單上修復驗證,但無法使其正常工作。 除非我輸入有效的電子郵件地址,否則驗證工作正常。 如果我這樣做,則出於某種原因它只會跳過所有其他驗證。

另外,如果我對控制器中所有內容的分割是否正確,請多多指教。 是否應該有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)

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

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

    //your code
}

為了檢查發布的模型是否有效,您需要在發布操作中檢查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方法而不是返回視圖都應返回重定向結果。 為了處理無效的模型狀態,您可以使用此處描述的一些方法

  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"); } 

首先,您的結構看起來是正確的,將操作拆分為具有區別的“獲取”和“發布”操作是正確的,並且是實現此操作的一種好方法。

我無法測試,但我認為問題在於您未在控制器中正確處理驗證; 您應該檢查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/zh-cn/aspnet/core/tutorials/first-mvc-app/validation

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM