我有一个ASP.NET MVC4应用程序,在某个点上有一个页面( Index ),用户可以从DropDownList中选择一个项目。提交后,控制器将根据列表中的所选项目将不同的PartialView名称返回到另一个视图(创建)。每个partial都有自己的ViewModel,当PartialView从Controller发送到 Create -View时,它会被正确呈现。为了实现这一点,我创建了一个通用的ViewModel和其他几个从这个通用ViewModel派生的视图模型。 创建 -view将一般ViewModel作为模型,将在 Create -view中呈现的Partials将匹配的派生类型作为Model。
但问题是,当我在PartialView上提交表单时,我必须在Controller中检索正确的ViewModel。接受一般ViewModel作为参数将无法工作,因为我无法将其向下转换为正确的ViewModel。这是我的一些示例代码:
的ViewModels:
public class PropertyViewModel
{
public string ViewName { get; set; }
public String Name { get; set; }
public String Description { get; set; }
}
public class IntegerViewModel : PropertyViewModel
{
public int MinValue { get; set; }
public int MaxValue { get; set; }
}
public class TextViewModel : PropertyViewModel
{
public int MaxLength { get; set; }
}
控制器:
public ActionResult Create(String partialName)
{
var model = GetViewModelFromName(partialName);
return View(model);
}
[HttpPost]
public ActionResult Create(???)
{
//What to do here and what kind of parameter should I expect?
}
有没有'干净'的方法吗?有谁知道如何实现这个目标?
更新
我有一个似乎有效的解决方案。在PartialView中,我设置了actionName和表单的controllerName,如下所示:
@using (Html.BeginForm("CreateIntegerProperty", "Property")) {
//Formstuff...
}
@using (Html.BeginForm("CreateTextProperty", "Property")) {
//Formstuff...
}
在我的控制器中,我有所有不同的动作(每个PartialViews一个)。这似乎有效。现在这是一个干净的方式吗?如果有人想出更好的主意,请告诉我!
答案 0 :(得分:2)
如果你的解决方案有效,那就去吧。对我来说似乎很好。如果您对每个操作都有相同的URL感到困扰,那么唯一的问题就出现了。
如果您愿意,可以通过将Action和Controller名称添加到基本ViewModel来增强它,如下所示:
public class PropertyViewModel
{
public string ViewName { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public String Controller { get; set; }
public String Action { get; set; }
}
然后这样做:
@using (Html.BeginForm(Model.Action, Model.Controller)) {
//Formstuff...
}
如果这意味着您现在可以对表单使用相同的View
(或部分视图或其他内容),那么这将是值得做的。
如果你想为每个动作想要相同的网址,那么一种方法是覆盖OnModelBinding
,但我可能不会亲自打扰。