c# – WPF MVVM – Simple login to an application – Stack Overflow

Wpf mvvm – simple login to an application

Вау, это был длинный вопрос!

Q1:
The process would work, I don’t know about using the LoginModel to talk to the MainWindowViewModel however.

You could try something like LoginView -> LoginViewModel -> [SecurityContextSingleton || LoginManagerSingleton] -> MainWindowView

Хотя некоторые считают синглтоны антипаттернами, я считаю, что в данных обстоятельствах они работают лучше всего. Это позволяет классу singleton реализовать интерфейс INotifyPropertyChanged и запускать события в ответ на обнаружение события выхода из системы.

Реализуйте команду LoginCommand на модели LoginViewModel или синглтоне, в зависимости от того, что вы предпочитаете (лично я, вероятно, сделал бы это на ViewModel, чтобы добавить некоторое разделение между ней и “внутренними” утилитарными классами). Для входа в систему эта команда будет вызывать метод на синглтоне.

Q2:
In these cases, I typically have (yet another) singleton class to act as the PageManager or ViewModelManager. This class is responsible for creating, disposing and holding references to the Top-level pages or the CurrentPage (in a single-page only situation).

Для того чтобы иметь возможность подключать события Loaded и Unloaded, мой класс ViewModelBase также имеет свойство, хранящее экземпляр UserControl, который в данный момент отображает мой класс. Наличие виртуальных методов OnLoaded(), OnDisplayed() и OnClosed(), которые могут быть определены во ViewModel, дает мне возможность загружать и выгружать содержимое страницы.

Когда экземпляр ViewModelManager. CurrentPage, который отображает MainWindowView, изменяется, срабатывает событие Unloaded, вызывается метод Dispose моей страницы, и в конечном итоге сборка мусора (GC) входит и убирает все остальное.

Q3:
I’m not sure if I understand this one, but hopefully you just mean “Display login page when user not logged in”, if this is the case, you could instruct your ViewModelToViewConverter to ignore any instructions when the user is not logged in (by checking the SecurityContext singleton) and instead only show the LoginView template, this is also helpful in cases where you want pages that only certain users have rights to see or use where you can check the security requirements before constructing the View, and replacing it with a security prompt.

Извините за столь длинный ответ; надеюсь, он был полезен.

Edit:
Also, you have misspelled “Management”


Редактировать комментарии для разъяснения

How would the LoginManagerSingleton talk directly to the
MainWindowView. Shouldn’t everything go through the
MainWindowViewModel so that there is no code behind on the
MainWindowView

Извините, я должен был выразиться яснее. Я не имею в виду, что LoginManager напрямую взаимодействует с MainWindowView (так как это должно быть просто представление), а скорее, что LoginManager просто устанавливает свойство CurrentUser в ответ на вызов, который делает LoginCommand, который в свою очередь поднимает событие PropertyChanged и MainWindowView (который слушает изменения) реагирует соответствующим образом.

Чтобы перенаправить пользователя на стандартный экран, который пользователи видят после входа в систему, LoginManager может вызвать PageManager. Open(new OverviewScreen()) (или PageManager. Open(“overview.screen”), если у вас реализован IOC).

По сути, LoginManager завершает процесс входа в систему, а представление просто отражает это по мере необходимости.

Кроме того, пока я это пишу, мне приходит в голову, что все это может содержаться в классе PageManager, а не в синглтоне LoginManager. Просто иметь метод Login(string, string), который при успешном входе в систему устанавливает CurrentUser.

В принципе, я могу понять концепцию PageManagerView через модель PageManagerViewModel.

MainWindowView может реагировать на изменение свойства CurrentPage, если PageManager является простым синглтоном, реализующим INotifyPropertyChanged. Я бы не стал проектировать PageManager по типу View-ViewModel.

У вас есть абстрактный класс ViewModelBase?

Да. Этот класс служит основой для всех моих видовых моделей.

Этот класс включает в себя

CurrentControl устанавливается в новый View при обнаружении вошедшего в систему пользователя.

Лично я бы сохранил только экземпляр ViewModelBase, который отображается в данный момент. Затем MainWindowView делает ссылку на него в ContentControl со следующим содержимым: Content=”Binding Source=x:Static vm:PageManager. Current, Path=CurrentPage”.

