Мой Linq-SQL нарушает привязку модели MVC2? - PullRequest
0 голосов
/ 01 апреля 2011

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

Я ищу любые ответы или ссылки на ресурсы, которые могут помочь мне разобраться в этом. Я все еще на ранних стадиях этого тоже, так что, если есть лучший способ - я все уши. Я сам писал 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 ]

0 голосов
/ 04 апреля 2011

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

0 голосов
/ 01 апреля 2011

Установщик 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; }
}

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

...