ASP.NET WebForms — дизайн элементов управления (относительно данных)

Я разрабатываю/создаю среднемасштабное веб-приложение ASP.NET с использованием WebForms. Основная работа в проекте заключается в создании каждой веб-формы, и я не знаю, как спроектировать (в смысле кода/данных/потока данных) свои элементы управления.

Я приведу вам несколько примеров того, с чем я имею дело, чтобы вы могли понять, что я имею в виду:


Распространенной задачей в приложении является ввод и отображение уличных адресов. Поэтому я создал UserControl под названием «AddressFields», который содержит ряд элементов HtmlInputText (один для строки 1, другой для города, страны, почтового индекса и т. д.). Мои классы сущностей БД содержат класс под названием «Адрес», поэтому этот элемент управления имеет методы:

  • void ShowAddress(Address addr) — заполняет элементы HtmlInputText соответствующим текстом).
  • void UpdateAddress(Address addr) — обновляет содержимое addr текущим содержимым элементов HtmlInputText.
  • Address CreateAddress() — создает новый экземпляр Address, передает его в UpdateAddress и затем возвращает.

Все идет нормально. Это работает, потому что элемент управления AddressFields «тупой», все, что он делает, — это отображает и извлекает данные для пользователя. ViewState также напрямую управляется полями HtmlInputText, поэтому никакой дополнительной логики не требуется.


Другой объект в моем приложении — «Клиент», который представляет собой класс с атрибутом Address, но этот класс также имеет несколько более сложных аспектов. Например, у клиента есть ряд тегов («категории» в моем приложении), которые можно назначить. В этом случае я разработал подкласс элемента управления ASP.NET CheckboxList.

Я создал еще один UserControl под названием «ClientFields», который содержит все необходимые поля для отображения информации о клиенте (включая элемент управления AddressFields), но также включает в себя мой подкласс CheckboxList под названием «CategoryList».

Проблема здесь в том, что элементу управления CategoryList необходимо предоставить данные для отображения (но не для обратных передач, поскольку он использует состояние просмотра). В этом случае у меня возникает вопрос: кто отвечает за подключение к базе данных и получение списка категорий?

Это элемент управления CategoryList? (Если да, то на каком этапе жизни элемента управления он запрашивает базу данных? Он не может сделать это в Control.Load, потому что это происходит после заполнения ClientFields. Происходит ли это в самих ClientFields? это происходит, потому что у ClientFields есть свой метод ShowClient(Client c), вызываемый внутри Page.Load.Альтернативой является выставление CategoryList из ClientFields, чтобы он мог быть доступен непосредственно страницей, но это нарушение хорошего дизайна программного обеспечения.


person Dai    schedule 28.03.2011    source источник
comment
ShowClient(Client c), загружены ли в ваш класс Client данные категории? Поскольку класс Client содержит данные клиента, я предполагаю, что данные категории являются его частью.   -  person Ricky    schedule 28.03.2011
comment
Я использую Linq-to-SQL для своего класса сущностей, а отношение Client/Category является отношением «многие ко многим», поэтому содержимое Client.Categories представляет собой просто таблицу ссылок. Класс клиента предварительно заполняется к тому времени, когда он попадает в форму, но список других категорий (которые не выбраны) недоступен, если вы не получите их специально из БД.   -  person Dai    schedule 28.03.2011


Ответы (1)


На мой взгляд, CategoryList отвечает за получение данных списка категорий, потому что все данные категорий должны быть получены независимо от того, выбраны ли один или несколько из них конкретным клиентом.

когда CategoryList запрашивает базу данных в течение своего жизненного цикла?

Как правило, переопределяйте метод OnInit для заполнения CategoryList, но ViewState не начинает работать в это время, поэтому вам нужно извлекать данные из БД и заполнять себя при каждой обратной передаче. Если вы хотите полагаться на ViewState, определите и зарегистрируйте обработчик событий InitComplete для Page в переопределенном методе OnInit и заполните CategoryList в обработчике событий. И метод OnInit, и событие InitComplete вызываются/запускаются перед событием Load.

//In CategoryList control
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    Page.InitComplete += new EventHandler(Page_InitComplete);
}

void Page_InitComplete(object sender, EventArgs e)
{
    // retrieve the data and populate the control
}

Надеюсь, поможет

person Ricky    schedule 28.03.2011