@ Html.ValidationMessageFor没有按预期工作

时间:2012-01-12 05:43:17

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

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

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; }
}

Razor文件。

    <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>'.

我们将不胜感激。

2 个答案:

答案 0 :(得分:5)

这是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" })

这将使验证工作,但它将显示默认消息该字段是必需的。但是否则会像你期望的那样奏效。

我想这是一个更好的解决方案,也是满足您需求的好方法。

答案 1 :(得分:3)

为什么我回答我自己的问题是我不希望任何人像我已经找到的那样面对同样的问题。

首先,让我对@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方法]

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

为什么我可以解决我的问题,我得到@Pankaj Upadhyay的连续指导。