【问题标题】:Is my Linq-SQL breaking my MVC2 model binding?我的 Linq-SQL 是否破坏了我的 MVC2 模型绑定?
【发布时间】:2011-07-27 09:55:22
【问题描述】:

我正在尝试使用内置模型绑定的 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 字典中,为什么它们没有被映射到对象?我完全错过了一些明显的东西吗?

【问题讨论】:

  • 您可能想要尝试做的事情是将您的视图模型传递给视图以进行渲染,然后在发布操作中绑定您的模型。我不认为你通过交换它来让自己更容易:)。
  • 可能是嵌套太深了?我做了类似的事情,但我的 EditorFor lambda 是 model.Email.EmailAddress,所以我成功地使用了少一层嵌套。另外,您可以发布为您的表单呈现的 html 吗?也许 Ids/Names 没有正确呈现。
  • 我不认为嵌套级别会成为问题。您很可能会发现问题是由于传递给默认模型绑定器的值与被绑定的模型不匹配,无论出于何种原因。您可以随时尝试注册自己的模型绑定器,以准确检查传递给绑定器的内容(或者按照 jlnors 的建议查看 HTML :))
  • @Shaun 我将正在传递的编辑操作添加到我为创建视图而创建的简单视图模型(请参阅下面对 Darin 的评论)到帖子中。我试图绑定到 httppost 中的视图模型的唯一原因(我之前曾尝试绑定到“客户端”,但与空子对象存在相同的问题)是这样我可以在验证错误时重新显示视图。 @jlnorsworthy 我也将在今天晚些时候查看 html。虽然,我认为我的问题可能出在视图模型中,因为我正在传递我的域对象。在域/视图模型之间有另一层对我来说更有意义。

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


【解决方案1】:

如果您希望模型绑定器能够成功绑定它,Address 设置器必须是 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; }
}

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

【讨论】:

  • 我在这个post 中使用类似于“模式2”的视图模型。基本上我的视图模型包含领域模型。 “模式 3”最有可能是你得到的?我认为这是我最有可能寻找的东西。在这篇文章中,他还链接到this post,它解释得更好,但也包括这个“AutoMapper”的东西。在这种情况下,这是一件好事吗?
【解决方案2】:

在@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 时遇到了一些问题,但现在它运行良好。我会推荐它!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 2016-08-23
    相关资源
    最近更新 更多