Asp.net mvc ListBoxFor中的任何选定项都不应在asp.net mvc中显示验证错误

Asp.net mvc ListBoxFor中的任何选定项都不应在asp.net mvc中显示验证错误,asp.net-mvc,validation,selection,html.listboxfor,Asp.net Mvc,Validation,Selection,Html.listboxfor,我在局部/局部对话框中显示删除视图。最初不选择任何项目。 当用户单击ok按钮时,Delete Post操作及其参数selectedIds为空。没关系,但我如何向用户显示错误消息 当我到达代码“returnpartialview”时,我在视图中得到一个异常,即我的Model.DisplayList为空 我知道我似乎在这里混合了两个问题,但我想一个可以解决另一个 删除操作: [HttpGet] public ActionResult Delete() {

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

当我到达代码“returnpartialview”时,我在视图中得到一个异常,即我的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();
        }
[HttpGet]
公共行动结果删除()
{
var templates=_templateDataProvider.GetTemplates();
var listViewModel=新listViewModel();
listViewModel.DisplayList=模板;
返回PartialView(listViewModel);
}
[HttpPost]
公共操作结果删除(int[]selectedIds)
{
如果(selectedIds==null)
{
AddModelError(“名称”,“未选择任何内容”);
}
if(ModelState.IsValid)
{
返回Json(新的{success=true});
}
返回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"} )
}
@model ITMS.ViewModels.ListViewModel
@使用(Html.BeginForm(“删除”、“模板”))
{ 
@Html.ValidationSummary(false)
@Html.ListBoxFor(x=>x.selectedds,newselectlist(Model.DisplayList,“Id”,“Name”),new{@class=“select”})
}
当我返回此文件时:

return PartialView(new ListViewModel<Template> { DisplayList = _templateDataProvider.GetTemplates() });
返回PartialView(新的ListViewModel{DisplayList=\u templateDataProvider.GetTemplates()});

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

在您的删除帖子操作中,当出现异常并且您重新显示部分视图时,您不会向该视图传递任何模型。然而,视图需要一个DisplayList属性才能加载列表框。因此,请确保您通过的模型与您在GET操作中通过的模型相同:

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

更新:

有关在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 IEnumerable GetTemplates()
{
var templates=HttpContext.Cache[“templates”]作为IEnumerable;
如果(模板==null)
{
templates=_templateDataProvider.GetTemplates();
HttpContext.Cache[“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);
}
public ActionResult Delete()
{
var listViewModel=新listViewModel();
listViewModel.DisplayList=GetTemplates();
返回PartialView(listViewModel);
}
[HttpPost]
公共操作结果删除(ListViewModel模型)
{
if(ModelState.IsValid)
{
返回Json(新的{success=true});
}
model.DisplayList=GetTemplates();
返回局部视图(模型);
}

在删除后期操作中,当出现异常并且重新显示局部视图时,您不会将任何模型传递到此视图。然而,视图需要一个DisplayList属性才能加载列表框。因此,请确保您通过的模型与您在GET操作中通过的模型相同:

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

更新:

有关在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 IEnumerable GetTemplates()
{
var templates=HttpContext.Cache[“templates”]作为IEnumerable;
如果(模板==null)
{
templates=_templateDataProvider.GetTemplates();
HttpContext.Cache[“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);
}
public ActionResult Delete()
{
var listViewModel=新listViewModel();
listViewModel.DisplayList=GetTemplates();
返回PartialView(listViewModel);
}
[HttpPost]
公共操作结果删除(ListViewModel模型)
{
if(ModelState.IsValid)
{
返回Json(新的{success=true});
}
model.DisplayList=GetTemplates();
返回局部视图(模型);
}

对不起,达林,我忘了一些现在更新的代码。我的ViewModel有一个DisplayList属性,返回我的模型,但再次访问数据库。。。我不想那样。如果没有其他机会,我是否必须再次访问数据提供程序?可能是一些棘手的代码?@Elisa,您必须了解,在HTML中,当您有
元素时,提交表单时,只有选定的值才会发送到服务器。您必须了解的另一件事是HTTP是一种无状态协议。因此,如果不从某个地方检索此列表,则无法重新显示该视图,因为该视图依赖于它。如果担心查询数据库可能会对性能造成负面影响,可以缓存
\u templateDataProvider.GetTemplates()
调用的结果。我已经更新了我的答案,提供了一个如何实现这一点的例子。好的,谢谢Darin。但我必须这样做:ModelState.addmodeleror(“名称”,“未选择任何内容”);如果在model.selectedds为null时未设置此选项,则不会显示错误消息。我不能用ZeroSelectionRequired属性对我的模型进行注释,尽管这样做很好。最好的方法是在视图模型上使用一些数据注释,以避免控制器操作与验证逻辑混淆。这不是它的责任。如果不能,请停止在视图中使用域模型,并开始使用您专门为给定视图的需求定义的视图模型。如果你不想听我的建议,那么,你可以继续在你的控制器中添加验证逻辑。我只是使用模板来填充viewmodel。你会换一种方式吗?不,数据注释是很好的建议;-)对不起,达林,我忘了更新一些代码了。我的V