【问题标题】:@Html.ValidationMessageFor did not work as expected@Html.ValidationMessageFor 没有按预期工作
【发布时间】:2012-01-12 05:43:17
【问题描述】:

我有两个模型类,它们具有一对多的关系。

public class CycleType
{
    [Required(ErrorMessage = "Cycle is required.")]
    public int CycleTypeID { get; set; }

    [Required(ErrorMessage = "Cycle Type is required.")]
    [StringLength(20, ErrorMessage = "Cycle Type may not be longer than 20 characters")]
    public string Type { get; set; }

    public List<CycleModel> CycleModels { get; set; }
}

public class CycleModel
{
    public int CycleModelID { get; set; }

    [DisplayName("Cycle Type")]
    [Required(ErrorMessage = "Cycle is required.")]
    public int CycleTypeID { get; set; }

    [Required(ErrorMessage = "Model is required.")]
    [StringLength(20, ErrorMessage = "Model may not be longer than 20 characters")]
    public string Model { get; set; }

    public virtual CycleType CycleType { get; set; }
}

剃刀文件。

    <div class="editor-label">
        @Html.LabelFor(model => model.CycleTypeID)
    </div>
    <div class="editor-field">            
        @Html.DropDownListFor(model => model.CycleTypeID,
                                (SelectList)ViewBag.CycleType,
                                "Select Cycle Type",
                              new { id = "ddlCycleType" })
        @Html.ValidationMessageFor(model => model.CycleTypeID)
    </div>


    <div class="editor-label">
        @Html.LabelFor(model => model.Model)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Model)
        @Html.ValidationMessageFor(model => model.Model)
    </div>

1)我的第一个问题是,当我选择选择循环类型时,Validaion 函数没有触发,它只会返回错误

The ViewData item that has the key 'CycleTypeID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.

2)第二个问题是,当我选择其中一种循环类型并将值建模为 20 多个字符时,验证器可以按我的预期进行检查。但我再次收到相同的错误消息。

The ViewData item that has the key 'CycleTypeID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.

我们将不胜感激。

