我的Linq-SQL是否破坏了我的MVC2模型绑定?

时间:2011-04-01 04:07:17

标签: linq-to-sql asp.net-mvc-2 http-post model-binding

我正在尝试使用内置模型绑定的MVC 2来处理Web表单中的http-post。从过去几个小时我一直在搜索的内容来看,我认为“物体内的物体”有点挑剔。

我正在寻找任何类型的答案或资源链接,可以帮助我解决这个问题。我还处于这个阶段的早期阶段,所以如果有更好的方法 - 我全都耳朵。我自己编写了Linq-SQL而没有使用代码生成。我认为我最接近的答案是here,但我仍然没有得到它。

模型客户端(我对问题所在的最佳猜测):

public class Client
{

    public int ClientID { get; set; }

    ...

    [Column(Name = "Address_id")]
    internal int AddressID { get; set; }

    internal EntityRef<Address> _address;
    [System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
    public Address Address
    {
        get { return _address.Entity; }
        internal set { _address.Entity = value; AddressID = value.AddressID; }
    }
}

模型地址(在客户实体内)

public class Address
{
    [Column] public string Address1 { get; set; }

    [Column] public string Address2 { get; set; }

    [Column] public string City { get; set; }

    ...

查看型号:

    public class ClientFormViewModel
{
    public Client Client { get; set; }
    ...
}

查看:

        <!-- id is hidden -->
        <%: Html.EditorFor(m => m.Client.ClientID) %>

        ...

        <%: Html.EditorFor(m => m.Client.Address.AddressID) %>

        <%: Html.LabelFor(m => m.Client.Address.Address1) %>
        <%: Html.EditorFor(m => m.Client.Address.Address1) %><br />           

        <%: Html.LabelFor(m => m.Client.Address.Address2) %>
        <%: Html.EditorFor(m => m.Client.Address.Address2) %><br />                   

        ...  

控制器:

    public ViewResult Edit(int clientId)
    {
        var client = clientsRepository.Clients.First(x => x.ClientID == clientId);
        ...

        // create view model
        var viewModel = new ClientFormViewModel
        {
            Client = client,
            ...
        };

        return View(viewModel);
    }

    [HttpPost]
    public ActionResult Edit(ClientFormViewModel clientForm)
    {
        if (ModelState.IsValid)
        {
            clientsRepository.SaveClient(clientForm.Client);
            return RedirectToAction("List");
        }
        else // validation error, so redisplay the same view
            ...
    }

所以我的问题是......当我进入HttpPost操作时, clientForm.Client.Address 总是 null 。虽然,当我查看 ModelState (有效)或使用 Request。[“key”] 时,所有键都与我对象的结构相匹配。例如,我看到 ModelState [“Client.Address.Address1”] “Client.Address.Address2”等。

所有其他基本属性都填写正常,这让我觉得linq-sql代码打破了模型绑定。但是怎么样?有没有办法解决它?如果这些键在Request / ModelState字典中,为什么它们没有映射到对象?我完全错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:0)

如果您希望模型绑定器能够成功绑定它,则Address setter必须为public

internal EntityRef<Address> _address;
[System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
public Address Address
{
    get { return _address.Entity; }
    set { _address.Entity = value; AddressID = value.AddressID; }
}

我个人建议您使用视图模型,而不是将这些模型传递给视图。

答案 1 :(得分:0)

在@Darin Dimitrov提到使用视图模型而不是传递域模型(我认为我已经在做)之后,我最终找到了解决方案。

我没有依赖默认的模型绑定来获取我的Linq-SQL映射,而是创建了一个展平的视图模型。

这两个帖子对我的帮助最大:

http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx

http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

我首先遇到了AutoMapper的一些问题,但现在它的效果非常好。我会推荐它!