MVC强类型部分视图模型绑定

时间:2011-09-08 18:35:26

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

我是MVC的新手,所以这是我的问题。我有一个父视图和一个在其中呈现的局部视图。 作为模型,我将IEnumerable传递给父视图。我通过列表迭代,并为每个项目渲染具有列表项作为模型的局部视图。在局部视图中,我有一个表单,在提交时触发一个子动作,该动作接受列表的类型作为参数。我的问题是param总是带着它的值为null。

这些是我的域名实体。

public class Contact
    {
        [Key]
        public int IdContacts { get; set; }
        public int UserId { get; set; }
        public int CreatedByUserId { get; set; }
        public int UpdatedByUserId { get; set; }
        public int AddressId { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public long HomePhone { get; set; }
        public long? WorkPhone { get; set; }
        public bool IsRelated { get; set; }
        public bool IsEmergency { get; set; }
        public bool IsDeceased { get; set; }
        public string Relationship { get; set; }
        public DateTime EntryDate { get; set; }
        public DateTime? ChangeDate { get; set; }
    }

 public class Address
    {
        [Key]
        public int IdAddresses { get; set; }
        public int CountryId { get; set; }
        public int StateId { get; set; }
        public int CreatedByUserId { get; set; }
        public int UpdatedByUserId { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public long PostalCode { get; set; }
        public string OfficeOrApt { get; set; }
        public int AreaGroup { get; set; }
        public int? SuperUserId { get; set; }
        public DateTime EntryDate { get; set; }
        public DateTime? ChangeDate { get; set; }
    }

这是我的视图模型

public class ContactModel
    {
        public Contact Contact { get; set; }
        public Address Address { get; set; }
        public bool IsEditMode { get; set; }
    }

这是我的父视图

@model IEnumerable<Cricket.WebUI.Models.ContactModel>
@{
    ViewBag.Title = "Contacts";
}
<h2 align="center">
    Contacts</h2>
<div class="iggr_container">
    <div class="iggr_clear">
    </div>
    @foreach (var contact in Model)
    {
        ViewDataDictionary dictionary = new ViewDataDictionary();
        string guid = (Guid.NewGuid()).ToString();
        dictionary.Add("prefix", guid);

        @Html.Hidden("Contact.Index", guid)
        @Html.Hidden("Address.Index", guid)
        @Html.Partial("ContactSummary", contact, dictionary)
        <hr style="width: 385px;" align="left" /> 
    }
</div>

这是我的部分观点

@model Models.ContactModel
<div class="iggr_clear">
</div>
@if (!Model.IsEditMode)
{
    var prefixContact = "Contact[" + ViewData["prefix"] + "].";
    var prefixAddress = "Address[" + ViewData["prefix"] + "].";

    using (Html.BeginForm("Edit", "Contacts", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        TempData["ContactModelObject"] = Model;
    <div>
        <b>
            @Html.Hidden(prefixContact + "FirstName", Model.Contact.FirstName);
            @Html.Hidden(prefixContact + "LastName", new { name = "Contact" + ViewData["prefixContact"] + ".LastName" })
            @Html.LabelFor(m => m.Contact.FirstName, Model.Contact.FirstName)
            &nbsp;
            @Html.LabelFor(m => m.Contact.LastName, Model.Contact.LastName)
        </b>
        <div>
            <span>Home Phone:</span>
            @Html.Hidden(prefixContact + "HomePhone", Model.Contact.HomePhone)
            @Html.LabelFor(m => m.Contact.HomePhone, Model.Contact.HomePhone.ToString())</div>
        <div>
            <span>Work Phone:</span>
            @Html.Hidden(prefixContact + "WorkPhone", Model.Contact.WorkPhone)
            <span>
                @if (Model.Contact.WorkPhone == null)
                {
                    @:N/A
            }
                else
                {
                    @Html.LabelFor(m => m.Contact.WorkPhone, Model.Contact.WorkPhone.ToString())
                }
            </span>
        </div>
        <div>
            @Html.Hidden(prefixAddress + "Street", Model.Address.Street)
            @Html.LabelFor(m => m.Address.Street, Model.Address.Street)
        </div>
        <div>
            @Html.Hidden(prefixAddress + "City", Model.Address.City)
            @Html.Hidden(prefixAddress + "PostalCode", Model.Address.PostalCode)
            @Html.LabelFor(m => m.Address.City, Model.Address.City)&nbsp;&nbsp;@Html.LabelFor(m => m.Address.PostalCode, Model.Address.PostalCode.ToString())
        </div>
        @Html.Hidden(prefixContact + "IsRelated", Model.Contact.IsRelated)
        @if (Model.Contact.IsRelated)
        {
            <b>Family</b>
            if (Model.Contact.IsEmergency || Model.Contact.IsDeceased)
            {
            <b>/</b>
            }
        }
        @Html.Hidden(prefixContact + "IsEmergency", Model.Contact.IsEmergency)
        @if (Model.Contact.IsEmergency && !Model.Contact.IsDeceased)
        { 
            <b>Emergency</b>
        }
        @Html.Hidden(prefixContact + "IsDeceased", Model.Contact.IsDeceased)
        @if (Model.Contact.IsDeceased)
        { 
            <b>Deceased</b>
        }
        <input type="submit" name="button" value="Edit" class="iggr_button_edit" style="margin-left: 150px;" />
    </div>
    }
}

最后是我的控制器类

public class ContactsController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        ContactsRepository repository = new ContactsRepository();

        CDE.User user = (from u in repository.Users where u.IdUsers == 1 select u).FirstOrDefault();

        var contacts = (from u in repository.Users
                       join c in repository.Contacts on new { UserId = u.IdUsers } equals new { UserId = c.UserId }
                       join a in repository.Addresses on new { AddressId = c.AddressId } equals new { AddressId = a.IdAddresses }
                       select new ContactModel()
                       {
                           Contact = c,
                           Address = a
                       }).AsEnumerable();

        return View("Contacts", contacts);
    }

    [HttpPost]
    [ActionName("Edit")]
    [@ActionFilter(ActionInvokerType = "button", ActionInvokerValue = "Edit")]
    public ViewResult Edit(ContactModel contact)
    {
        //Here contact.Contact comes as null same for contact.Address
        return View("Contacts", null);//Ignore this line
    }
}

1 个答案:

答案 0 :(得分:0)

我觉得你的前缀结构干扰了MVC中通常会发生的绑定。您可以使用自定义模型绑定实现,或者找到一种没有前缀的方法。