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

发布于 2024-10-28 02:31:44 字数 2799 浏览 2 评论 0原文

我正在尝试使用 MVC 2 内置模型绑定来处理来自 Web 表单的 http-post。从我过去几个小时的搜索来看,我发现“对象中的对象”有点挑剔。

我正在寻找任何类型的答案或资源链接来帮助我解决这个问题。我还处于早期阶段,所以如果有更好的方法 - 我洗耳恭听。我一直在自己编写 Linq-SQL,而不是使用代码生成。我认为我正在寻找的最接近的答案是 这里,但我还是没明白。

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

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。地址始终为。虽然,当我查看 ModelState(有效)或使用 Request.["key"] 时,所有键都与我的对象的结构匹配。例如,我看到 ModelState["Client.Address.Address1"]"Client.Address.Address2" 等。

所有其他基本属性都填写良好,这让我认为 linq-sql 代码破坏了模型绑定。但如何呢?有办法解决吗?如果这些键位于 Request/ModelState 字典中,为什么它们没有映射到对象?我完全错过了一些明显的东西吗?

I am trying to handle the http-post from a web form using MVC 2s built in model binding. From what I have been searching through for the past few hours I have figured it is a bit finicky with "objects within objects."

I'm looking for any kind of answers or links to resources that may help me figure this out. I'm still in the early stages of this also so if there is a better way - I'm all ears. I have been writing the Linq-SQL myself and not using the code generation. I think the closest answer I'm looking for is here, but I'm still not getting it.

Model Client (my best guess for where the issue is):

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; }
    }
}

Model Address (within client entity)

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

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

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

    ...

View Model:

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

View:

        <!-- 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 />                   

        ...  

Controller:

    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
            ...
    }

So my issue is... when I get into the HttpPost action, the clientForm.Client.Address is always null. Although, when I look into the ModelState (which is valid), or use Request.["key"], all of the keys match the structure of my object. For example, I see ModelState["Client.Address.Address1"], "Client.Address.Address2", etc.

All other basic properties are filled in fine, which make me think the linq-sql code is breaking the model binding. But how? And is there a way to fix it? If those keys are within the Request/ModelState dictionary, why are they not being mapped to the object? Am I totally missing something obvious?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独闯女儿国 2024-11-04 02:31:44

如果您希望模型绑定器能够成功绑定它,则 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; }
}

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

The Address setter must be public if you want the model binder to be able to successfully bind it:

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; }
}

Personally I would recommend you using view models instead of passing those models to and from the views.

好多鱼好多余 2024-11-04 02:31:44

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

After @Darin Dimitrov mentioned using a view model instead of passing the domain model (which I thought I was already doing), I ended up figuring out a solution.

Instead of relying on the default model binding picking up my Linq-SQL mapping, I created a flattened view model.

What helped me the most were these two posts:

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/

I had some issues with AutoMapper at first, but now it works pretty well. I would recommend it!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文