简体   繁体   English

无法修复ASP.NET MVC验证

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

I've been trying to fix the validation on my form for a while now, but can't get it to work properly. 我一直在尝试在表单上修复验证,但无法使其正常工作。 The validation works fine, unless I enter a valid email address. 除非我输入有效的电子邮件地址,否则验证工作正常。 If I do, then it just skips all other validation for some reason. 如果我这样做,则出于某种原因它只会跳过所有其他验证。

Also, would appreciate advice about if I'm doing it right with the split of everything in the controller. 另外,如果我对控制器中所有内容的分割是否正确,请多多指教。 Should there be 2 actions (1 for GET to just load the empty form and 1 for POST when the user submits it)? 是否应该有2个动作(1个用于GET以便仅加载空表单,1个用于POST当用户提交表单时)? Am I doing something wrong there? 我在那里做错了吗?

EDIT: Correction: If I enter a valid email address, the form submits fine and ignores the other validation. 编辑:更正:如果我输入有效的电子邮件地址,该表格会很好地提交,并且会忽略其他验证。 If I don't have a valid email address, the validation checks everything. 如果我没有有效的电子邮件地址,验证将检查所有内容。

Here's my model class: 这是我的模型课:

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

Here is my controller: 这是我的控制器:

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

And here is my form: 这是我的表格:

    @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>
    }

And of course bottom of the body includes: 当然,主体的底部包括:

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

Use Modelstate.IsValid . 使用Modelstate.IsValid It tells you if any model errors have been added to ModelState. 它告诉您是否有任何模型错误已添加到ModelState。

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

    //your code
}

In order to check if posted model is valid you need to check ModelState.IsValid in the post action (see in the example below). 为了检查发布的模型是否有效,您需要在发布操作中检查ModelState.IsValid(请参见下面的示例)。

Also, would appreciate advice about if I'm doing it right with the split of everything in the controller. 另外,如果我对控制器中所有内容的分割是否正确,请多多指教。 Should there be 2 actions (1 for GET to just load the empty form and 1 for POST when the user submits it)? 是否应该有2个动作(1个用于GET以便仅加载空表单,1个用于POST当用户提交表单时)? Am I doing something wrong there? 我在那里做错了吗?

The approach is right but the way you do it is not. 该方法是正确的,但您做不到的方法。

Assuming that you have a Register.cshtml view (not a partial view): Since a view has a model, you should always provide it. 假设您具有Register.cshtml视图(而非局部视图):由于视图具有模型,因此应始终提供该模型。 So your get method should look like this: 因此,您的get方法应如下所示:

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

For the post method there are 2 approaches: 对于post方法,有2种方法:

  1. POST-REDIRECT-GET pattern (PRG) - a little bit more complex(but in my opinion it is more correct way of doing this). POST-REDIRECT-GET模式(PRG)-稍微复杂一点(但我认为这是更正确的方法)。 Post method instead of returning a view should return a redirect result both in case of error and in case of success. 在发生错误和成功的情况下,Post方法而不是返回视图都应返回重定向结果。 For handling invalid model state you can use some approaches that are described here 为了处理无效的模型状态,您可以使用此处描述的一些方法

  2. Your way 你的方式

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

First of all, your structure seems correct, to split the actions to have a differentiated Get and Post actions is correct and a good way to do it. 首先,您的结构看起来是正确的,将操作拆分为具有区别的“获取”和“发布”操作是正确的,并且是实现此操作的一种好方法。

I am not able to test, but I think the issue is that you don't handle the validation correctly in your controller; 我无法测试,但我认为问题在于您未在控制器中正确处理验证; you should check the the ModelState to be valid. 您应该检查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);
    }

This way if there is an error in the Model (based on the Rules you put with DataAnnotations). 如果模型中存在错误,则采用这种方式(基于您使用DataAnnotations放置的规则)。

Also I am not sure that your DataAnnotations Attributes are the correct one: Some differ from those that are used in this article: 另外,我不确定您的DataAnnotations属性是否正确:有些不同于本文中使用的属性:

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM