C# 如果ModelState.IsValid为false,则重新填充某些属性值
我有以下操作方法(部分代码):C# 如果ModelState.IsValid为false,则重新填充某些属性值,c#,asp.net-mvc,asp.net-mvc-2,asp.net-mvc-3,viewmodel,C#,Asp.net Mvc,Asp.net Mvc 2,Asp.net Mvc 3,Viewmodel,我有以下操作方法(部分代码): EditGrantApplicationViewModel如下所示(部分代码): 我的服务层中的CreateEditGrantApplicationViewModel: public EditGrantApplicationViewModel CreateEditGrantApplicationViewModel() { EditGrantApplicationViewModel editGrantApplicationViewModel = new Edi
EditGrantApplicationViewModel
如下所示(部分代码):
我的服务层中的CreateEditGrantApplicationViewModel
:
public EditGrantApplicationViewModel CreateEditGrantApplicationViewModel()
{
EditGrantApplicationViewModel editGrantApplicationViewModel = new EditGrantApplicationViewModel
{
Titles = titleRepository
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name)
};
return editGrantApplicationViewModel;
}
当我单击submit按钮时,它将进入PostActionCreate
方法。它接收类型为editGrantApplicationViewModel
的editGrantApplicationViewModel
参数。为什么Titles属性设置为null?我以为它会保留它的价值观
现在假设有一个错误,ModelState.IsValid
为false。这意味着我必须重新填充Titles
属性。给定已在editGrantApplicationViewModel
中的表单中设置的属性值,我现在如何填充Titles属性?我假设在我的服务层中需要另一个方法来填充它?最好的方法是什么
任何源代码将不胜感激
更新2011-04-11
在我看来,我有3个下拉列表。标题、银行和帐户类型。这就是为什么我的视图模型中有3个列表。我为每个人都提供了一个服务类来处理插入、更新和获取项目。例如,在我的银行服务类中,我将有Insert、Update、GetAll、GetById等与银行相关的方法。我会有类似的标题和帐户类型的服务
这是我目前在控制器类中使用它的方式:
private IGrantApplicationService grantApplicationService;
private ITitleService titleService;
private IBankService bankService;
private IAccountTypeService accountTypeService;
public GrantApplicationController(IGrantApplicationService grantApplicationService, ITitleService titleService, IBankService bankService, IAccountTypeService accountTypeService)
{
this.grantApplicationService = grantApplicationService;
this.titleService = titleService;
this.bankService = bankService;
this.accountTypeService = accountTypeService;
}
public ActionResult Create()
{
EditGrantApplicationViewModel editGrantApplicationViewModel = new EditGrantApplicationViewModel
{
// Populate the dropdown lists
Titles = titleService
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name),
Banks = bankService
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name),
AccountTypes = accountTypeService
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name)
};
return View(editGrantApplicationViewModel);
}
我们之前谈过,您说过最好为控制器提供一个服务。在我的例子中,我需要从3个不同的数据库表填充3个列表。请你提供一些代码,说明你是如何做到这一点的。如果需要更多详细信息,请告诉我。因为mvc是无状态的(在大多数情况下,您可以使用TempData和session来维护某些状态)。在初始请求和显示之后,titles属性基本上丢失
要重新生成标题
,您需要以某种方式在表单上显示这些值,以便ModelBinder
可以重新水化您的EditGrantApplicationViewModel
您很可能需要执行以下操作:
public ActionResult Create()
{
EditGrantApplicationViewModel editGrantApplicationViewModel = grantApplicationService.CreateEditGrantApplicationViewModel();
return View(editGrantApplicationViewModel);
}
<% foreach(Title title in Model.Titles { %>
<%: Html.HIddenFor(m => title) %>
<% } %>
标题)%%>
注意我的语法可能有点不正确,因为我的机器上没有visual studio
此外,我不确定ModelBinder将如何处理您的IEnumberable
,您可能必须将其更改为List
,以便ModelBinder能够正确地构建类型
有关如何绑定到标题
列表的其他信息
服务层不应该返回视图模型,它应该使用模型。因此,让您的服务层返回这些标题:
public IEnumerable<Title> GetTitles()
{
return titleRepository
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name)
};
}
在这个控制器的构造函数中,我通过构造函数注入传递一个IGrantApplicationService实例。我想我也可以传递一个ITitleService实例,但我尝试只将应用程序服务传递给相应的控制器。希望这有意义?@Brendan,我误读了这个问题,似乎
标题
用于下拉列表,而SelectedTitle是必填字段。您可能需要以某种方式保留表单上的信息,或者正如您所说的,在模型状态无效时,使用ITitleService在出现错误时重新填充标题。@Darin:前几天您提到聚合,这是什么意思?如果需要填充AccountTypes列表,现在会发生什么?我对AccountTypeService.GetAll和TitleService.GetAll都有一个服务方法。我应该在grantApplicationService中复制这两种方法吗?“对我来说,这听起来是不必要的。”布伦丹·沃格特,在不了解你的情况下很难回答这样的问题。这些账户
和标题
实体之间是否存在任何关系?是什么使您有理由选择两种服务类别:AccountTypeService
和titleservice
?我觉得你在复制你的存储库。@Darin:我已经更新了我的帖子,并添加了一个更新部分。如果我需要提供更多的代码,请告诉我。@Brendan Vogt,编写一个服务方法,返回包含3个集合属性(标题、银行和帐户类型)的模型如何。然后在服务方法返回的模型和控制器中的视图模型之间设置映射。@Darin:我遇到的另一个问题是当ModelState.IsValid为false时,我的3个列表为null,这意味着需要重新填充它。考虑到已经包含表单值的视图模型,我需要如何以及在何处重新填充这些列表(根据上面的答案)?如果你能提供一些代码,那么将不胜感激。
<% foreach(Title title in Model.Titles { %>
<%: Html.HIddenFor(m => title) %>
<% } %>
public IEnumerable<Title> GetTitles()
{
return titleRepository
.GetAll()
.Where(x => x.Active)
.OrderBy(x => x.Name)
};
}
public ActionResult Create()
{
var model = new EditGrantApplicationViewModel
{
Titles = grantApplicationService.GetTitles()
};
return View(model);
}
[HttpPost]
public ActionResult Create(EditGrantApplicationViewModel model)
{
if (!ModelState.IsValid)
{
// Reload the Titles as we are redisplaying the same view
// and they were not part of the view model that was submitted
model.Titles = grantApplicationService.GetTitles();
return View("Create", model);
}
return View("Index");
}