Asp.net mvc 5 一个POST操作的多视图模型

Asp.net mvc 5 一个POST操作的多视图模型,asp.net-mvc-5,model-binding,Asp.net Mvc 5,Model Binding,是否可以使用相同的post操作,但使用两种不同的模型,使用的模型由当前用户的角色决定?我已经将我的真实场景简化为下面的示例,但我的想法是我有两个角色:经理和区域经理。Manager可以添加一个记录(在本例中,假设它是一个用户),其中只包含名字和姓氏。另一方面,区域可以与管理器执行相同的操作,但还必须添加存储在嵌套视图模型和值类型属性上的多条其他信息,以及必需的数据注释 我希望使用这些独立的视图模型和视图,这样我就不必根据角色执行空检查或条件必需属性。此外,正如Stephen在下面指出的,第二个/

是否可以使用相同的post操作,但使用两种不同的模型,使用的模型由当前用户的角色决定?我已经将我的真实场景简化为下面的示例,但我的想法是我有两个角色:经理和区域经理。Manager可以添加一个记录(在本例中,假设它是一个用户),其中只包含名字和姓氏。另一方面,区域可以与管理器执行相同的操作,但还必须添加存储在嵌套视图模型和值类型属性上的多条其他信息,以及必需的数据注释

我希望使用这些独立的视图模型和视图,这样我就不必根据角色执行空检查或条件必需属性。此外,正如Stephen在下面指出的,第二个/不同名称的操作方法也可以工作,但只是好奇路由是否可以保持不变(Users/Add)

以下是我尝试过的:

控制器

public ActionResult Add()
{
    if (User.IsInRole("Regional"))
        return View("AddRegional", new AddRegionalViewModel());

    return View("Add", new AddViewModel());
}

[HttpPost]
public ActionResult Add(AddViewModel addViewModel)
{
    // process manager add command

    return RedirectToAction("List");
}

[HttpPost]
public ActionResult Add(AddRegionalViewModel addRegionalViewModel)
{
    // process regional add command

    return RedirectToAction("List");
}
查看模型

public class AddViewModel
{
    [Required]
    public string First { get; set; }

    [Required]
    public string Last { get; set; }
}

public class AddRegionalViewModel
{
    [Required]
    public string First { get; set; }

    [Required]
    public string Last { get; set; }

    [Required]
    public string Email { get; set; }

    // in reality there are a LOT more value types / nested view models here
}
视图

public class AddViewModel
{
    [Required]
    public string First { get; set; }

    [Required]
    public string Last { get; set; }
}

public class AddRegionalViewModel
{
    [Required]
    public string First { get; set; }

    [Required]
    public string Last { get; set; }

    [Required]
    public string Email { get; set; }

    // in reality there are a LOT more value types / nested view models here
}
Add.cshtml

@model ModelBindingHell.ViewModels.AddViewModel
@{
ViewBag.Title=“添加”;
}
添加
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
@LabelFor(model=>model.First)
@EditorFor(model=>model.First)
@Html.ValidationMessageFor(model=>model.First)
@LabelFor(model=>model.Last)
@EditorFor(model=>model.Last)
@Html.ValidationMessageFor(model=>model.Last)
}
AddRegional.cshtml

@model ModelBindingHell.ViewModels.AddRegionalViewModel
@{
ViewBag.Title=“添加”;
}
添加
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
@LabelFor(model=>model.First)
@EditorFor(model=>model.First)
@Html.ValidationMessageFor(model=>model.First)
@LabelFor(model=>model.Last)
@EditorFor(model=>model.Last)
@Html.ValidationMessageFor(model=>model.Last)
@LabelFor(model=>model.Email)
@EditorFor(model=>model.Email)
@Html.ValidationMessageFor(model=>model.Email)
}

必须创建自定义模型绑定器并编写大量代码来确定要初始化和绑定的模型。为什么不简单地使用两种post方法—
public ActionResult AddViewModel(AddViewModel AddViewModel)
public ActionResult AddRegionalViewModel(AddRegionalViewModel AddRegionalViewModel)
?我希望保留路由/Users/Add,而不必拥有/Users/AddRegional。操作名称由
HttpGet
定义,而不是由
HttpPost
定义,无需更改任何路由。GET方法保持不变。我可能只是吹毛求疵/是个完美主义者,但我的意思是帖子必须转到/Users/AddRegional而不是/Users/Add。
@model ModelBindingHell.ViewModels.AddRegionalViewModel

@{
    ViewBag.Title = "Add";
}

<h2>Add</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <div class="form-group">
            @Html.LabelFor(model => model.First)
            @Html.EditorFor(model => model.First)
            @Html.ValidationMessageFor(model => model.First)
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Last)
            @Html.EditorFor(model => model.Last)
            @Html.ValidationMessageFor(model => model.Last)
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Email)
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}