Створення динамічного інтерфейсу ASP.NET, керованого даними, Різне, Програмування, статті

 

Більшість веб-додатків, керованих даними, мають фіксованими моделлю даних і призначеним для користувача інтерфейсом. “Фіксованими” в тому плані, що дані, які необхідно отримати, вже відомі заздалегідь. Отже, таблиці бази даних створені до того, як пишеться сам код, і призначений для користувача інтерфейс програми диктується заздалегідь певною моделлю даних. У той час як більшість додатків працюють з фіксованою моделлю даних, існують випадки, коли частини моделі повинні бути визначені кінцевим користувачем. Такі програми складніше створити, тому що модель даних і призначений для користувача інтерфейс повинні бути достатньо гнучкими, щоб дозволити користувачеві вказати інформацію, яку потрібно зберігати.


Уявіть, що ви створюєте веб-додаток, яке використовувалося б у маленьких юридичних фірмах для управління їх клієнтурою. Вам знадобиться таблиця бази даних, яка зберігала б інформацію про кожного клієнті. Дана таблиця буде мати колонки для кожного атрибута клієнта, наприклад: FirstName-для імені, LastName-для прізвища, Email – для електронної пошти, Address1 – для основного адреси, Address2 – Для додаткового адреси, City – місто і так далі. Незалежно від того, які атрибути ви визначите для даної таблиці, ви можете бути впевнені в тому, що може з’явитися така юридична контора, якої буде потрібна додаткова інформація, не міститься в таблиці. Щоб надати такий рівень гнучкості, вам необхідно дозволити кожній фірмі вказувати додаткові атрибути щодо клієнтів, що стосуються їх компанії.


Дана стаття є першою частиною з чотирьох, які розглядають спосіб створення моделі даних і призначеного для користувача інтерфейсу, що дозволяють реалізувати дані динамічні веб-сайти, керовані даними. У цій статті ми розглянемо збереження динамічної, визначеної кінцевим користувачем інформації в базі даних. Читайте далі, щоб дізнатися більше про це!


Огляд динамічного користувальницького інтерфейсу, керованого даними


До того, як ми почнемо створювати нашу модель даних, давайте приділимо якийсь час обговорення всіх основ динамічного користувальницького інтерфейсу, керованого даними. Такі інтерфейси найчастіше використовуються в веб-додатках, де єдиний сервер додатка служить як веб-сайту для безлічі клієнтів. У вступі я навів приклад веб-додатки, що використовується безліччю юридичних компаній. Ідея з динамічним пользователскім інтерфейсом, керованим даними, полягає в тому, що на додаток до текстових полів даних клієнтам може знадобитися створити спеціалізовані атрибути. Така модель вимагає наявності таких компонентів:



У наведеній статті розглядається спосіб створення моделі даних для запису динамічних атрибутів, вказаних користувачем. У другій частині ми розглянемо спосіб створення веб-сторінки, де клієнти визначають свої спеціалізовані атрибути. Третя частина досліджує найскладнішу складову головоломки – динамічне створення користувальницького інтерфейсу, заснованого на інформації авторизованого користувача, а четверта розгляне більш просунуті принципи по даній темі.


Протягом трьох перших статей ми досліджуємо реалізацію спрощеної версії даного прикладу, зазначеного у введенні до даної статті, а саме веб-додатки для юридичних фірм, що дозволяє кожній компанії вказати і зберегти спеціалізіровнние атрибути, що стосуються їх клієнтури.


Створення фіксованої частини моделі даних: схеми Membership та пов’язаних з нею сутностей, а також Customers і Clients


Більшість додатків мають динамічним, керованим даними компонентом, а також фіксованої моделлю даних. Більш того, зазвичай більшість моделей даних є фіксованими, у той час як невелика частина все ж є динамічною. Для даного прикладу існують три сутності фіксованого моделі даних:



