ASP.NET MVC的视图模型在提交时为空

7

我有一个复杂的视图模型,我正在将其传递给创建视图。当我在页面上输入数据并提交后,模型为空。子对象中的字段和“test”字段都是空的。为什么会这样?

public class ContactIncident
{
    [Key]
    public int Id { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    [Display(Name = "Incident Date")]
    [DataType(DataType.Date)]
    public DateTime? IncidentDateTime { get; set; }

    [Display(Name = "Follow Up Date")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    [DataType(DataType.Date)]
    public DateTime? FollowUpDate { get; set; }
}

public class IncidentManager
{    
    public ContactIncident Incident { get; set; }
    public string Test { get; set; }
}


public ActionResult Create(int? id)
{
    IncidentManager im = new IncidentManager();
    ContactIncident ci = new ContactIncident();
    ci.IncidentDateTime = DateTime.Now;
    ci.FollowUpDate = DateTime.Now.AddDays(14);
    im.Incident = ci;
    return View(im);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(IncidentManager im)
{
    if (ModelState.IsValid)
    {
        ContactIncident ci = new ContactIncident();
        ci.IncidentDateTime = incident.Incident.IncidentDateTime;
        ci.Description = im.Incident.Description;
        return RedirectToAction("Index");
    }
    return View(incident);
}

视图:

@model MyApp.Web.ViewModels.IncidentManager
@{
    ViewBag.Title = "Edit Incident";
}
<h4>@ViewBag.Title</h4>    
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal well">
        @Html.ValidationSummary(true)      
        @Html.EditorFor(model=>model.Test)   
        <div class="row">
            <div class="col-md-2">
                @Html.LabelFor(model => model.Incident.IncidentDateTime)
            </div>
            <div class="col-md-2">
                @Html.DisplayFor(model => model.Incident.IncidentDateTime)
            </div>
        </div>
        <div class="row">
            <div class="col-md-2">
                @Html.LabelFor(model => model.Incident.Description)
            </div>
            <div class="col-md-10">
                @Html.EditorFor(model => model.Incident.Description, new { htmlAttributes = new { @class = "form-control", rows = "5" }, })
            </div>
                   <div class="col-md-2">
                @Html.LabelFor(model => model.Incident.FollowUpDate)
            </div>
            <div class="col-md-2">
                @Html.EditorFor(model => model.Incident.FollowUpDate, new { htmlAttributes = new { @class = "form-control"}, })
            </div>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Save" class="btn btn-default" />
        </div>
    </div>
}

2
你能展示一下你的cshtml文件吗?我想看看你是如何定义表单元素的。 - Bassam Mehanni
1
我认为 ci.IncidentDateTime = incident.Incident.IncidentDateTime; 是一个打字错误,实际上应该是 ci.IncidentDateTime = im.Incident.IncidentDateTime;。同样的,return View(incident); 也应该是 return View(im);(你的代码无法编译)。除此之外,你的代码工作正常,尽管 IncidentDateTime 将是 null,因为你没有为它创建表单输入。 - user3559349
1个回答

8
问题在于,如果您使用不同的参数名称,则DefaultModelBinder将无法正确映射嵌套模型。您必须使用与ViewModel名称相同的参数名称
public ActionResult Create(IncidentManager incidentManager)

作为一般实践,始终使用模型名称作为参数名称以避免映射问题。

更新:

DefaultModelBinder使用“基于约定”的映射。

IncidentManager.Incident = incidentManager.Incident (will map)
IncidentManager.Incident = im.Incident    //won't map because 'im' != 'incidentManager'

1
请详细说明一下。您是在与 IncidentManager 类交流吗?如果是,为什么? - John S
1
我进行了修改并且它已经可以运行。我之前遇到过这个问题好几次,总是绕过去做,但现在这样会更好。 - John S
3
“你必须使用与 ViewModel 名称相同的参数名称”是错误的!参数名称可以是任何有效的名称,只要它不是与模型中的属性之一相同的名称。 - user3559349
1
@StephenMuecke - 自此帖子以来,他们可能已经更新了模型绑定逻辑。既然这是被接受的答案,那么这一定解决了发帖者的问题。无论你的观点如何。 - Yorro
1
不,它没有改变(在这方面,对于MVC-3、MVC-4和MVC-5来说都是一样的)。 - user3559349
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接