请帮助将对象传回发布操作

时间:2009-09-09 13:15:27

标签: c# asp.net-mvc

我有一个get方法将一个Store类型的对象传递给视图,在使用菜单对话框创建视图时(即创建强类型视图),当我选择视图内容时,它正确地将表单括起来编辑。在不改变视图的任何内容的情况下,我添加了一个接受商店对象作为参数的post方法。对象上的属性永远不会填充表单数据,我无法弄清楚原因。 Request.Form.Count显示14个正确的项目减去将生成15的Id。如果我分别键入每个参数,它们会被设置。我也可以使用FormCollection来获取值,但确定将整个对象传回并使用它会很好。

是否有可能发生这种情况的原因?

商店定义:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DomainModel
{
    public class Store : GuidIdentityPersistenceBase
    {
        private string _address1;

        private string _address2;

        private string _city;

        private string _county;

        private int _oldStoreNumber;

        private string _faxNumber;

        private bool _hasHydraulicHose;

        private bool _hasInsCounter;

        private bool _hasPaintBooth;

        private bool _isHubStore;

        private bool _isOpenNightsWeekends;

        private int _newStoreNumber;

        private string _phoneNumber;

        private string _postalCode;

        private string _state;

        private IList _walls = new List();

        public virtual string Address1
        {
            get
            {
                return _address1;
            }
            set
            {
                _address1 = value;
            }
        }

        public virtual string Address2
        {
            get
            {
                return _address2;
            }
            set
            {
                _address2 = value;
            }
        }

        public virtual string City
        {
            get
            {
                return _city;
            }
            set
            {
                _city = value;
            }
        }

        public virtual string County
        {
            get
            {
                return _county;
            }
            set
            {
                _county = value;
            }
        }

        public virtual int OLDStoreNumber
        {
            get
            {
                return _oldStoreNumber;
            }
            set
            {
                _oldStoreNumber = value;
            }
        }

        public virtual string FaxNumber
        {
            get
            {
                return _faxNumber;
            }
            set
            {
                _faxNumber = value;
            }
        }

        public virtual bool HasHydraulicHose
        {
            get
            {
                return _hasHydraulicHose;
            }
            set
            {
                _hasHydraulicHose = value;
            }
        }

        public virtual bool HasInsCounter
        {
            get
            {
                return _hasInsCounter;
            }
            set
            {
                _hasInsCounter = value;
            }
        }

        public virtual bool HasPaintBooth
        {
            get
            {
                return _hasPaintBooth;
            }
            set
            {
                _hasPaintBooth = value;
            }
        }

        public virtual Guid Id
        {
            get
            {
                return _persistenceId;
            }
        }

        public virtual bool IsHubStore
        {
            get
            {
                return _isHubStore;
            }
            set
            {
                _isHubStore = value;
            }
        }

        public virtual bool IsOpenNightsWeekends
        {
            get
            {
                return _isOpenNightsWeekends;
            }
            set
            {
                _isOpenNightsWeekends = value;
            }
        }

        public virtual int NewStoreNumber
        {
            get
            {
                return _newStoreNumber;
            }
            set
            {
                _newStoreNumber = value;
            }
        }

        public virtual string PhoneNumber
        {
            get
            {
                return _phoneNumber;
            }
            set
            {
                _phoneNumber = value;
            }
        }
        public virtual string PostalCode
        {
            get
            {
                return _postalCode;
            }
            set
            {
                _postalCode = value;
            }
        }

        public virtual string State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
            }
        }

        public virtual IList Walls
        {
            get
            {
                return _walls.ToList().AsReadOnly();
            }
        }

        public virtual void AddWall(Wall wall)
        {
            wall.Store = this;
            _walls.Add(wall);
        }

    }
}

采取行动:

[AcceptVerbs(HttpVerbs.Get)]
        public ViewResult EditStore(Guid Id)
        {
            Store store;
            using (UnitOfWork.Start())
            {
                store = _storeRepository.GetStore(Id);
            }

            return View(store);
        }

发布行动(是的,我意识到没有编码检查等,一开始只是粗略):