По-перше, нам необхідно реалізувати SqlMembershipProvider з ASP.NET та налаштувати сайт на використання авторизації на основі форми, але повний опис даного процесу виходить за рамки цієї статті (для отримання більш детальної інформації вам варто прочитати статті з темі авторизації на основі форми, Membership і Roles). Реалізація SqlMembershipProvider додасть кілька таблиць, уявлень і збережених процедур. Таблиця aspnet_Users містить по запису для кожного користувача, і кожна записть унікально ідентифікується за допомогою поля UserId, яке є типу uniqueidentifier. На додаток до таблиць, що належать до SqlMembershipProvider, нам необхідно додати іншу таблицю, яка вказує, до якої облікового запису належить кожен користувач. Ми повернемося до цього, як тільки створимо таблицю Customers.


Таблиця Customers використовується для моделювання різних юридичних компаній, які використовують наш веб-сайт. Дана таблиця містить по запису на кожну юридичну фірму (наші клієнти – користувачі). Створіть дану таблицю, слідуючи нижчеподаній схемою:















Column Name

Data Type

Опис


CustomerId


uniqueidentifier


Первинний ключ; значення за замовчуванням – NEWID ()


FirmName


nvarchar(50)



Зверніть увагу на те, що поле CustomerId є типу uniqueidentifier і має значення, рівне за замовчуванням NEWID (). uniqueidentifier є SQL-виразом для Globally Unique Identifier (GUID) (Глобально унікальний ідентифікатор); NEWID () за замовчуванням автоматично призначає значення GUID даної колонці при вставці нового запису. Якщо б ви хотіли зробити дану колонку типу int і зробити її типу IDENTITY, то і це цілком реалізовується.


Тепер, коли ми реалізували таблицю Customers, ми можемо повернутися і додати таблицю, яка пов’язує клієнтські записи з користувачами. Створіть нову таблицю з назвою ExtendedUserInfo і з наступного структурою:















Column Name

Data Type

Опис


UserId


uniqueidentifier


Первинний ключ; Зовнішній ключ до aspnet_Users.UserId


CustomerId


uniqueidentifier


Зовнішній ключ до Customers.CustomerId


Дана таблиця має зв’язок типу “один до одного” з таблицею aspnet_Users (яка містить по запису для кожної користувальницької записи системи). На даний момент таблиця містить тільки одну колонку – CustomerId, але ви можете додати інші, на ваш розсуд.


Остання таблиця, яку нам необхідно створити, є таблиця Clients. Якщо ви пам’ятаєте, ця таблиця має по одному запису для кожного клієнта юридичної фірми, і вона ж зберігає фіксовані атрибути, які притаманні всім юридичним фірмам. Створіть дану таблицю згідно з наступною схемою:



























Column Name

Data Type

Опис


ClientId


uniqueidentifier


Первинний ключ; default value of NEWID ()


CustomerId


uniqueidentifier


Зовнішній ключ до Customers.CustomerId


FirstName


nvarchar(50)



LastName


nvarchar(50)



Email


nvarchar(100)



Наступна ER-діаграма демонструє три таблиці, створені нами вручну, а також таблицю aspnet_Users і з відносинами між ними всіма.


Збереження значень спеціалізованих атрибутів клієнта


На даному етапі сторінка ~ / Customers / ClientCustomAttributes.aspx відображає інтерфейси для спеціалізованих клієнтських атрибутів і включає поточні, щойно відредаговані, значення. Нарешті, нам треба оновити зміни значень атрибутів. Сторінка ~ / Customers / ClientCustomAttributes.aspx включає в себе кнопку Update, натиснувши яку ви відновите значення спеціалізованих атрибутів клієнта і потім користувач буде перенаправлено на сторінку управління клієнтами (Manage Clients) (ie, ~ / Customers / Default.aspx).


Насамперед тут буде отримання значень, які користувач ввів в різні інтерфейси спеціалізованих атрибутів. Це здійснимо шляхом здійснення запиту до бази даних для того, щоб отримати список спеціалізованих атрибутів для клієнта і потім перерахувати атрибути використовуючи метод FindControl (controlId) для того, щоб програмно отримати доступ до елемента керування і отримати його значення.


