I show the Delete View in a partial/dialog. Initially no items are selected. When the user clicks the ok button the Delete Post action and its parameter selectedIds is NULL. Thats ok, but how can I show the user an error message?
When I reach the code "return PartialView" then I get an Exception in the View, that my Model.DisplayList ist empty.
I know I seem to mix 2 problems here but I guess one could solve the other...
Delete Actions:
[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();
}
Delete View:
@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"} )
}
When I return this:
return PartialView(new ListViewModel<Template> { DisplayList = _templateDataProvider.GetTemplates() });
then it works, but I do not want to access the database again for this.
In your Delete POST action when there is an exception and you redisplay the partial view you are not passing any model to this view. And yet your view needs a DisplayList property in order to load the list box. So make sure you are passing a model tha same way you did in your GET action:
Another possibility is to directly have the Delete action take the view model:
Now as far as the validation is concerned you could decorate your
SelectedIds
property on the view model with for example the Required attribute:UPDATE:
A performance concern has been expressed in the comments section about accessing the database to load the list again in the POST action. To avoid this performance hit the values could be cached and reused.
Like this:
and then: