首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MVC ModelState IsValid报告为true时应为false

MVC ModelState IsValid报告为true时应为false
EN

Stack Overflow用户
提问于 2014-05-07 16:28:58
回答 3查看 1.5K关注 0票数 0

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

代码语言:javascript
运行
复制
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; }
    }
}

我的主计长像这样..。

代码语言:javascript
运行
复制
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视图是这样的..。

代码语言:javascript
运行
复制
@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>
}

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

如果我输入密码和确认字段的详细信息,并在Register中放置一个断点,那么即使我没有添加任何帐户或用户详细信息,ModelState.IsValid值也是真的。

如果我输入用户名,评估.

代码语言:javascript
运行
复制
Request.Form["ApplicationUser.UserName"]

给出正确的值,但是我认为应该由绑定填充的ApplicationUser.UserName没有什么!?

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

这个问题来自我提出的另一个问题(链接下面),那么我遗漏了什么呢?

Entity Framework 6 Reusing Data Annotations

请注意,我对这个特定实现的错误感兴趣,而不是因为我不想深入探讨的各种原因而被提供替代实现。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-09 09:38:56

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

坏消息是它不起作用。

好消息是,只要做一点小小的改变,它就能完美地发挥作用:

在你的控制器里,

  • 要么删除Bind POST操作参数的Register属性
  • 或者使用这个:[Bind(Include = "Account, ApplicationUser, Password, PasswordConfirmation")]

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

  • 除非您希望显式地包含或排除模型的一部分(通常是出于安全原因),否则不需要使用Bind属性。您宁愿使用所需的确切属性创建一个ViewModel (通过这种方式键入和维护较少的代码!)。
  • 您不需要提供默认构造函数来初始化嵌套对象。MVC模型绑定将自动实例化它们。实际上,我建议您不要这样做:如果您忘记在视图中包含嵌套对象的属性,则嵌套对象应该为空,而不是具有空属性的对象。会造成很多混乱!
票数 1
EN

Stack Overflow用户

发布于 2014-05-07 16:44:55

尝试在ApplicationUser本身中包含RegisterViewModel和Account属性。

代码语言:javascript
运行
复制
    public class RegisterViewModel
{
    [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; }
[Display(Name = "Account Type", Prompt = "Account Type"), Required()]
    public AccountType AccountType { get; set; }
    [Display(Name = "Organisation Name", Prompt = "Name of Organisation"), StringLength(255)]
    public string OrganisationName { get; set; }
    public RegisterViewModel()
    {

    }

    [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"), Compare("Password", ErrorMessage = "Your confirmation doesn't match...")]
    public string PasswordConfirmation { get; set; }
}
票数 0
EN

Stack Overflow用户

发布于 2014-05-07 17:15:22

您可能想要删除构造函数(因为如果它们是空的,则需要它们- ok )

代码语言:javascript
运行
复制
public RegisterViewModel()
{
    ApplicationUser = new ApplicationUser();
    Account = new Account();
}

并使ApplicationUserAccount属性成为必需的。

验证在绑定期间进行,如果这两个属性都没有绑定,那么您的模型状态将通过设计有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23523327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档