我有一个View来创建一个对象,这个对象可以有三种类型。所以我决定创建一个带有3个选项卡的选项卡面板,每个选项卡代表一个此对象的类型。
用户必须选择他将填充数据的标签,然后按提交。顺便说一句,每个标签都有一个FORM和一个提交。
到目前为止,1个View和3个表单。
我想知道是否有更好的方法来做到这一点。使用渲染动作,局部视图,只有一个视图模型,很多视图模型。
我的最后一次尝试是使用具有所有可能性的大视图模型和用于确定类型/选项卡面板的隐藏字段。当用户提交时,我只获得此对象类型将使用的字段并保存在数据库中。
Pro:只有一个视图模型,只有一个控制器。如果模型状态有错误,我可以毫不费力地在视图中显示结果(使用html validationmessagefor)。剃刀绑定和剃刀助手。 缺点:我不能在所有字段中使用数据注释,因为某些字段需要一个类型而不是另一个字段,并且它们具有相同的名称。如果更改了一个表单的字段,则具有相同名称的另一个选项卡/表单中的字段也将更改。该对象有一些必须根据类型选择更改的属性,但另一个属性是相同的。这些显示了他的价值的变化,并显示了每个表格的验证信息。 这是最好的方法
任何形式的帮助都会非常棒。 感谢
修改
我正在考虑创建一个viewmodel作为3个视图模型的容器。因此字段将被分开,对于每个“提交”,我将使用三个视图模型中的一个。
这是一个很好的方法吗?
答案 0 :(得分:3)
无论你是使用子动作,部分还是只是在一个视图中抛出所有内容都没有区别。特别是,一旦您发布,无论您是否使用子操作或部分首先呈现表单,都是无关紧要的。你不能发布到儿童行动。
首先,我建议您创建一个包装器视图模型来保存所有特定于表单的视图模型,并在页面上为每个表单使用一个视图模型,并且不要忘记实例化这些视图模型(主视图模型的构造函数是个好地方):
public class MainViewModel
{
public MainViewModel()
{
Form1 = new Form1ViewModel();
Form2 = new Form2ViewModel();
...
}
public Form1ViewModel Form1 { get; set; }
public Form2ViewModel Form2 { get; set; }
...
}
接下来,由于您实际上为每个表单使用单独的提交按钮,因此您可以更轻松地使用它,因为您可以为每个提交按钮指定一个名称,并使用它来确定用户提交的表单:
<button type="submit" name="_form1Submit">Submit</button>
然后,在你的行动中:
if (Request.Unvalidated["_form1Submit"] != null)
{
// form 1 was submitted
}
最后,默认情况下,模型绑定器将验证您的整个视图模型(MainViewModel
),并且您将在其他未填写的表单上的任何字段上获得错误。但是,您可以使用TryUpdateModel
在您想要的任何部分重新运行模型验证:
if (Request.Unvalidated["_form1Submit"] != null)
{
TryUpdateModel(model.Form1);
if (ModelState.IsValid)
{
// do something interesting
}
}