Наступний блок коду (який я знайшов в обробнику події Click елемента Update Button) отримує спеціалізований клієнтський атрибут з бази даних, в циклі проходить по них і для кожного атрибута викликає метод GetValueForCustomAttribute щоб отримати користувача введення в інтерфейс. Незабаром ми розглянемо даний метод.


“Отримання спеціалізованих атрибутів для користувача


Dim myCommand As New SqlCommand


myCommand.Connection = myConnection


myCommand.Transaction = myTransaction


myCommand.CommandText = “SELECT a.DynamicAttributeId, a.DataTypeId ” & _


                  “FROM DynamicAttributesForClients a ” & _


                  “WHERE a.CustomerId = @CustomerId “


myCommand.Parameters.AddWithValue(“@CustomerId”, Helpers.GetCustomerIdForLoggedOnUser())


Dim myReader As SqlDataReader = myCommand.ExecuteReader


Dim AttributeValues As New Dictionary(Of Guid, SqlParameter)
While myReader.Read()
   Dim DynamicAttributeId As Guid = CType(myReader(“DynamicAttributeId”), Guid)
   Dim DataTypeId As DataTypeIdEnum = CType(Convert.ToInt32(myReader(“DataTypeId”)), DataTypeIdEnum)


   AttributeValues(DynamicAttributeId) = GetValueForCustomAttribute(DynamicAttributeId, DataTypeId)
End While
myReader.Close() 


Значення, повернення з методу GetValueForCustomAttribute, зберігаються в об’єкті Dictionary, названому AttributeValues. Об’єкт Dictionary придатний для зберігання набору елементів, які індексуються з якогось значенням, відмінному від порядкового числа. В даному випадку я хочу мати колекцію атрибутів, доступну за допомогою AttributeId (значення Guid), чиїми значеннями є об’єкти SqlParameter з відповідними значеннями, введеними користувачем. Тому я створив об’єкт Dictionary з ключами типу Guid і значення типу SqlParameter – Dim AttributeValues ​​As New Dictionary (Of Guid, SqlParameter). (Якщо вам все ще незрозуміло, то все стане більш зрозуміло, як тільки ми далі розглянемо код обробника події Click, який насправді оновлює базу даних.)


Метод GetValueForCustomAttribute повертає об’єкт SqlParameter зі значенням ParameterName типу @ DynamicValue і відповідно встановлені властивості Value і DbType. Якщо клієнт не введе значення, Value елемента SqlParameter – призначається значення NULL (DBNull.Value). Більш того, властивість DbType встановлено відповідно до типу даних спеціалізованого клієнтського атрибута. Користувальницький інтерфейс, використовуваний для певного клієнтського атрибута, повертається за допомогою методу FindControl (controlId) (а саме, CustomUITable.FindControl (controlId)). Згадайте, що при створенні елементів управління користувальницького інтерфейсу для спеціалізованих клієнтських атрибутів, ми налаштуємо ID елемента управління в значення колонки DynamicAttributeId, форматованого за допомогою методу GetID. Така ж логіка використовується для програмного пошуку елемента управління, тим самим ми можемо повернути значення, введене користувачем.