[AcceptVerbs(HttpVerbs.Post)]
           public ActionResult EditStore(Store store)
        {
            using (UnitOfWork.Start())
            {
                _storeRepository.Update(store);

                UnitOfWork.Current.Flush();
            }

            return RedirectToAction("EditStore", store.Id);
        }

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Address1">Address1:</label>
            <%= Html.TextBox("Address1", Model.Address1) %>
            <%= Html.ValidationMessage("Address1", "*") %>
        </p>
        <p>
            <label for="Address2">Address2:</label>
            <%= Html.TextBox("Address2", Model.Address2) %>
            <%= Html.ValidationMessage("Address2", "*") %>
        </p>
        <p>
            <label for="City">City:</label>
            <%= Html.TextBox("City", Model.City) %>
            <%= Html.ValidationMessage("City", "*") %>
        </p>
        <p>
            <label for="County">County:</label>
            <%= Html.TextBox("County", Model.County) %>
            <%= Html.ValidationMessage("County", "*") %>
        </p>
        <p>
            <label for="OLDStoreNumber">OLDStoreNumber:</label>
            <%= Html.TextBox("OLDStoreNumber", Model.OLDStoreNumber) %>
            <%= Html.ValidationMessage("OLDStoreNumber", "*") %>
        </p>
        <p>
            <label for="FaxNumber">FaxNumber:</label>
            <%= Html.TextBox("FaxNumber", Model.FaxNumber) %>
            <%= Html.ValidationMessage("FaxNumber", "*") %>
        </p>
        <p>
            <label for="HasHydraulicHose">HasHydraulicHose:</label>
            <%= Html.TextBox("HasHydraulicHose", Model.HasHydraulicHose) %>
            <%= Html.ValidationMessage("HasHydraulicHose", "*") %>
        </p>
        <p>
            <label for="HasInsCounter">HasInsCounter:</label>
            <%= Html.TextBox("HasInsCounter", Model.HasInsCounter) %>
            <%= Html.ValidationMessage("HasInsCounter", "*") %>
        </p>
        <p>
            <label for="HasPaintBooth">HasPaintBooth:</label>
            <%= Html.TextBox("HasPaintBooth", Model.HasPaintBooth) %>
            <%= Html.ValidationMessage("HasPaintBooth", "*") %>
        </p>
        <p>
            <label for="IsHubStore">IsHubStore:</label>
            <%= Html.TextBox("IsHubStore", Model.IsHubStore) %>
            <%= Html.ValidationMessage("IsHubStore", "*") %>
        </p>
        <p>
            <label for="IsOpenNightsWeekends">IsOpenNightsWeekends:</label>
            <%= Html.TextBox("IsOpenNightsWeekends", Model.IsOpenNightsWeekends) %>
            <%= Html.ValidationMessage("IsOpenNightsWeekends", "*") %>
        </p>
        <p>
            <label for="NewStoreNumber">NewStoreNumber:</label>
            <%= Html.TextBox("NewStoreNumber", Model.NewStoreNumber) %>
            <%= Html.ValidationMessage("NewStoreNumber", "*") %>
        </p>
        <p>
            <label for="PhoneNumber">PhoneNumber:</label>
            <%= Html.TextBox("PhoneNumber", Model.PhoneNumber) %>
            <%= Html.ValidationMessage("PhoneNumber", "*") %>
        </p>
        <p>
            <label for="PostalCode">PostalCode:</label>
            <%= Html.TextBox("PostalCode", Model.PostalCode) %>
            <%= Html.ValidationMessage("PostalCode", "*") %>
        </p>
        <p>
            <label for="State">State:</label>
            <%= Html.TextBox("State", Model.State) %>
            <%= Html.ValidationMessage("State", "*") %>
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

<% } %>

<div>
    <%=Html.ActionLink("Back to List", "Index") %>
</div>

