当处理MVC中的表单帖子时,我发现自己编写了一些有些繁琐的代码,以确保发布的下拉列表选择是针对列表中的有效项目。这个想法是,没有什么能阻止包含最初未在下拉列表中显示的选定ID的帖子。用户可以将他们自己的项目插入下拉列表(或以其他方式发布他们想要的任何内容),或者表单可能已经在窗口中停留了很长时间,以至于现在可用的项目已经更改。无论它为什么会发生,事实是,您无法控制发布的数据。以下是我如何处理的一些示例代码:
VM:
public class MyViewModel
{
public string SelectedItemID {get; set;}
public List<Items> AvailableItems {get; set;}
}
查看:
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.SelectedItemID,
Model.AvailableItems.Select(i => new SelectListItem()
{
Value = i.ID.ToString(),
Text = i.Name,
Selected = (Model.SelectedItemID == i.ID)
}), "Select One")
}
控制器:
[HttpPost]
public ActionResult Index(MyViewModel myVM)
{
bool isValid = true;
try
{
//Reload the available items
myVM.AvailableItems = Repository.GetAvailableItems();
if(!ModelState.IsValid)
{
isValid = false;
}
else
{
//Make sure the SelectedItemID is a real item
if(!myVM.AvailableItems.Any(i => i.ID == myVM.SelectedItemID))
{
isValid = false;
myVM.SelectedItemID = null;
ModelState.AddModelError("SelectedItemID", "Required"); //This gets interesting when the selected ID belongs to a nested VM in a collection.
}
}
if(isValid)
{
//Finally I can process the form
}
}
catch(Exception)
{
ModelState.AddModelError("", "Unable to process your submission. Please try again.");
}
//return an ActionResult
}
如果SelectedItemID属于集合内的嵌套视图模型,则在ModelState中设置错误会特别难看。这似乎应该是标准类型的验证,但相对于在asp.net MVC中执行其他验证的简易性而言,这非常丑陋且乏味。是否有更简单的方法来处理这个问题?
答案 0 :(得分:0)
我认为你应该看看Tim Coker在这里的回应:
Is it possible to update ModelState.IsValid manually?
基本上,您希望使viewmodel类继承自IValidatableObject,然后将一些验证逻辑放入其中。如果您的标准未得到满足,则后续验证调用将失败(即SelectedItemId不在新的数据库查询中)