ListBoxFor中没有选定的项应该在asp.net mvc中显示验证错误

时间:2012-05-23 17:29:22

标签: asp.net-mvc validation selection html.listboxfor

我在部分/对话框中显示删除视图。最初没有选择任何项目。 当用户单击“确定”按钮时,“删除发布”操作及其参数selectedIds为NULL。好的,但是如何向用户显示错误消息?

当我到达代码“return PartialView”时,我在View中得到一个Exception,我的Model.DisplayList是空的。

我知道我似乎在这里混淆了两个问题,但我猜一个人可以解决另一个......

删除操作:

[HttpGet]
        public ActionResult Delete()
        {
            var templates = _templateDataProvider.GetTemplates();
            var listViewModel = new ListViewModel<Template>();
            listViewModel.DisplayList = templates;
            return PartialView(listViewModel);
        }

        [HttpPost]
        public ActionResult Delete(int[] selectedIds)
        {
            if (selectedIds == null)
            {
                ModelState.AddModelError("Name", "Nothing selected");
            }

            if (ModelState.IsValid)
            {
                return Json(new { success = true });
            }

            return PartialView();
        }

删除视图:

@model ITMS.ViewModels.ListViewModel<ITMS.Models.Template>
<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("Delete", "Template"))
{ 
    @Html.ValidationSummary(false)      
    @Html.ListBoxFor(x => x.SelectedIds, new SelectList(Model.DisplayList, "Id", "Name"),new { @class = "select"} )
}

当我退回时:

return PartialView(new ListViewModel<Template> { DisplayList = _templateDataProvider.GetTemplates() });

然后它可以工作,但我不想再为此访问数据库。

1 个答案:

答案 0 :(得分:1)

在出现异常并且重新显示局部视图时,在删除POST操作中,您没有将任何模型传递给此视图。然而,您的视图需要DisplayList属性才能加载列表框。因此,请确保您以与GET操作相同的方式传递模型:

var templates = _templateDataProvider.GetTemplates();
var listViewModel = new ListViewModel<Template>();
listViewModel.DisplayList = templates;
return PartialView(listViewModel);

另一种可能性是直接让删除操作采用视图模型:

[HttpPost]
public ActionResult Delete(ListViewModel<Template> model)
{
    if (ModelState.IsValid)
    {
        return Json(new { success = true });
    }

    // Make sure you rebind the DisplayList property
    model.DisplayList = _templateDataProvider.GetTemplates();
    return PartialView(model);
}

现在就验证而言,您可以使用例如Required属性修饰视图模型上的SelectedIds属性:

[Required]
public IEnumerable<Template> SelectedIds { get; set; }

更新:

在评论部分中已经表达了关于访问数据库以在POST操作中再次加载列表的性能问题。为了避免这种性能损失,可以缓存和重用这些值。

像这样:

public IEnumerable<Template> GetTemplates()
{
    var templates = HttpContext.Cache["templates"] as IEnumerable<Template>;
    if (templates == null)
    {
        templates = _templateDataProvider.GetTemplates();
        HttpContext.Cache["templates"] = templates;
    }
    return templates;
}

然后:

public ActionResult Delete()
{
    var listViewModel = new ListViewModel<Template>();
    listViewModel.DisplayList = GetTemplates();
    return PartialView(listViewModel);
}

[HttpPost]
public ActionResult Delete(ListViewModel<Template> model)
{
    if (ModelState.IsValid)
    {
        return Json(new { success = true });
    }

    model.DisplayList = GetTemplates();
    return PartialView(model);
}