<fieldset> <legend>Fields</legend> <p> <label for="Address1">Address1:</label> <%= Html.TextBox("Address1", Model.Address1) %> <%= Html.ValidationMessage("Address1", "*") %> </p> <p> <label for="Address2">Address2:</label> <%= Html.TextBox("Address2", Model.Address2) %> <%= Html.ValidationMessage("Address2", "*") %> </p> <p> <label for="City">City:</label> <%= Html.TextBox("City", Model.City) %> <%= Html.ValidationMessage("City", "*") %> </p> <p> <label for="County">County:</label> <%= Html.TextBox("County", Model.County) %> <%= Html.ValidationMessage("County", "*") %> </p> <p> <label for="OLDStoreNumber">OLDStoreNumber:</label> <%= Html.TextBox("OLDStoreNumber", Model.OLDStoreNumber) %> <%= Html.ValidationMessage("OLDStoreNumber", "*") %> </p> <p> <label for="FaxNumber">FaxNumber:</label> <%= Html.TextBox("FaxNumber", Model.FaxNumber) %> <%= Html.ValidationMessage("FaxNumber", "*") %> </p> <p> <label for="HasHydraulicHose">HasHydraulicHose:</label> <%= Html.TextBox("HasHydraulicHose", Model.HasHydraulicHose) %> <%= Html.ValidationMessage("HasHydraulicHose", "*") %> </p> <p> <label for="HasInsCounter">HasInsCounter:</label> <%= Html.TextBox("HasInsCounter", Model.HasInsCounter) %> <%= Html.ValidationMessage("HasInsCounter", "*") %> </p> <p> <label for="HasPaintBooth">HasPaintBooth:</label> <%= Html.TextBox("HasPaintBooth", Model.HasPaintBooth) %> <%= Html.ValidationMessage("HasPaintBooth", "*") %> </p> <p> <label for="IsHubStore">IsHubStore:</label> <%= Html.TextBox("IsHubStore", Model.IsHubStore) %> <%= Html.ValidationMessage("IsHubStore", "*") %> </p> <p> <label for="IsOpenNightsWeekends">IsOpenNightsWeekends:</label> <%= Html.TextBox("IsOpenNightsWeekends", Model.IsOpenNightsWeekends) %> <%= Html.ValidationMessage("IsOpenNightsWeekends", "*") %> </p> <p> <label for="NewStoreNumber">NewStoreNumber:</label> <%= Html.TextBox("NewStoreNumber", Model.NewStoreNumber) %> <%= Html.ValidationMessage("NewStoreNumber", "*") %> </p> <p> <label for="PhoneNumber">PhoneNumber:</label> <%= Html.TextBox("PhoneNumber", Model.PhoneNumber) %> <%= Html.ValidationMessage("PhoneNumber", "*") %> </p> <p> <label for="PostalCode">PostalCode:</label> <%= Html.TextBox("PostalCode", Model.PostalCode) %> <%= Html.ValidationMessage("PostalCode", "*") %> </p> <p> <label for="State">State:</label> <%= Html.TextBox("State", Model.State) %> <%= Html.ValidationMessage("State", "*") %> </p> <p> <input type="submit" value="Save" /> </p> </fieldset> <% } %> <div> <%=Html.ActionLink("Back to List", "Index") %> </div>

的Fiddler:

5 个答案:

答案 0 :(得分:1)

重命名表单元素以匹配 objectname propertyname ,如下所示:

<%= Html.TextBox("SomeNewObj.Id",Model.Id);
<%= Html.TextBox("SomeNewObj.Title",Model.Title);

其中 SomeNewObj 是POST方法的参数名称:

public ActionResult SomePostMethod(int id, Store SomeNewObj)
{
     //SomeNewObj.Title should be properly populated
     //...
}

仅当表单ID包含对象参数的名称及其属性时,ASP.NET MVC才会与新的Store对象建立关联。

记得编码! :)我在这个例子中把它留了出来。

答案 1 :(得分:1)

您的表单必须包含该类型的所有非可空属性,否则默认模型绑定程序不会绑定它。你说你不包括ID。这是一个像Guid或int这样的非可空类型吗?那是你的问题。

有两种方法可以解决这个问题:

  1. 将ID的类型更改为像Guid一样可以为空的类型?
  2. 为表单添加ID的“默认”值,例如Guid.Empty。
  3. 我注意到您使用TextBoxes绑定到Boolean属性。这意味着如果省略任何值或无法将其转换为布尔值,则整个类型的绑定将失败,因为属性不可为空。使用除复选框之外的任何东西来绑定到布尔值有点不稳定。通常,如果您为模型绑定设计一个类型,您可能希望在用户未填写一个属性并不意味着您不希望看到它们为其他属性填充的内容时使所有内容都可为空。

答案 2 :(得分:0)

您可以尝试使用UpdateModel(StoreObject);

也许值会被设定。

答案 3 :(得分:0)

我为它设置了一个CustomModelBinder。对于一些前期工作,从长远来看这些回报,相信我......

public class StoreModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext,
                                           ModelBindingContext bindingContext)
    {
        Store store= 
            (Store)(bindingContext.Model ?? new Store());

        // For example...
        store.ID = Convert.ToInt32(controllerContext.HttpContext.Request["storeID"]);

        // Set other properties...
    }
}

您可以跨控制器和操作重用,您的控制器不必担心消化FormCollections。

答案 4 :(得分:0)

问题在于我使用的IoC框架。好吧,它不是框架本身的问题,而是我的配置。将Castle Windsor用于IoC框架时,必须将注册的容器标记为具有生活方式=瞬态而不是默认的Singleton。如果您允许使用默认值,那么在使用它时会造成严重破坏。

谢谢大家的帮助。