Я также использую конвертер, но это совершенно необязательно. Вы можете просто полагаться на записи ResourceDictionary. Однако использование этого метода также позволяет разработчику перехватить вызов и при необходимости отобразить SecurityPage или ErrorPage.

Then when the application starts it detects no one is logged in, and
thus creates a LoginView and sets that to be the CurrentControl.
Rather than harding it that the LoginView is displayed by default

Вы можете создать приложение с экземпляром экрана OverviewScreen в качестве первой страницы, которую видит пользователь. Тогда ViewModelToViewConverter перехватит это, поскольку PageManager в настоящее время имеет нулевое свойство CurrentUser, и вместо отображения пользовательского элемента OverviewScreenView отобразит пользовательский элемент LoginView.

Когда пользователь успешно войдет в систему, LoginViewModel даст команду PageManager перенаправить его на исходный экземпляр экрана OverviewScreen, который теперь будет отображаться правильно, поскольку свойство CurrentUser не является null.

Как люди преодолевают это ограничение, поскольку, как вы упоминаете, и другие согласны, одиночки нежелательны?

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


Edit 2:

Используете ли вы общедоступный фреймворк MVVM или набор классов?

Нет, я использую фреймворк, который я разработал и улучшил за последние девять-двенадцать месяцев. Этот фреймворк по-прежнему в основном придерживается рекомендаций MVVM, но в него также включены некоторые уникальные функции, которые уменьшают общий объем кода, который необходимо написать.

В некоторых примерах MVVM, например, представления настроены очень похоже на то, как у вас; однако представление создает новый экземпляр ViewModel внутри своего свойства ViewObject. DataContext. Кому-то это может показаться удобным, но это не позволяет разработчикам подключать определенные события Windows из ViewModel, например OnPageLoad().

В моем случае OnPageLoad() вызывается после того, как все элементы управления на странице созданы и видны на экране, что может произойти сразу, через некоторое время после вызова конструктора или вообще никогда. Например, когда страница имеет несколько дочерних страниц внутри вкладок, которые в данный момент не выбраны, я загружаю большую часть данных здесь, чтобы ускорить время загрузки страницы.

Кроме того, при построении ViewModel таким образом количество кода в каждом представлении увеличивается минимум на три строки. Это может показаться не очень много, но если в вашем приложении используется много представлений, дополнительное количество строк может быстро увеличиться, потому что эти строки кода не только одинаковы для всех представлений, но и создают дублирующий код. Кроме того, я невероятно ленив. Набирать код – это не то, ради чего я решил стать разработчиком.

What I will do in a future revision through your idea of a page
manager would be to have several views open at once like a tabcontrol,
where a page manager controls pagetabs instead of just a single
userControl. Then tabs can be selected by a separate view binded to
the page manager

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

Если вы храните их в свойстве ObservableCollection менеджера PageManager, все это

Не могли бы вы рассказать подробнее о ViewModelConverter?

Да, было бы проще показать вам код, чем давать конспект.

    public override object Convert(object value, SimpleConverterArguments args)
    {
        if (value == null)
            return null;

        ViewModelBase vm = value as ViewModelBase;

        if (vm != null && vm.PageTemplate != null)
            return vm.PageTemplate;

        System.Windows.Controls.UserControl template = GetTemplateFromObject(value);

        if (vm != null)
            vm.PageTemplate = template;

        if (template != null)
            template.DataContext = value;

        return template;
    }

Если этот кодекс разбить на разделы, то он гласит:

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

  • Различия между типами страниц, которыми являются. F

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

Как организовать авторизацию и аутентификацию в wpf приложении?

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

Идентификация должна существовать независимо от базы данных. Кроме того, речь идет не о безопасности, а о том, насколько легко можно управлять правами пользователей. Как вы можете предоставить доступ только к одной из сущностей, хранящихся в таблице, если их несколько? Если в базе данных нет соответствующей сущности, как получить к ней доступ?

Алгоритм входа пользователя в систему – это следующая тема. Пароль достаточно безопасен сам по себе. Пароль не должен храниться на серверах клиента или базы данных, поскольку они также уязвимы для взлома. Для этого существуют сервисы преобразования md5 в строку. Возможно, можно использовать более сложный алгоритм. Тем не менее, md5 также будет работать.

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

Похожее:  Токен Авторизации / Хабр

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *