是否可以将封装Person的ViewModel对象传递给Create视图,但只能从POST Create操作方法接收Person对象?

LaT*_*TeX 2 asp.net-mvc asp.net-mvc-3

我有一个域模型和一个视图模型如下:

领域模型:

namespace MvcApplication1.Models
{
    public enum Sex { Male, Female };
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }

        [Required(ErrorMessage="Please select either Female or Male.")]
        public Sex? Sex { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

查看型号:

namespace MvcApplication1.ViewModels
{
    public class HomeCreateVM
    {
        public HomeCreateVM()
        {
        }
        public HomeCreateVM(Person p)
        {
            Person = p;
            SelectList = p.Sex.GetSelectList();
        }
        public Person Person { get; set; }
        public SelectList SelectList { get; set; }

    }
}
Run Code Online (Sandbox Code Playgroud)

辅助扩展方法定义如下:

namespace MvcApplication1.Models
{
    public static class Utilities
    {
        public static SelectList GetSelectList<XXX>(this XXX? obj) where XXX : struct
        {
            var values = from XXX x in Enum.GetValues(typeof(XXX))
                         select new { Text = x.ToString(), Value = x };
            return new SelectList(values, "Value", "Text", obj);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

public ActionResult Create()
{
    var p = new Person();

    return View(new HomeCreateVM(p));
}

[HttpPost]
public ActionResult Create(Person hc)// the source of problem!
{
    if (ModelState.IsValid)//always false!
    {
        TempData["status"] = hc;
        return RedirectToAction("Confirm");
    }
    else
        return View(new HomeCreateVM(hc));
}
Run Code Online (Sandbox Code Playgroud)

HomeCreateVM.cshtml:

@model MvcApplication1.ViewModels.HomeCreateVM
<div>
    Name: @Html.EditorFor(model => model.Person.Name)</div>
<div>
    Sex: @Html.DropDownListFor(model => model.Person.Sex, Model.SelectList, "--Select--")</div>
Run Code Online (Sandbox Code Playgroud)

创建视图:

@model MvcApplication1.ViewModels.HomeCreateVM

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>HomeCreateVM</legend>
        @Html.EditorForModel()
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Run Code Online (Sandbox Code Playgroud)

题:

如果POST Create操作方法接受HomeCreateVM对象作为参数,则没有问题.但是,如果我将POST Create操作方法参数更改HomeCreateVMPerson(如上面的代码所示),则ModelState.IsValid始终返回false.

问题是:"是否可以将ViewModel对象传递给Create视图,但只接受来自POST Create操作方法的DomainModel对象?"

Dar*_*rov 5

由于您的视图是对视图模型的强类型,因此表单字段将如下所示:

<input type="text" name="Person.Name" />
Run Code Online (Sandbox Code Playgroud)

如果要正确绑定,则需要指定前缀:

[HttpPost]
public ActionResult Create([Bind(Prefix = "Person")]Person hc)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @ user596314,我理解你的担忧,但不幸的是,这是不可能的.只能将常量值传递给属性. (2认同)