Create Login in WPF, MVVM Pattern, C# and SQL Server - Step by Step + Display user data

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi in the previous video we created this login user interface in wpf now we will do the user authentication with c-sharp sql server and implement the mvvm pattern as i already mentioned in previous videos wpf better fits and takes full advantage of the mvvm pattern introducing quickly the mvvm pattern is made up of three components the model the view and the view model the model represents the domain objects that encapsulate data implement business logic services and data access at least generally speaking since these tasks are divided into layers such as the domain services and data access layer therefore the model would only represent the business entities and belongs to the domain layer while the view and the view model are part of the presentation layer however the layering depends on application complexity the view model provides the data and functionality for the view that is it exposes the data to the view and provides commands to control user interaction so this component will implement properties in property change notifications to update the value of the view elements in turn also implements the commands to execute tasks when a user performs an action for example when a button is clicked most wpf controls implement and support the i command interface and it will invoke the associated methods when the controls default action occurs in this case when the login button is clicked the user's authentication method will be executed finally the view is all the user interface elements such as windows pages user controls and resource dictionaries bindings are declared in the view that bind properties of the view to properties of the view model views should only be responsible for displaying the content of the view model and should be built with xaml only that is to say there should be no code in the views code behind except those that are the responsibility of the view for example move close minimize maximize the window or some animation effect as for the direction of dependency in this case it is only from left to right that is the view only knows the view model and the view model only knows the model but the model has no knowledge of the existence of the view model in the same way the view model has no knowledge of the existence of the view this separation is one of the key principles of the mvvm pattern well let's start with the tutorial we have a simple database a user table with the following fields a field for user id of type unique identifier then the username password names and email the username and email must have unique values and finally the data insertion of three users i'll leave the script download link in the video description well now let's move on to visual studio the previous video only did the design of the login view along with a brief introduction to wpf so i recommend you watch it if you are just starting to use wpf okay now to do the user authentication we will implement the models view models and data access let's start by adding the view models as i mentioned in the introduction to this tutorial the view models provide the data and functionality for each of the views for that purpose they need to implement property change notifications to update the value of the elements of the view and also implement commands to execute tasks when a user performs a certain action however doing that in each of the view models can be very tedious for this reason two main classes are usually added so that it can be used by all view models a base class that implements property change notifications and another class to execute the commands so let's first add the base class for the view models [Music] well we added reference to the component model assembly then we set the class to abstract so that it can only be used via inheritance then we implement the notify property changed interface this interface has a single event that notifies binding clients that a property value has changed and that you need to re-evaluate your values now we define a method to raise the event when a property has changed [Music] all right now we add another class to delegate the commands from the view to the view model usually this class is named relay command or delegate command but i will name it view model command simply for the sake of keeping a good nomenclature of names well we add reference to the windows input assembly and we implement the command interface [Music] now we define a field of type action to execute the commands the action delegate is used to encapsulate a method that is we can pass a method as a parameter then we define another field of type predicate to determine if the action can be executed or not this delegate allows the control to be enabled or disabled based on whether its command can be executed you will understand it better when we define the commands in the view model ok now we create the constructor with these fields we define another constructor with a single parameter to execute the action since not all commands have to be validated to determine if the action should be executed well in the can execute changed event we subscribe or unsubscribe the required suggested event as needed for this we use the command manager the require suggested event occurs when the command manager detects if the command execution condition has changed now we turn to the methods in the can execute method if the can execute action field is null we return true since the validation predicate has not been established otherwise we return the value of the delegate that is the method that is going to be defined and delegated in the view model finally in the execute method we simply execute the action in the same way this will execute the method that is going to be delegated to the view model alright that's it for this class now we will add a class for the login view model we set to public class and inherit the base class of the view model defined above well then we define properties to establish the binding between the view and the view model for this we first declare fields in this case the username password a field to display error messages and another field of type boolean to set if the view is visible since if the login is successful we will hide the view as default we set to true for the password we will use the secure string data type as this is a sensitive data type and we must keep it as safe as possible however microsoft no longer recommends using the secure string for your new projects because at some point it will be necessary to convert the content to plain text for example to do some kind of validation restore it in the database and from.net core the secure string content is no longer encrypted but in my opinion if you are using the.net framework i would still recommend using the secure string only for sensitive data access via keyboard since in wpf the password box control has a secure string property and that will cause the data is kept hidden in memory however that is just one more step because you still have to apply other security methods for example immediately encrypt the user's password once created and then store it in the database well let's continue we select these fields and generate the properties now every time a property value is set we must notify that the property value is changed that is generate an event for that we use the method previously created in the model view base class in the parameter we can write the name of the property or use the name of statement to get the name we do the same on every property in order not to send the name in each property we can use the color member name attribute in the base class method this attribute allows us to obtain the name of the property or method of the caller i do it this way so that the concepts of the mvvm pattern more understandable all right then we define properties of type command to execute the user's actions for example in this case a command to execute the user login we only define the get accessor the set accessor must be private and only the class itself should be able to initialize or set a value since it would make no sense for the view to initialize the action command so the principle of the mvvm pattern would be broken well and in this way we define the commands for interaction with the user and execute actions for example show the password characters recover or remember user password in the constructor we initialize the commands using the previously created view model command class so the login command will be equal to a new view model command type object the constructor of this class requires two parameters the first we must send a delegate to execute the login command and another delegate to check if the command can be executed that will allow the login button to be enabled or disable itself depending on the function that we implement in the method for example in this case the button will not execute the command until the username and password field have some value however that is optional since not all commands have to do some type of validation to be executed for that reason in the view models command class we create another constructor overload that only takes one parameter to execute the action for example the recover password command well these methods are the ones that are delegated to the commands and these object type parameters are optional we can define the method with no parameters or with parameters for example username and email it will throw an error because the structure of the default delegate method has changed as the method now requires two parameters to send these arguments we can either use the delegate statement or using lambda expression okay and this is how the commands are defined and initialized now we will implement the method of if the login command can be executed in this type of method is where we must do the corresponding validations before executing the command in this case as i mentioned before we will validate the data in the username and password field so if the username and password is null or has only blank spaces or the number of characters is less than 3 we indicate that the data is not valid so the command should not be executed since it would not make sense perform the user authentication query with empty data because obviously it would be a vein query otherwise if the data is valid the button will be enabled so you can execute the command on click all right that's all for now in a while we'll implement the execute login command method now the most fundamental part of the mvvm pattern is to establish the bindings between the properties of the view and the view model the bindings are declared in the view so we go to the login view first we add the reference to the view models component well now we need to set the view model as the views data context you can use the resources to create the view model i've seen many who do it but in my opinion the resources are used for other purposes i prefer to use data context since it is the correct thing and it has to do with the mvbm pattern but in the end it's everyone's preference this view model tag is just an alias you can put the name you want alright once the view model is established as the views data context we declare the bindings to bind the view properties to the view model properties the bindings are the engine of the mvvm pattern it's what maintains the view and the view model in context and in sync so the visibility property of the window will be bound to the is view visible property since if the login is successful we will hide the view in mode we set it to update both ways and here we need a converter since the is view visible property is of type boolean and the window visibility property is of type enumeration that is it can have one of three values so they are different data types which will then throw an error but there is a class that can convert a boolean to a visibility enumeration so on the window resources we instantiate the boolean to visibility converter class and put on any name we want finally we set the converter from the resources okay now we set the binding between the text of the username text box and the username property of the view model we do similarly for the password box however you cannot set the binding to the password property of the password box control since this for security reasons is not a dependency property so the only solution without violating the principles of the mvvm pattern is to create a custom control so select and copy the password box we defined in the previous video we added a folder to store the custom controls then we add a user control give it a name for example bindable password box we paste the code copied previously and remove the height and margin property since these properties have to be set from the view design when we add external resources to the user control like the image source in this case we need to set a stronger path so we need to set the assembly name at references in this case wpf login form and the semicolon component suffix which specifies that the referenced assembly is local well finally we set a name to the password box then in the code we need to create a new dependency property and thus declare the binding for the password field so for the password property we define a dependency property of type public static and read only then we define a new password property in data type we use secure string since in the view model the password property is of tight secure string in the get accessor we return the value of the dependency property defined above similarly in the set accessor we set the value to the dependency property all right now we need to register this property as a dependency property as the first parameter we send the name of the property that we want to register in this case the password property then we send the data type of the property in this case it is secure string finally we send the data type of the owner of the property which is the bindable password box well as a last step we need to set the value of the standard password box to the new password property for that we subscribe to the password changed event since it is raised every time the value of the control changes [Music] now in the view we replace the password box with the custom control we created we add the reference to the custom controls namespace and binding the user control's new password property to the viewmodel's password property okay now the same way we binding the login button to the view models login command the subscription to the click event is no longer necessary so we remove it and use the command property to bind the command to execute finally we binding the error message property of the view model for this we add a text block and we make the corresponding presentation settings [Music] [Music] all right that's it let's test if it works properly the button is correctly disabled when the text boxes have no data since we established that the command should always be executed when the username and password fields are not empty or have a minimum length of three characters you can do other types of validation so that the command can be executed this is just a basic example of how commands work well apparently my button doesn't get enabled despite needing the validation conditions here's the problem in case of text boxes you need to update the binding source every time the text box property changes the same goes for password boxes you need to update the binding source we can also establish that the data is updated in both directions and each time the property change event is generated great now the button is enabled when the fields have a value of at least three characters so you can continue to execute the login command well the functionality of the execute login command method has not been implemented yet also to check that the property bindings are okay you can add a value to each field for example if i set an initial value to the username field the corresponding text box should display the set value all right now let's implement the login command method but before that we need to implement the model and the data access object to perform the database query so in the models component we add a class for the user model we define the corresponding properties generally they are the same as the fields of the table in this case it doesn't make much sense to use the secure string data type for the password since at some point it will be necessary to convert it to plain text to perform validations or save it in the database however the password must be encrypted immediately after it is created okay now we add an interface to declare the user repository methods here we will have a boolean method for user authentication as parameters we define the user and password but since in the view and in the view model the password is of the secure string type i will use the network credential class since this class admits in the constructor a secure string password and it is possible to get the password in plain text okay so we continue to declare all public methods of user data access for example add edit delete get by id get by username or get all as i mentioned in the previous tutorial on the mvp pattern in windows forms the dependency inversion principle states that the details must depend on the abstractions in this case speaking in terms of architecture the data access layer should depend on the domain model but not the other way around so we define this abstract interface of the repository in the model and the data access layer will be the one to implement the detail this will allow loose coupling between the model and data access layer and the model is not dependent on data access the interfaces are used in most of the architecture and design patterns also to implement dependency injection i suggest you to watch the previous video tutorials of the mvp pattern in windows forms to understand better well on the other hand also remember that the models belong to the domain layer and the repositories to the data access layer however i will not implement the layered architecture in this tutorial since the video would be too long and it's not the topic of the tutorial maybe i'll do it another time so now i'll just add another folder for the repositories we add a base class for data access objects we reference the data sql client assembly and set the class to public and abstract so that the class can only be used via inheritance well here we just define the connection string and a method to get the connection to sql you can add other common properties and methods for repositories [Music] now we add another class for the user repository we inherit the base class and implement the user repository interface [Music] well finally we implement the user authentication method here we make the corresponding query to the database and return a boolean value if the user authentication is valid [Music] [Music] [Music] [Music] you can make two queries first if the username exists in case the query is unsuccessful generate an exception of user does not exist in the system otherwise continue to validate the password for the handling of validations and errors i would recommend using the exception pattern as i mentioned above the network credential class allows get the password as a secure string or a normal string as plain text sql server doesn't support secure string data type so we must compulsorily obtain the password as normal string well finally in the valid user field we execute the query if the result is equal to null we set the valid user field to false otherwise to true all right that's all we save the changes now we go back to the execute login command method of the view model we define a field for the user repository in the type we use the interface and initialize it in the constructor with the concrete class that implements the interface [Music] well we define a field and call the repositories user authentication method as a parameter we send an object of type network credential with the username and password now if the user is valid we are going to register and save the username and then retrieve and display the user data in the main view there are many ways to do this in this case i will use the current principal property of the thread class this property allows to establish the identity of the user executing the current thread so we instantiate the generic principal class the constructor of this class requires as parameters a class that implements the identity interface and an array of roles in this case i will use the generic identity class if you want you can create a custom class implementing the identity interface in roles i will send a null value since i will not do the handling of roles and user privileges okay finally we set the is view visible property to false since the login was successful and the view should be hidden otherwise if the user is invalid we set the error message for example invalid username or password as i mentioned before you can first validate if the user exists then validate the password thus providing a better user experience it uses the exception pattern to set the error message all right now we go to the app file to modify the start of the application we subscribe to the startup event but before we remove the start route set previously as it is no longer applicable in this case at least in my case because my login form is a separate window generally there is only one main view of type window the other views including the login view were created in user controls and are displayed in some container of the main window view that way it is easier to implement the pattern mvvm however i like to have the login layout completely different from the main window view which is why i created a separate window for the login although that would make it difficult to implement the mvvm pattern since we don't need to have code in the views code behind except those that are the views responsibility but the trick to not breaking the mvvm pattern principles was to define the is view visible property in the logins view model then we need to subscribe the visible changed event and it closed the login window if user authentication was successful and finally open the main view window so in code we define this event method and do the following [Music] we instantiate the login view we then show the view and subscribe to the is visible changed event [Music] now if the login view is not visible and it is loaded we instantiate the main view show it and finally close the login view if you want to have a method to log out you can subscribe to the main views close event and reopen the view on login [Music] well the logic here is simple the is visible event and property depend on the is view visible property of the login view model as this property is set to false if the user's login is valid and the property is binding to the visibility property of the window which will cause the visibility event to be raised when the view model property changes well let's execute the application to check great it works correctly well finally we will display the user data in the main view as in the login command we register the current user in the thread so we just retrieve the user data from the database and display it in some text block of the main view for that similar to everything above we define the model for the current user account we define the view model of the main window view then we bind the properties of the view with the properties of the view model and finally in the user repository we perform the query to obtain the data of the current user [Music] so [Music] [Music] [Music] [Music] [Music] [Music] [Music] do [Music] [Music] [Music] [Music] [Music] all right in the case of the password for security reasons it would be better to keep it as an empty string since the password is not usually displayed great the current user data is displayed correctly well apparently i have a little problem here here i wanted to apply some security if someone tries to directly open the main window without login it would show an error message then close the whole application however in wpf when setting the data context on the view it creates the view model instance at design time so the login is not performed which is why the message box is displayed and the design won't be generated so i'll make a little modification we display the message in the display name property and for security reasons we hide or disable the child views and we instantiate the user account property in the constructor [Music] well if we compile the project it should show the message of unauthenticated user since it is not logged in and with this we check that the view model is instantiated at design time alright that's all for this tutorial in the next video we'll design the main view and open the child views inside some container and navigation well until next time
Info
Channel: RJ Code Advance EN
Views: 54,502
Rating: undefined out of 5
Keywords: Windows Form, C#, VB, .NET, Software, HTML, Modern Forms, software, computer, technology, design of modern user interfaces, visual basic, php, java, design flat login, software development, web programming, information systems development, JavaScript, Visual Basic, Software Patterns, Architecture Patterns, Design Patterns, Language Patterns, Software Engineering, Systems, Web pages, mvc, layers, objects, POO, object-oriented programming, mysql, mariadb, .Net Framework, Custom Controls, SQL
Id: FGqj4q09NtA
Channel Id: undefined
Length: 36min 18sec (2178 seconds)
Published: Sun Jul 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.