1

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

当我到达代码“return PartialView”时,我在视图中得到一个异常,我的 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() });

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

4

1 回答 1

1

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

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

另一种可能性是直接让 Delete 操作获取视图模型:

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

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

[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);
}
于 2012-05-23T17:32:45.020 回答