asp mvc,无法理解复合模型

时间:2014-10-30 17:03:06

标签: c# asp.net asp.net-mvc

我正在尝试学习如何使用多个模型创建一个基本的ASP MVC向导应用程序,并且正在玩一些示例项目。因为我是初学者,所以我从这开始:http://www.binaryintellect.net/articles/9a5fe277-6e7e-43e5-8408-a28ff5be7801.aspx

我有3个强类型的部分视图,BasicDetails,AddressDetails和ContactDetails,用户使用JQuery在Index页面上滚动浏览div。我希望每个局部视图都有自己的模型/数据库表,在滚动浏览所有部分视图后,我想在一个评论页面上显示所有这些视图,然后将它们全部写入各自的数据库表。我以为我会通过使用复合模型来实现这一点,但到目前为止还不成功。

我的模型类,全部在一个文件Customer.cs中:

public class Customer
{
    public BasicDetails BasicDetails { get; set; }
    public AddressDetails AddressDetails { get; set; }
    public ContactDetails ContactDetails { get; set; }
}

public class BasicDetails
{
    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
}

public class AddressDetails
{
    public string Address { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

public class ContactDetails
{
    public string ContactName { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
}

HomeController.cs:

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(Customer obj)
    {
        if (ModelState.IsValid)
        {
            return View("Review", obj);
        }
        return View();
    }

    public ActionResult Review(Customer obj)
    {
        return View();
    }

的Index.aspx:

<% using (Html.BeginForm("Index", "Home", FormMethod.Post)){%>

<div id="divBasic" class="index">
<% Html.RenderPartial("BasicDetails"); %>
</div>

<div id="divAddress" class="index">
<% Html.RenderPartial("AddressDetails"); %>
</div>

<div id="divContact" class="index">
<% Html.RenderPartial("ContactDetails"); %>
</div>

<%}%>

用于滚动的JQuery:

$("div.index").hide();
$("div.index:first").show();
$("div.index :button[value='Next'],:button[value='Previous']").click(function () {
    var parentDiv = $(this).parent();
    $("div.index").hide();
    if ($(this).val() == "Previous") {
        var prevDiv = parentDiv.prev();
        prevDiv.show();
    }
    if ($(this).val() == "Next") {
        var nextDiv = parentDiv.next();
        nextDiv.show();
    }
});

Review.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication2.Models.Customer>" %>
...

<fieldset>
    <legend>Fields</legend>

    <div class="display-label">CustomerID</div>
    <div class="display-field"><%: Model.BasicDetails.CustomerID %></div>

    <div class="display-label">CompanyName</div>
    <div class="display-field"><%: Model.BasicDetails.CompanyName %></div>

    <div class="display-label">Address</div>
    <div class="display-field"><%: Model.AddressDetails.Address %></div>

    <div class="display-label">City</div>
    <div class="display-field"><%: Model.AddressDetails.City %></div>

    <div class="display-label">Country</div>
    <div class="display-field"><%: Model.AddressDetails.Country %></div>

    <div class="display-label">PostalCode</div>
    <div class="display-field"><%: Model.AddressDetails.PostalCode %></div>

    <div class="display-label">ContactName</div>
    <div class="display-field"><%: Model.ContactDetails.ContactName %></div>

    <div class="display-label">Phone</div>
    <div class="display-field"><%: Model.ContactDetails.Phone %></div>

    <div class="display-label">Fax</div>
    <div class="display-field"><%: Model.ContactDetails.Fax %></div>

</fieldset>

BasicDetails:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication2.Models.BasicDetails>" %>

<h1>Step 1 : Basic Details</h1>
<%= Html.LabelFor(m=>m.CustomerID) %>
<%= Html.TextBoxFor(m=>m.CustomerID) %>
<%= Html.ValidationMessageFor(m=>m.CustomerID) %><br />
<%= Html.LabelFor(m=>m.CompanyName) %>
<%= Html.TextBoxFor(m=>m.CompanyName) %>
<%= Html.ValidationMessageFor(m=>m.CompanyName) %><br />

<input type="button" name="nextBtn" value='Next' />

AddressDetails:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication2.Models.AddressDetails>" %>

<h1>Step 2 : Address Details</h1>
<%= Html.LabelFor(m=>m.Address) %><br />
<%= Html.TextBoxFor(m=>m.Address) %>
<%= Html.ValidationMessageFor(m=>m.Address) %> 
<br />
<%= Html.LabelFor(m=>m.City) %><br />
<%= Html.TextBoxFor(m=>m.City) %>
<%= Html.ValidationMessageFor(m=>m.City) %> 
<br />
<%= Html.LabelFor(m=>m.Country) %><br />
<%= Html.TextBoxFor(m=>m.Country) %>
<%= Html.ValidationMessageFor(m=>m.Country) %> 
<br />
<%= Html.LabelFor(m=>m.PostalCode) %><br />
<%= Html.TextBoxFor(m=>m.PostalCode) %>
<%= Html.ValidationMessageFor(m=>m.PostalCode) %><br /> 
<br />
<input type="button" name="prevBtn" value='Previous' />
<input type="button" name="nextBtn" value='Next' />

ContactDetails:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication2.Models.ContactDetails>" %>

<h1>Step 3 : Contact Details</h1>
<%= Html.LabelFor(m=>m.ContactName) %><br />
<%= Html.TextBoxFor(m=>m.ContactName) %>
<%= Html.ValidationMessageFor(m=>m.ContactName) %> 
<br />
<%= Html.LabelFor(m=>m.Phone) %><br />
<%= Html.TextBoxFor(m=>m.Phone) %>
<%= Html.ValidationMessageFor(m=>m.Phone) %> 
<br />
<%= Html.LabelFor(m=>m.Fax) %><br />
<%= Html.TextBoxFor(m=>m.Fax) %>
<%= Html.ValidationMessageFor(m=>m.Fax) %> <br />
<br />
<input type="button" name="prevBtn" value='Previous' />
<input type="submit" name="nextBtn" value='Finish' />

所以我有几个问题:

问题1: 如果我这样做,我在提交时收到一个错误,上面写着“System.NullReferenceException:对象引用未设置为对象的实例”,用于Review中的“Model.BasicalDetails.CustomerID”。我是否需要为每个客户成员分配BasicDetails,AddressDetails和ContactDetails,如果是,在哪里?

问题2: 如果我将我的客户模型更改为:

public class Customer
{
    public string SalesRep { get; set; }
    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
    public string ContactName { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
}

public class BasicDetails
{
    public string SalesRep { get; set; }
    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
}

public class AddressDetails
{
    public string Address { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

public class ContactDetails
{
    public string ContactName { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
}

...而不是将BasicDetails,AddressDetails和ContactDetails作为成员与其他三个类具有所有相同的字段,并且在Review中将Model.AddressDetails.City更改为仅仅Model.City,并离开其他一切都一样,它的工作原理。为什么会这样?在部分视图中输入信息时,它如何知道还更新客户?

感谢您提供任何建议。

1 个答案:

答案 0 :(得分:1)

首先,在复合模型中初始化属性:

public class Customer
{
    public Customer()
    {
        BasicDetails = new BasicDetails();
        AddressDetails = new AddressDetails();
        ContactDetails = new ContactDetails();
    }

    public BasicDetails BasicDetails { get; set; }
    public AddressDetails AddressDetails { get; set; }
    public ContactDetails ContactDetails { get; set; }
}

接下来,如果在渲染局部视图时未指定模型,则传入主视图的模型,因此您需要指定部分应使用的实际模型,即:

<% Html.RenderPartial("BasicDetails", Model.BasicDetails); %>

对你的其他部分做同样的事,你应该没事。