Пользовательское поведение в веб-приложении - PullRequest
0 голосов
/ 18 февраля 2010

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

По сути, я ищу архитектурный подход к реализации пользовательского поведения в приложении ASP.NET WebForms. Есть ли лучший подход, чем разбрасывание операторов if / else по всей базе кода на уровне представления, бизнес-уровне и уровне постоянства?

Редактировать : Некоторые примеры:

  • Если пользователь в группе А, его навигация будет состоять из всего навигация из группы B плюс несколько дополнительные ссылки.

  • Если пользователь находится в группе А, страница будет показать пользовательские элементы управления c1, c2 и c3. Если пользователь находится в группе B, он будет см. только c1 и c3 на одной странице.

  • Если пользователь сохраняет некоторые данные в форме и они в группе А, отправьте уведомление по электронной почте. Если пользователь в группе B отправьте текстовое сообщение вместо этого.

Мы можем решить все эти конкретные проблемы, но ищем способ максимально полно инкапсулировать это поведение, чтобы оно не разбросано по базе кода.

Редактировать : Есть несколько интересных ответов, связанных с динамической загрузкой пользовательских элементов управления. Должна ли логика определять, какие элементы управления загружать или какое поведение использовать на основе группы пользователей, должна быть заключена в один (не связный) класс, например ::1010 *

GroupManager.GetNavigationControl(int groupId) // loads site nav control based on group
GroupManager.PerformNotification(int groupId) // sends text or email based on group

Или эта логика должна существовать как можно ближе к месту в коде, где она используется, и поэтому распространяться по различным уровням кодовой базы?

Ответы [ 4 ]

1 голос
/ 18 февраля 2010

Не вдаваясь в подробности и не вдаваясь в IoC и тому подобное, я думаю, что я бы оставил его довольно простым и имел бы простой старый фабричный класс, который вы бы использовали для возврата соответствующих экземпляров элементов пользовательского интерфейса [пользовательские элементы управления] на основе текущего пользователя, делающего запрос. При этом вы будете иметь все свои «если» заявления в одном месте. Чтобы обойтись без операторов 'if', вы можете просто создать файл конфигурации сопоставления или таблицу БД, содержащую ссылки на пользовательские элементы управления, которые будут использоваться, когда пользователь принадлежит к определенной группе.

Примечание. Обе эти опции приведут к созданию динамических элементов управления на странице, что не без собственных сложностей, но я уже некоторое время успешно использую динамические элементы управления в своих приложениях без проблем - это было просто вопросом из-за того, что я потерял жизненный цикл страницы больше, чем мне хотелось.

1 голос
/ 18 февраля 2010

Ну, здесь нет подробностей тонны , но я подозреваю, что вы могли бы извлечь выгоду из полиморфизма (то есть различных реализаций интерфейса), чтобы иметь дело с частями приложения, которые различаются между группами пользователей. Контейнер Inversion of Control, такой как Spring.NET , может помочь вам соединить / настроить эти различные реализации вместе на основе текущей роли пользователя. Вы также можете воспользоваться API-интерфейсом Spring Aspect Oriented Programming, в котором вы можете декорировать методы на своем бизнес-уровне / уровне доступа к данным, чтобы можно было выполнять логику авторизации.

1 голос
/ 18 февраля 2010

Под «группами» вы подразумеваете «роли»? Если вы говорите о ролях, вы можете настроить свое поведение, выполнив что-то вроде этого

If User.IsInRole("SomeRandomRole") Then
     'Do some random behavioral crap
ElseIF User.IsInRole("TheCoolRole") Then
     'Do some cool behavioral crap
Else
     'Do generic crap
End If

Другим вариантом может быть использование UserControls на основе ролей. Поэтому, когда вы загружаете страницу, она загружает пользовательский контроль на основе роли, которая его запросила.

вы могли бы оставить PlaceHolder пустым и вызвать метод LoadControl из кода.

Тогда все ваши элементы управления будут соответствовать вашим ролям

Role = Admin | UserControl = Admin.ascx
Роль = Пользователь | UserControl = User.ascx

0 голосов
/ 18 февраля 2010

Вы также можете наследовать от объекта Principal, чтобы справиться с этим, как вам бы хотелось.

Вот как я это сделал в приложении с такими правилами:

Создал мой собственный объект IPrincipal, который произошел от моего объекта Person, чтобы иметь возможность наследовать возможность поиска групп и ролей и тому подобное:

public class Principal : MyNamespace.Person, IPrincipal {
}

Заставить текущий контекст использовать мой объект IPrincipal:

protected void Application_AuthenticateRequest(Object Sender, EventArgs E) {
        if (HttpContext.Current.User != null &&
            HttpContext.Current.User.Identity.IsAuthenticated &&
            HttpContext.Current.User.Identity is FormsIdentity) {
                FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
                HttpContext.Current.User = new MyNamespace.Principal(id);
        } 
    }

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

public class CurrentUser {

        /// <summary>
        /// Is the current user authenticated
        /// </summary>
        static public bool IsAuthed {
            get { return System.Web.HttpContext.Current.User.Identity.IsAuthenticated; }
        }

        /// <summary>
        /// Returns the Principal object in case it is needed. Also used for other static properties of this class.
        /// </summary>
        static public MyNamespace.Principal User {
            get {
                return (MyNamespace.Principal)System.Web.HttpContext.Current.User;
            }
        }
}

Затем вы можете вызывать такие вещи, как CurrentUser.User.IsInGroup ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...