MVC ModelState IsValid报告true,何时应为false [英] MVC ModelState IsValid reports true when should be false

查看:90
本文介绍了MVC ModelState IsValid报告true,何时应为false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下3个类(现在包括所有代码)...

I have the following 3 classes (all code now included)...

using System.ComponentModel.DataAnnotations;

namespace MyWebApp.Models
{
    public class ApplicationUser
    {
        [Display(Prompt = "Your Name", Name = "Contact Name"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Please enter a valid contact")]
        public string ContactName { get; set; }
        [Display(Name = "Username", Prompt = "Login As"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Your username must be at least 3 characters")]
        public string UserName { get; set; }
    }

    public class Account
    {
        [Display(Name = "Account Type", Prompt = "Account Type"), Required()]
        public int AccountType { get; set; }
        [Display(Name = "Organisation Name", Prompt = "Name of Organisation"), StringLength(255)]
        public string OrganisationName { get; set; }
    }

    public class RegisterViewModel
    {
        public ApplicationUser ApplicationUser { get; set; }
        public Account Account { get; set; }

        public RegisterViewModel()
        {
            ApplicationUser = new ApplicationUser();
            Account = new Account();
        }

        [Display(Name = "Password", Prompt = "Password"), Required(), DataType(DataType.Password), StringLength(255, MinimumLength = 5, ErrorMessage = "The password must be at least 7 characters")]
        public string Password { get; set; }

        [Display(Name = "Confirm Password", Prompt = "Confirm Password"), DataType(DataType.Password), Compare("Password", ErrorMessage = "Your confirmation doesn't match...")]
        public string PasswordConfirmation { get; set; }
    }
}

我的控制器看起来像这样...

My Controller looks like this...

using System.Web.Mvc;
using MyWebApp.Models;

namespace MyWebApp.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        // GET: /Account/
        [AllowAnonymous]
        public ActionResult Register()
        {
            RegisterViewModel mdl = new RegisterViewModel();
            return View(mdl);
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult Register([Bind(Include = "Account.AccountType, ApplicationUser.ContactName, ApplicationUser.UserName, Password, Account.OrganisationName, Account.OrganisationRegistrationNumber, Account.AddressLine1, Account.AddressLine2, Account.AddressLine3, Account.City, Account.County, Account.Postcode, ApplicationUser.Email, ApplicationUser.PhoneNumber, PasswordConfirmation")]RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = model.ApplicationUser;
                var associatedAccount = model.Account;

                var u1 = Request.Form["ApplicationUser.UserName"];
                if (u1 == user.UserName)
                {
                    // we got it
                    ViewBag.Message = "We got it";
                }
                else
                {
                    // no we didn't
                    ViewBag.Message = "We failed!";
                }
                return View(model);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
    }
}

我的Register.cshtml视图外观像这样...

my Register.cshtml view looks like this...

@using MyWebApp.Models
@model MyWebApp.Models.RegisterViewModel

@{
    ViewBag.Title = "Register User";
}

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

    <div class="form-horizontal">
        <h4>New Account</h4>
        <hr />
        <p>@ViewBag.Message</p>
        @Html.ValidationSummary(true)
        <div class="col-md-6">
            <div class="form-group">
                @Html.LabelFor(model => model.ApplicationUser.ContactName, new { @class = "control-label col-md-5" })
                <div class="col-md-7">
                    @Html.EditorFor(model => model.ApplicationUser.ContactName, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.ApplicationUser.ContactName)
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.ApplicationUser.UserName, new { @class = "control-label col-md-5" })
                <div class="col-md-7">
                    @Html.EditorFor(model => model.ApplicationUser.UserName, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.ApplicationUser.UserName)
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-5" })
                <div class="col-md-7">
                    @Html.EditorFor(model => model.Password, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.Password)
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.PasswordConfirmation, new { @class = "control-label col-md-5" })
                <div class="col-md-7">
                    @Html.EditorFor(model => model.PasswordConfirmation, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.PasswordConfirmation)
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <div class="org-info">
                <div class="form-group">
                    @Html.LabelFor(model => model.Account.OrganisationName, new { @class = "control-label col-md-5" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Account.OrganisationName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.Account.OrganisationName)
                    </div>
                </div>
            </div>
            <hr />
            <div class="form-group">
                <div class="col-md-8"></div>
                <div class="col-md-4">
                    <input type="submit" value="Sign Up" class="btn btn-default form-control" />
                </div>
            </div>
        </div>
    </div>
}

我的问题是,当用户单击注册而不在视图中输入任何详细信息时,只有密码和密码确认字段显示为问题,而Account或ApplicationUser属性均未显示问题。

My issue is that when a user clicks Register without entering any details on the view, only the password and password confirmation fields show as having issues, none of the Account or ApplicationUser Properties show issue.

如果我输入密码和确认字段的详细信息并输入注册方法中的一个断点,即使我没有添加任何帐户或用户详细信息,ModelState.IsValid值也为true。

If I enter details for the password and confirmation fields and put a break point in the Register method, the ModelState.IsValid value is true even though I haven't added any Account or User details.

如果我输入,请说一个用户名,正在评估...

If I do enter say a username, evaluating...

Request.Form["ApplicationUser.UserName"]

给出正确的值,但是我认为应该由Bind填充的ApplicationUser.UserName没有任何内容!?

gives the correct value and yet ApplicationUser.UserName which I would think should be populated by the Bind has nothing!?

我怀疑这是我的Bind声明,但是我尝试了UserName,ApplicationUser.UserName和ApplicationUser_UserName,但似乎都存在相同的问题。

I suspect it's my Bind declaration but I have tried UserName, ApplicationUser.UserName and ApplicationUser_UserName but all seem to have the same problem.

此问题来自另一个我提出了一个问题(下面的链接),所以我想念什么?

This question has come about from another question I raised (link below), so what am I missing?

实体框架6重用数据注释

请注意,我对这个特定实现中的问题感兴趣

Please note that I'm interested in what's wrong in this particular implementation rather than being offered alternate implementations for various reasons I don't really want to go into.

推荐答案

我已经下载了您的代码,将其包含在一个新的空MVC4应用程序中。

I've downloaded your code and included it in a new empty MVC4 application.

坏消息是它不起作用。

好消息是,只需稍作更改,它便可以完美运行:

The good news is that it can work perfectly with just an small change:

在您的控制器中,


