Мой Linq-SQL нарушает привязку модели MVC2?

Я пытаюсь обработать http-сообщение из веб-формы, используя встроенную привязку модели MVC 2s. Из того, что я искал последние несколько часов, я понял, что это немного привередливо к "объектам внутри объектов".

Я ищу любые ответы или ссылки на ресурсы, которые могут помочь мне понять это. Я все еще на ранних стадиях этого тоже, так что, если есть лучший способ - я все уши. Я сам писал 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.Address всегда имеет значение null. Хотя, когда я смотрю на ModelState (который действителен) или использую Request.["Key"], все ключи соответствуют структуре моего объекта. Например, я вижу ModelState ["Client.Address.Address1"], "Client.Address.Address2" и т. Д.

Все остальные базовые свойства заполнены в порядке, что заставляет меня думать, что код linq-sql нарушает привязку модели. Но как? И есть ли способ это исправить? Если эти ключи находятся в словаре Request/ModelState, почему они не отображаются на объект? Я что-то упускаю из виду?

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, но теперь он работает довольно хорошо. Я бы порекомендовал это!

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

Лично я бы порекомендовал вам использовать модели представления вместо передачи этих моделей в представления и из них.

Другие вопросы по тегам