代码之家  ›  专栏  ›  技术社区  ›  morganpdx

modelstate.isvalid在应该为true时返回false

  •  2
  • morganpdx  · 技术社区  · 15 年前

    我有一个非常简单的MVC 2表单。它有两个下拉列表,用户和角色。“员工”下拉列表通过验证,而“角色”下拉列表则不通过验证,无论我选择什么。虽然我计划实现一个默认的“空”选项,但是没有默认的“空”选项,这就是为什么我需要验证才能工作。它在客户端和服务器验证中都失败。我就是不明白为什么一个人会工作,而另一个人却不工作!

    形式:

    <% using (Html.BeginForm()) {%>
    
        <%:Html.ValidationSummary(true) %>
        <%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%>
    
        <p>
            <input type="submit" value="Add New User" />
        </p>
    
        <% } %>
    
    <% Html.EndForm(); %>
    

    编辑器模板:

    <tr>
        <td>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.UserId) %>
                <%: Html.RequiredMarkFor(model => model.UserId) %>
            </div>   
        </td>    
        <td>    
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.UserId, new SelectList(ViewData["AllEmployees"] as IEnumerable, "UserId", "DisplayName", Model.UserId)) %>
            <%: Html.ValidationMessageFor(model => model.UserId>
        </div>    
        </td>       
    </tr>     
    
    <tr>
        <td>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.AccessLevel)%>
                <%: Html.RequiredMarkFor(model => model.AccessLevel)%>
            </div>   
        </td>    
        <td>    
            <div class="editor-field">
                <%: Html.DropDownListFor(model => model.AccessLevel, new SelectList(ViewData["RoleList"] as IEnumerable, Model.AccessLevel))%>
                <%: Html.ValidationMessageFor(model => model.AccessLevel)%>
            </div>    
        </td>       
    </tr> 
    

    元数据:

        [DisplayName("Employee")]
        [Required(ErrorMessage = "Please select an employee.")]
        [StringLength(8, ErrorMessage = "User Id must be less than 8 characters.")]
        [DisplayFormat(ConvertEmptyStringToNull = false,
                                HtmlEncode = true)]
        [DataType(DataType.Text)]
        public object UserId { get; set; }
    
    
        // Validation rules for Access Level
        [DisplayName("Role")]
        [Required(ErrorMessage = "Please select the role for this user.")]
        [StringLength(15, ErrorMessage = "Role must be under 15 characters.")]
        [DisplayFormat(ConvertEmptyStringToNull = false,
                                HtmlEncode = true)]
        [DataType(DataType.Text)]
        public object AccessLevel { get; set; }
    

    获取操作:

        List<String> roles = (from o in txDB.Users
                                          select o.AccessLevel).Distinct().ToList(); 
    
        var viewModel = new UserViewModel
        {
            User = new User(),
            AllEmployees = empList,
            RoleList = roles
        };
        return View(viewModel);
    

    事后处理:

        [HttpPost]
        [AuthorizeAttribute(Roles="Administrator")]
        public ActionResult Create(User user)
        {
            if(!ModelState.IsValid)
            {
                //ModelState is invalid
                return View(new User());
            }
            try
            {
               //do stuff
            }
        }
    

    所需的帮助器方法(来自 Define markup for [Required] fields in View in ASP.NET MVC 2.0 ):

        public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
        {
            if(ModelMetadata.FromLambdaExpression(expression, helper.ViewData).IsRequired)
                return "*";
            else
                return string.Empty;
        } 
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Justin Soliz    15 年前

    post方法应该如下以获得服务器端验证…

    [HttpPost]
    [AuthorizeAttribute(Roles="Administrator")]
    public ActionResult Create(User user)
    {
        if(!TryUpdateModel(user))
        {
           // Model is INVALID
           return View(user);
        }
        else
        {
            // ModelState is VALID
            // Do stuff
        }
    }
    

    这个 else 可能是多余的,这取决于你在做什么,但这应该让你去。 在您的 <% using Html.BeginForm() %> 你需要

    <% Html.EnableClientValidation(); %>
    

    您还需要参考脚本、MicrosoftAjax和MicrosoftV验证

        2
  •  1
  •   Lorenzo OnoSendai    15 年前

    首先:您有两个结束表单标记

    如果你使用

    <% using (Html.BeginForm()) {%>
    <% } %>
    

    你不需要用这个

    <% Html.EndForm(); %>
    

    关于验证问题,您只对用户属性使用编辑器,这是唯一一个由模型绑定器绑定的编辑器。

    <%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%>
    

    尝试用editor for model替换前面的代码,因为您的编辑器模板用于模型类。

    所以你的表格应该改成

    <% using (Html.BeginForm()) {%>
    
        <%:Html.ValidationSummary(true) %>
        <table>
            <%:Html.EditorForModel()%>
        </table>
        <p>
            <input type="submit" value="Add New User" />
        </p>
    <% } %>
    

    你完了!