Private Function GetValueForCustomAttribute(ByVal DynamicAttributeId As Guid, ByVal DataTypeId As DataTypeIdEnum) As SqlParameter


   Dim userInputParam As New SqlParameter


   userInputParam.ParameterName = “@DynamicValue”


   userInputParam.Value = DBNull.Value


   Dim ctrlId As String = GetID(DynamicAttributeId)
   Dim ctrl As Control = CustomUITable.FindControl(ctrlId)


   Select Case DataTypeId
      Case DataTypeIdEnum.String
         Dim tb As TextBox = CType(ctrl, TextBox)
         userInputParam.DbType = Data.DbType.String
         If Not String.IsNullOrEmpty(tb.Text) Then
            userInputParam.Value = tb.Text.Trim()
         End If


      Case DataTypeIdEnum.Boolean
         Dim cb As CheckBox = CType(ctrl, CheckBox)
         userInputParam.Value = cb.Checked
         userInputParam.DbType = Data.DbType.Boolean


      Case DataTypeIdEnum.Numeric
         Dim tb As TextBox = CType(ctrl, TextBox)
         userInputParam.DbType = Data.DbType.Double
         If Not String.IsNullOrEmpty(tb.Text) Then
            userInputParam.Value = tb.Text.Trim()
         End If


      Case DataTypeIdEnum.Date
         Dim tb As TextBox = CType(ctrl, TextBox)
         userInputParam.DbType = Data.DbType.Date
         If Not String.IsNullOrEmpty(tb.Text) Then
            userInputParam.Value = tb.Text.Trim()
         End If
   End Select


   Return userInputParam
End Function 


Так само, як і у випадку з кодом, використовуваним для створення призначеного для користувача інтерфейсу, логіка, що використовується в методі GetValueForCustomAttribute для отримання користувацького значення, є жорстко запрограмованої у фоновому класі ASP.NET.


Як тільки всі значення спеціалізованих клієнтських атрибутів будуть завантажені в об’єкт AttributeValues ​​Dictionary, ми будемо готові оновити базу даних. Кожне значення клієнтського атрибута зберігається в записі таблиці DynamicValuesForClients. Якщо всього існують п’ять спеціалізованих атрибутів, то кожен клієнт, чиї атрибути були збережені, буде мати п’ять записів у DynamicValuesForClients. При збереженні клієнтських спеціалізованих атрибутів нам напевно знадобиться:


· Вставити записи в DynamicValuesForClients – якщо у клієнта ще не були вказані значення жодного спеціалізованого атрибута, або якщо нові спеціалізовані клієнтські атрибути були додані в систему, то в DynamicValuesForClients не буде відповідного запису для конкретного значення атрибута. Тому нам необхідно буде додати новий запис в DynamicValuesForClients.


· Відновити записи в DynamicValuesForClients – якщо клієнт вже має запис в DynamicValuesForClients для певного спеціалізованого атрибута, оновлення значення атрибута потребує оновлення відповідного запису в базі даних.


Який підхід ми будемо використовувати – залежить від того, чи існує вже запис в таблиці DynamicValuesForClients для пари ClientId і AttributeId. Я створив збережену процедуру, названу lawfirm_AddOrUpdateDynamicValueForClient для обробки даного рішення. Це спрощує код ASP.NET: просто в циклі пройти по об’єкту AttributeValues ​​Dictionary і для кожного елемента викликати збережену процедуру lawfirm_AddOrUpdateDynamicValueForClient, передаючи ClientId, AttributeId і значення для даного атрибута. (Оскільки елементи в об’єкті AttributeValues ​​Dictionary є об’єктами SqlParameter, то ми можемо додати їх до набору Parameters SqlCommand використовуючи myCommand.Parameters.Add (AttributeValues ​​(attributeId)).)


For Each AttributeId As Guid In AttributeValues.Keys


   myCommand.CommandText = “lawfirm_AddOrUpdateDynamicValueForClient”


   myCommand.CommandType = Data.CommandType.StoredProcedure


   myCommand.Parameters.Clear()


   myCommand.Parameters.AddWithValue(“@ClientId”, Request.QueryString(“ID”))


   myCommand.Parameters.AddWithValue(“@AttributeId”, AttributeId)


   myCommand.Parameters.Add(AttributeValues(AttributeId))


   myCommand.ExecuteNonQuery()
Next 


Далі ви побачите збережену процедуру lawfirm_AddOrUpdateDynamicValueForClient. Вона дуже проста – в ній перевіряється існування запису для переданої пари ClientId і AttributeId. У разі якщо вона знайдена, то запис вже існує в табли

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*