【问题标题】:Validation on DropDownListFor problem (ModelState.IsValid always false)DropDownListFor 问题的验证(ModelState.IsValid 始终为 false)
【发布时间】:2011-04-13 19:35:04
【问题描述】:

我在 DropDownListFor 上使用验证时遇到问题...

我的模特:

public class User 
{
    ...
    public virtual int Id{ get; set; }
    [Required(ErrorMessage = "Required.")]
    public virtual Role Role { get; set; }
}

public class Role 
{        
    public virtual int Id{ get; set; }
    [Required(ErrorMessage = "Required.")]
    public virtual string Name { get; set; }
}

我的控制器:

    public ActionResult Edit()
    {
        ViewBag.Roles = new SelectList(new Repository<Role>().GetAll(), "Id", "Name");

        return View();
    }

我的编辑视图(强类型)

   @model User
   ...
   @Html.LabelFor(model => model.Role)
   @Html.DropDownListFor(model => model.Role.Id, ViewBag.Roles as SelectList, "-- Select --",new { @class = "form radius" })
   @Html.ValidationMessageFor(model => model.Role)

一切正常,当我尝试保存用户模型时问题被触发:

    [HttpPost]
    public ActionResult Edit(User user)
    {
        if (ModelState.IsValid)
        ...
    }

ModelState.IsValid 始终为 false...查看 ModelState 内部,错误在 Role.Name 键中...错误是:Name field is required

有没有办法解决这个问题?怎么样?

谢谢

【问题讨论】:

    标签: validation asp.net-mvc-3


    【解决方案1】:

    您已在 Name 属性上放置了一个必需的属性,但它从未发送到服务器,因此您的模型无效(仅发布了 Id)。所以你应该把它放在Id 属性上:

    public class Role 
    {        
        [Required(ErrorMessage = "Required.")]
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }
    

    您还应该将这个Id 属性设为Nullable,因为您为下拉列表定义了一个空值,如果用户没有选择任何值,它将崩溃。所以你的模型应该是这样的:

    public class Role 
    {        
        [Required(ErrorMessage = "Required.")]
        public virtual int? Id { get; set; }
        public virtual string Name { get; set; }
    }
    

    您还可以从 User 类的 Role 属性中删除 Required 属性。不需要。

    最后的建议,可能也是最重要的一条:用你的视图模型上的一个属性替换这个ViewBag ugliness,这样帮助器看起来像这样:

    @Html.DropDownListFor(
        model => model.Role.Id, 
        Model.Roles, 
        "-- Select --",
        new { @class = "form radius" }
    )
    

    【讨论】:

    • 问题是我有一个角色 UI,用户可以在其中注册新角色...并且需要 Name 上的必需项,除了我的 Id 属性属于 EntityBase 类...
    • @Paul 然后确保您的表单上有一个Name 输入字段并且发送了一个值,否则您的模型将永远无效。如果没有名称字段,则使用视图模型。事实上,不,您应该始终使用视图模型 :-)
    • 是的,这就是我想要做的,但我不知道怎么做:(
    • @Paul,您定义了一个仅包含给定视图所需属性的类,并且您的控制器操作将此视图模型作为参数。它将包含相应的验证属性。因此,如果此视图中没有 Name,您的 EditUserViewModel 中将没有 Name 属性。事实上,您正试图在不同的情况下重用您的模型,这让您很头疼。不要将这个User 模型放入所有操作中,因为验证规则会有所不同。定义视图模型,然后在视图模型和模型之间进行映射。
    • 很长一段时间以来,我一直无法理解模型之间的区别(例如,您在“控制器下方”使用的内容一直到数据库和 ViewModel。Darin 描述得最好:如果它不在 View 中它不应该在 View 的 Model 变量的类中。
    【解决方案2】:

    我也遇到过这种错误。

    也许您的问题的解决方案是在您的 Edit.cshtml 视图中放置这样的代码:

    @Html.HiddenFor(model => model.Id)

    【讨论】:

      【解决方案3】:

      型号

      public class Role 
      {        
          [Required(ErrorMessage = "Id Required.")]
          public virtual int Id { get; set; }
          [Required(ErrorMessage = "Name Required.")]
          public virtual string Name { get; set; }
      }
      

      查看

      @Html.DropDownListFor(m => m.Role.Id, (SelectList)ViewBag.gRoles, "-- Select --")
      @Html.ValidationMessageFor(m => m.Role.Id)
      

      控制器

      [HttpPost]
      [ValidateAntiForgeryToken]
      public ActionResult Creedit(User x)
      {
          x.Role = db.RoseSet.Find(x.Role.Id);
          if (x.Role != null)
          {
              ModelState["Role.Name"].Errors.Clear();
      
          }
      
          if (ModelState.IsValid)
          {
            // proceed
          }
          else
          {
            // return validation error
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-01
        • 2018-10-07
        • 2022-07-21
        • 1970-01-01
        • 2019-09-11
        相关资源
        最近更新 更多