【问题讨论】:

    标签: c# asp.net-mvc entity-framework validation


    【解决方案1】:

    这是 Asp.net MVC 中的一个错误,因为验证不适用于 DropDownListFor 和 TextAreaFor 扩展方法。

    您可以在http://aspnet.codeplex.com/workitem/8576查看详细信息

    因此,您将需要使用 HTML.DropDownList 而不是 DropDownListFor,然后您的验证将按预期工作。

    更新

    从你的控制器,传递这个

    ViewBag.CycleTypeId = new SelectList(db.CycleTypes, "CycleTypeId", "Type"); // db is ur context instance
    

    在 View 中使用这个

    @Html.DropDownList("CycleTypeId", String.Empty)
    

    更多更新

    对于这个问题还有另一种解决方法。

    只需使用您的原始代码DropDownListFor。然后像下面一样使用类属性

     @Html.DropDownListFor(model => model.CycleTypeID,
                                (SelectList)ViewBag.CycleType,
                                "Select Cycle Type",
                              new { id = "ddlCycleType", @class = "required" })
    

    这将使验证工作,但它会显示该字段为必填项的默认消息。但 else 会按照您的预期工作。

    我想这是一个更好的解决方案,并且可以满足您的要求。

    【讨论】:

    • 感谢您提供有用的解决方案@Pankaj Upadhyay。我认为 HTML.DropDownList 无法加载像“(SelectList)ViewBag.CycleType”这样的数据集合。所以你能告诉我最好的解决方案吗?
    • 我已经用 DropDownList 的用法更新了答案。让我知道它是否不起作用。现在无法在我的系统上测试它
    • 非常感谢@Pankaj Upadhyay,这是可行的,但一个问题是它无法根据现有值动态选择其中一项。我可以使用“@Html.DropDownListFor(model => model.CycleTypeID, ...”来制作。谢谢
    • 你也可以这样做,只需传递这个ViewBag.CycleTypeId = new SelectList(db.CycleTypes, "CycleTypeId", "Type", yourModel.CycleTypeId);,它会增加一个选择参数
    • 通过使用您的代码,我可以让下拉列表按我的预期显示和自动选择,但至于验证它仍然有同样的问题。无论如何感谢您非常有用的指导@Pankaj Upadhyay My Source code
    【解决方案2】:

    我为什么要回答我自己的问题是因为我不希望任何人面临我已经发现的同样问题。

    首先,让我对@Pankaj Upadhyay 说,我非常感谢他的大力帮助。我真的非常感谢@Pankaj Upadhyay。

    我终于可以通过从@Pankaj Upadhyay 获得持续帮助来解决我的问题。

    @model CyclingClubSystem.Models.CycleModel
    
    @{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
    HtmlHelper.ClientValidationEnabled = true;
    HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
    
    }
    
    <h2>Edit</h2>
    
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>CycleModel</legend>
    
        @Html.HiddenFor(model => model.CycleModelID)
    
        <div class="editor-label">
            @Html.LabelFor(model => model.CycleTypeID)
        </div>
        <div class="editor-field">            
            @*Html.DropDownListFor(model => model.CycleTypeID,
                                    (SelectList)ViewBag.CycleType,
                                    "Select Cycle Type",
                               new { id = "ddlCycleType", @class = "required" })*@
    
            @Html.DropDownListFor(model => model.CycleTypeID,
                            (SelectList)ViewBag.CycleType,
                            "Select Cycle Type",
                          new { id = "ddlCycleType"})
    
            @*Html.DropDownList("CycleType", "Select Cycle Type")*@
            @Html.ValidationMessageFor(model => model.CycleTypeID)
        </div>
    
    
        <div class="editor-label">
            @Html.LabelFor(model => model.Model)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Model)
            @Html.ValidationMessageFor(model => model.Model)
        </div>
    
        <p>
            <input type="submit" value="Save" />
        </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
    

    控制器类

        [HttpGet]
        public ActionResult Edit(int CycleModelID)
        {
            CycleModel cycleModel = unitOfWork_CycleModel.GenericTEntityRepository.GetByID(CycleModelID);
            //ViewBag.CycleType = new SelectList(unitOfWork_cycleType.GenericTEntityRepository.Get(orderBy: CycleTypes => CycleTypes.OrderBy(CycleType => CycleType.Type)), "CycleTypeID", "Type", cycleModel.CycleTypeID);
            ViewBag.CycleType = new SelectList(unitOfWork_cycleType.GenericTEntityRepository.Get(orderBy: CycleTypes => CycleTypes.OrderBy(CycleType => CycleType.Type)), "CycleTypeID", "Type");
            return View(cycleModel);
        }
    
        [HttpPost]
        public ActionResult Edit(CycleModel  _CycleModel)
        {
            if (ModelState.IsValid)
            {
                unitOfWork_CycleModel.GenericTEntityRepository.Update(_CycleModel);
                unitOfWork_CycleModel.Save();
                return RedirectToAction("Index");
            }
            ViewBag.CycleType = new SelectList(unitOfWork_cycleType.GenericTEntityRepository.Get(orderBy: CycleTypes => CycleTypes.OrderBy(CycleType => CycleType.Type)), "CycleTypeID", "Type");
            return View(_CycleModel);
        }
    

    最后,我发现导致错误的主要原因是我忘记将该代码放在[Controller Edit Post method]

    ViewBag.CycleType = new SelectList(unitOfWork_cycleType.GenericTEntityRepository.Get(orderBy: CycleTypes => CycleTypes.OrderBy(CycleType => CycleType.Type)), "CycleTypeID", "Type");
    

    我之所以能解决我的问题,是因为我得到了@Pankaj Upadhyay 的持续指导。

    【讨论】:

    • +1 让我们知道您的解决方案是什么。这对我也有帮助。所以也谢谢你,@Frank Myat Thu!
    猜你喜欢
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    • 1970-01-01
    • 2012-07-02
    • 2011-09-07
    • 2013-03-03
    • 2015-05-18
    相关资源
    最近更新 更多