从编辑返回ViewModel的问题

时间:2010-07-18 10:23:50

标签: asp.net-mvc asp.net-mvc-2

我试图将相同的模型返回到编辑模型的视图。使它类似Word或具有ctrl + s功能的东西来保存模式。虽然返回到视图的模型包含一堆空值,但出于某种愚蠢的原因,这种方法很好。是因为当控制器获得视图模型或者我以错误的方式处理MVC时,事情没有正确序列化?

这是模型

public class EditInvoiceModel
{
    private readonly IEnumerable<Customer> _customers;

    public EditInvoiceModel()
    {
        CreateProduct = new Product { Invoice = Invoice };
        CreateWorkday = new Workday { Invoice = Invoice };
    }

    public EditInvoiceModel(Invoice invoice, IEnumerable<Customer> customers)
    {
        Invoice = invoice;
        _customers = customers;

        Customers = _customers.Select(x =>
                                      new SelectListItem
                                        {
                                            Selected = x.Id == Invoice.CustomerID,
                                            Text = x.Name,
                                            Value = x.Id.ToString()
                                        });

        Products = Invoice.Products;
        Workdays = Invoice.Workdays;

        CreateProduct = new Product {Invoice = Invoice};
        CreateWorkday = new Workday { Invoice = Invoice };
    }

    public IEnumerable<SelectListItem> Customers { get; set; }
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<Workday> Workdays { get; set; }
    public Product CreateProduct { get; set; }
    public Workday CreateWorkday { get; set; }
    public Invoice Invoice { get; set; }
}

这是控制器动作,它将模型返回到同一视图。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(EditInvoiceModel invoiceModel)
{
    try
    {
        _repository.UpdateInvoice(invoiceModel.Invoice);
    }
    catch (Exception ex)
    {
        Log.Error(ex);
    }

    return View(invoiceModel);
}

当返回到视图时,除Invoice之外的所有属性都为null。我不知道为什么会这样。希望有人可以提供帮助。

发生的问题(在视图中)如下:这不是因为打字错误,因为它在第一次运行视图时工作正常。这必须是模型绑定器的问题或我对模型绑定器的使用。

The ViewData item that has the key 'Invoice.CustomerID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: System.InvalidOperationException: The ViewData item that has the key 'Invoice.CustomerID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.

Source Error: 

Line 28:        <div class="editor-field">
Line 29:            <%: Html.DropDownListFor(x => x.Invoice.CustomerID, Model.Customers)%>
Line 30:            <%: Html.ValidationMessageFor(x => x.Invoice.CustomerID)%>
Line 31:        </div>

最后是显示视图模型的视图的一部分。

<%@ page language="C#" masterpagefile="~/Views/Shared/Site.Master" 
    inherits="System.Web.Mvc.ViewPage<FakturaLight.WebClient.Models.EditInvoiceModel>" %>
<asp:content id="Content2" contentplaceholderid="MainContent" runat="server">
    <%= Html.ValidationSummary() %>
    <% using (Html.BeginForm())
    { %>
    <%= Html.AntiForgeryToken() %>
    <div class="content-left">
        <%: Html.EditorFor(x => x.Invoice) %>
        <div class="editor-label">
            <%: Html.LabelFor(x => x.Invoice.CustomerID)%>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(x => x.Invoice.CustomerID, Model.Customers)%>
            <%: Html.ValidationMessageFor(x => x.Invoice.CustomerID)%>
        </div>
    <% } %>
    </div>
    <div class="content-right" id="details" style=" clear:both;">
        <div id="workdays">
            <%: Html.DisplayFor(x => x.Workdays) %>
        </div>
        <div id="products">
            <%: Html.DisplayFor(x => x.Products) %>
        </div>
    </div>
</asp:content>

2 个答案:

答案 0 :(得分:2)

达林是对的。请记住,您仍在使用断开连接的客户端。这只是HTML和HTTP的封面。模型绑定器只能绑定在HTTP POST中推送到服务器的值。该类的所有其他属性将不会收到任何分配,因此如果您希望在

中将更完整的模型推回到浏览器中
return View(invoiceModel);

您需要在控制器内的服务器端或者使用存储库的更新方法完成这些属性分配。

答案 1 :(得分:1)

仅填充Invoice属性的原因是因为在您的表单中您只有输入字段和下拉列表。模型绑定器根据请求中发送的内容填充属性。您正在发布一个仅包含Invoice值的表单。就WorkdaysProducts属性而言,您只显示它们(Html.DisplayFor)并且它们永远不会发送到服务器。此外,模型绑定器调用模型的默认构造函数,它不会初始化这些属性,因此它们在回发时为空。