  • 要么删除 Register POST操作参数
  • $ b $的 Bind 属性b
  • 或使用以下命令: [Bind(Include = Account,ApplicationUser,Password,PasswordConfirmation)]

  • either remove the Bind attribute of the Register POST action parameter
  • or use this one: [Bind(Include = "Account, ApplicationUser, Password, PasswordConfirmation")]

以及关于代码的一对注释​​:

And a pair of comments about your code:


  • 除非您要明确包含或排除模型的一部分(通常出于安全考虑)原因),您无需使用 Bind 属性。您宁愿使用所需的确切属性来创建ViewModel(那样,您就可以键入并维护更少的代码!)。

  • 您无需提供默认的构造函数即可进行初始化嵌套的对象。 MVC模型绑定程序将自动实例化它们。实际上,我建议您不要这样做:如果忘记在视图中包括嵌套对象的属性,则该嵌套对象应该为null,而不是具有null属性的对象。会造成很多混乱!

  • unless you want to explicitly include or exclude part of your model (usually for security reasons) you don't need to use the Bind attribute. You'd rather create a ViewModel with the exact properties that you need (in that way you type and maintain less code!).
  • you don't need to supply a default constructor to initialize the nested objects. The MVC model binder will instantiate them automatically. In fact, I recommend you not to do it: if you forget to include the properties of the nested object in your view, that nested object should be null, and not an object with null properties. That can create a lot of confussion!!

这篇关于MVC ModelState IsValid报告true,何时应为false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