ViewModel丢失了帖子数据

时间:2013-09-09 11:29:34

标签: c# asp.net asp.net-mvc entity-framework mvvm

我正在尝试创建一个复杂的ViewModel,它既包含公司的详细信息页面中的索引页面和公司便笺创建页面,也希望得到一些关于我是否正确执行此操作的指导。

我现在的问题是,当我创建一个新的公司注释时,它在我在cshtml中包含的EditorFor字段之外的对象中没有任何信息 - 它会丢失ViewModel中的所有数据。

我有一个公司模型和CompanyController,在我的详细信息操作中,我填充了与公司相关的所有注释,以及一个允许用户添加新注释的表单。

我的公司和公司注释模型非常简单:

public class Company
{
    public int CompanyID { get; set; }
    // bunch of fields related to the company

    public virtual ICollection<CompanyNote> CompanyNotes { get; set; }
}


public class CompanyNote
{
    public int CompanyNoteID { get; set; }
    public DateTime Date { get; set; }
    public string Note { get; set; }

    public Company Company { get; set; }
}

我有一个看起来像这样的ViewModel:

public class CompanyViewModel
{
    public Company Company { get; set; }

    // List of all notes associated with this company
    public IEnumerable<CompanyNote> CompanyNotes { get; set; }

    // A CompanyNote object to allow me to create a new note:
    public CompanyNote CompanyNote { get; set; }
}

这是我的详细信息操作,它填充公司记录,获取相关注释的列表,并显示带有新的空对象的创建表单:

    public ActionResult Details(int id = 0)
    {
        var viewModel = new CompanyViewModel();

        viewModel.Company = db.Companies.Find(id);

        if (viewModel.Company == null)
        {
            return HttpNotFound();
        }

        viewModel.CompanyNotes = (from a in db.CompanyNotes
                                  where a.Company.CompanyID.Equals(id)
                                  select a).OrderBy(x => x.Date);

        viewModel.CompanyNote = new CompanyNote
            {
                Date = System.DateTime.Now,
                Company = viewModel.Company
            };

        return View(viewModel);
    }

这是我在CompanyController中的CreateNote操作。 (我应该将其拆分为单独的部分视图吗?有什么好处?)

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateNote(CompanyViewModel companyViewModel)
    {
        CompanyNote companyNote = companyViewModel.CompanyNote;

        if (ModelState.IsValid)
        {

            db.CompanyNotes.Add(companyNote);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(companyViewModel);

    }

最后,这是detail.cshtml的简化版本:

@model Project.ViewModels.CompanyViewModel

// My company detail display is here, removed for sake of berevity 
@using (Html.BeginForm("CreateNote", "Company"))
{

    @Html.EditorFor(model => model.CompanyNote.Date)
    @Html.TextAreaFor(model => model.CompanyNote.Note})
    <input type="submit" value="Create" />
}

当我发布时,我的CreateNote操作有一个基本为空的companyViewModel,除了companyViewModel.CompanyNote.Date和companyViewModel.CompanyNote.Note,它们是我的表单中的字段 - ViewModel中的所有其他数据是null,所以我不确定如何将引用包含回母公司。

我是否在正确的道路上?

谢谢, 罗比

1 个答案:

答案 0 :(得分:6)

  

发布时,我的CreateNote操作有一个companyViewModel   基本上是空的,除了   companyViewModel.CompanyNote.Date和   companyViewModel.CompanyNote.Note,这是我表单中的字段 -   ViewModel中的所有其他数据都为null,所以我不知道如何   甚至包括对母公司的引用。

这是完全正常的行为。只有当您提交表单时,才会将表单中包含的信息作为输入字段发送到服务器,这是您希望模型绑定器能够检索的唯一信息。

如果您需要在HttpPost操作中使用CompanyNotes集合,只需查询您的后端,就像您在GET操作中一样。您可以通过将公司ID作为隐藏字段传递来执行此操作:

@Html.HiddenFor(model => model.Company.CompanyID)

因此,我们的想法是只在表单信息中包含用户应该以某种方式修改的输入字段。对于所有其他信息,嗯,你已经在你的后端拥有它,所以你所要做的就是点击它来获得它。

与传统的WebForms相反,ASP.NET MVC中不再存在任何ViewState概念。它更接近HTTP协议的无状态特性。