将不同类型的ViewModel返回给Controller

时间:2012-03-15 09:14:14

标签: c# asp.net-mvc mvvm partial-views asp.net-mvc-4

我有一个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一个)。这似乎有效。现在这是一个干净的方式吗?如果有人想出更好的主意,请告诉我!

1 个答案:

答案 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,但我可能不会亲自打扰。

相关问题