Тёмный

Getting User Data (Part 2) - A TimCo Retail Manager Video 

IAmTimCorey
Подписаться 415 тыс.
Просмотров 25 тыс.
50% 1

** TimCo source code now at: www.iamtimcorey.com/courses/b...
Full Courses: www.iamtimcorey.com
Mailing List: signup.iamtimcorey.com/
One-off tutorials are awesome but they aren't the only thing you should be doing to learn C#. Another vital part of learning is learning how to put it all together. This interactive course is all about putting the pieces together. You can watch each video on its own or you can watch them in order and see a bigger picture. The choice is yours.
This course focuses on real-world development. As such, we are simulating that we work for TimCo Enterprise Solutions on a brand new product, the TimCo Retail Manager. Just like in the real world, we are starting out with one set of requirements but know that over time they will change.

Опубликовано:

 

4 июл 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 221   
@nogo1880
@nogo1880 3 года назад
Part 1 and Part 2 of the "Getting User Data" videos have really broadened my understanding of C#, APIs and applications. Seeing these projects separated, the API calls being made, the queries to the database, objects being passed around and their methods being called, that's experience that I haven't gotten from any other course I've taken. At least not at this scale, where there are multiple projects involved, and so many factors to take into consideration. Even the debugging sessions have been super informative. Your videos are (from a learning standpoint) the best videos I've seen on RU-vid. I don't know how many times I will thank you throughout this playlist, but I will continue to do so regardless of how many times I've already said it. Thank you. Thank you. Thank you.
@tomthelestaff-iamtimcorey7597
@tomthelestaff-iamtimcorey7597 3 года назад
You are just the type person Tim is looking to help. Thanks for trusting him to help build your skills.
@mjaguilar923
@mjaguilar923 5 лет назад
Thank you for creating these vids. We may not be a numerous bunch viewing but we are certainly rooting for your success.soon this will be a reference for other newbs
@IAmTimCorey
@IAmTimCorey 5 лет назад
You are welcome.
@parko1965
@parko1965 4 года назад
This is not for newbs. Jumping in and out of errors in programming and correcting before concentrating on the subject. Very confusing.
@NickSteffen
@NickSteffen 2 года назад
Thanks! The Series is incredibly informative. Definitely looking forward to getting through the rest.
@IAmTimCorey
@IAmTimCorey 2 года назад
Thank you!
@rodrigo6459
@rodrigo6459 5 лет назад
WOW!!! this is getting a LOT MORE COMPLEX!, probably will have to watch this video twice to understand/digest all the information.
@IAmTimCorey
@IAmTimCorey 5 лет назад
Yup. It is drifting out of the nice, neat tutorial realm and into the "real world". The key is to make small changes, test often, and don't be afraid to step back and plan out a step if you aren't sure.
@jasonvonhaartman3325
@jasonvonhaartman3325 2 года назад
quote of the year "Make it public" .Love your style by the way.
@IAmTimCorey
@IAmTimCorey 2 года назад
Thanks!
@kdcurrin
@kdcurrin 4 года назад
How Is Tim Switching Between Files So Quickly? At 23:00 I got a little confused as to how Tim was navigating around so quickly. So for everyone else who doesn't know if you hold ctrl and click on an element it will take to straight to the definition. Alternatively, you can put your cursor inside the element and press F12. Hopefully, someone finds this useful :)
@IAmTimCorey
@IAmTimCorey 4 года назад
Yep, those are great options.
@dawidbiell
@dawidbiell 2 года назад
Great part of whole tutorial. I jump to next one :)
@IAmTimCorey
@IAmTimCorey 2 года назад
Great!
@harag9
@harag9 5 лет назад
Great episode Tim, thanks - took me 3 attempts to finish due to distractions, but finally got there this morning :)
@IAmTimCorey
@IAmTimCorey 5 лет назад
I'm glad you stuck with it.
@vartikagupta8816
@vartikagupta8816 3 года назад
The answer to my question in last video is the first thing in this video. Thanks for answering it Tim! :)
@tomthelestaff-iamtimcorey7597
@tomthelestaff-iamtimcorey7597 3 года назад
I think Tim can read minds. Have not proven it yet, but ...
@StudentCompanion
@StudentCompanion 5 лет назад
Great video and project. Thanks a lot and keep it up!
@IAmTimCorey
@IAmTimCorey 5 лет назад
Thanks! Will do.
@sc100200090
@sc100200090 4 года назад
Excellent Video!
@IAmTimCorey
@IAmTimCorey 4 года назад
Thanks!
@josmulder9597
@josmulder9597 4 года назад
Hi Tim, here a big fan. Compliments. With the issue regarding api/user in stead of /user I have fixed while the application was still running. This worked and I was very pleased with it. So you don't have to stop the application, make the fix and then start again.
@IAmTimCorey
@IAmTimCorey 4 года назад
Thanks for sharing
@jimlynch8313
@jimlynch8313 5 лет назад
Awesome job as always! I am learning a lot through this about building out an API as I build one for my job's data access. Just a few quick thoughts: @21:16 - AuthenticatedUser is still in the TRMDesktopUI.Models namespace (notice IAPIHelper's using statement for AuthenticatedUser). Nit-picky, I know. @29:00 - Yes, DefaultRequestHeaders.Clear() does clear everything under DefaultRequestHeaders, including Accept. @39:40 - You can Ctrl+. to get the option to 'Pull to interface' so you don't have to manually copy & paste into the file. Very handy! editted to remove answered question in video.
@IAmTimCorey
@IAmTimCorey 5 лет назад
Good catch on the using. I'll try to remember to remove that in the next video. Thanks for verifying the clear. I wasn't positive and didn't have the time to check. As for the one line assignment, yes I could but I don't prefer that method. It is harder to read. As for the Ctrl+., I didn't realize they added that. That's awesome! I'll have to remember that.
@S8Fii
@S8Fii 4 года назад
Watching this great tutorial so far, I'd recommend adding folders for the solutions, since they're becoming many and could get confusing to some. Solutions folders names as API, UI, Database etc would be great way to organise the project even more.
@IAmTimCorey
@IAmTimCorey 4 года назад
Wait for it... Wait for it... (they are coming in a future video...based upon user feedback). Good suggestion.
@devops_junkie9203
@devops_junkie9203 4 года назад
Great Job Tim, I almost got lost, I managed to get back in track. FYI I couldn't use the "token" from inside our APIHelpers, instead only from LoggedInUserModel. Either way, it works.
@IAmTimCorey
@IAmTimCorey 4 года назад
I am glad you got it to work.
@stefangulas
@stefangulas 4 года назад
Hi Tim, thanks for the great course, I am enjoying the journey. Two suggestions from my side: 1. one section that would help me in this journey would be a small overview of what we have done so far where we stand and what we will do in this video and what will be the next steps. Sometimes I get lost in the details and am not aware of what exactly we are doing and how it fits into the larger picture. 2.I would appreciate some kind of challenge, it should not be too hard, but it should make the users try to think through a small solution themselves. Ok that's it, keep up the great work!
@IAmTimCorey
@IAmTimCorey 4 года назад
Thanks for the suggestions! I'll keep them in mind.
@ArticcTrinax
@ArticcTrinax 5 лет назад
Love the series! As a great way to improve and teach. It would be a fantastic idea to add a tiny bonus tip in each video for "Did you know?" types of things. For instance where to add custom code snippets, or keyboard shotcuts that could speed up your coding. I know you have a couple of videos for tips & tricks, but this I feel like could help either remind or teach people watching your videos! :)
@IAmTimCorey
@IAmTimCorey 5 лет назад
I do try to call out tips when I use them but I'll see what I can do to be more intentional about it. Thanks for the suggestion.
@fraymansrandomthings993
@fraymansrandomthings993 4 года назад
We're starting to have a number of projects in the solution and they all start with TMRD, some 2 of them end in library.. it's hard to identify things quickly.. I would suggest adding solution folders to the solution to at least break the API from the front end. The solution folders don't affect namespace but are great for organizing groups of projects together.
@IAmTimCorey
@IAmTimCorey 4 года назад
Good suggestion. Since I'm heading out on a trip, I pre-recorded a few videos but I'll add that suggestion to the list. Hopefully I can add it in around the time we upgrade to .NET Core.
@SimoLPers
@SimoLPers 3 года назад
Hey Tim, great series! I've been seeing it the last week or so and it is great to see how all of this teaches so many things at once, even if it's just something "minor" like fixing typo mistakes. Now one thing I ask myself is, what would be a reason to have the separate calls for logging in and than a second call for getting user data? I mean, obviously to keep thing cleanly and structured it would make sense in some way... But why wouldn't someone call for a login request to the API and then with that call, get the user data back? Since, if your call returns a success response it'd probably mean already that the user was logged in successfully and you could then fetch the data from the response as well and you wouldn't have to keep track of two sperate models, but only the one user instance itself. I hope it makes sense :) Thx for all the great posts and hard work! Greetings from Germany
@scara1701
@scara1701 3 года назад
Hi Tim, thanks for this series. It's nice to see a programmers mind at work. I've started watching these to keep me company during the lonely lockdown home office hours. I've tagged along with my own hobby project using this as a reference. I did however start with Net 5, figuring things out myself which don't match the old 4.x Framework ways. One issue I had was the unability to access my user API with the token (401 - Unauthorized). The API is available on both http & https (via redirect), turns out that the issue only exists when I go to the API via http (I guess the token gets lost during the redirect?). I also passed the authorization header to the httpclient in a different way: _apiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);. Anyhow just wanted to share this info for others who might end up with similar issues.
@tomthelestaff-iamtimcorey7597
@tomthelestaff-iamtimcorey7597 3 года назад
Thanks for watching and sharing your experiences.
@girornsveinsson7970
@girornsveinsson7970 4 года назад
Thanks for a great video. I know that I am a whole year behind in this but I noticed a small thing that I thought was a bit weird. It looked to me as one of the using statements in the APIHelper refers to TRMDesktopUI.Models but it works anyway. I then realized that you forgot to change the namespace when you moved AuthenticatedUser.cs between projects.
@IAmTimCorey
@IAmTimCorey 4 года назад
Thanks for pointing it out. You haven't caught up to this point yet but in the future, we are using Azure Boards to track our bugs and features and we are assigning them to commits. I just entered this in as bug #29. When you get that far, you will see us fix this bug you submitted (it hasn't happened yet). Thanks for pointing it out.
@Wingloader
@Wingloader 2 года назад
Tim, I love you man. This is the best tutorial series on RU-vid. I am just became a Patreon supporter TODAY. I am late to the game with this series. Will I be able to download this solutions still? I read a comment in the previous video that the code was no longer available. I will be honest. I'm a lone ranger and I've been writing ASP.Net VB for 20 years. My code is horrible. I want to rewrite my web site in C# using your project as a template for "how you SHOULD do things". I know this is not a web project, but most of the framework you created here applies. Using your code as a starting point will mean I don't have to go back to vid 1 and write the code myself as you show on screen. Thanks for this. I've learned more from these videos than I could ever have learned trying to piece together a hundred how-to vids on specific items. I can't believe how awesome this series is.
@IAmTimCorey
@IAmTimCorey 2 года назад
The source code is no longer on Pateon because it is no longer an active series. However, you can still get the code by purchasing the course (it is currently broken up into three phases, although we will be joining it together at some point): www.iamtimcorey.com/courses?query=timco
@Wingloader
@Wingloader 2 года назад
@@IAmTimCorey Just enrolled. Thanks for the quick reply.
@muttBunch
@muttBunch Год назад
I'm going back watching all of these and I just accidentally happened to turn on closed captioning and I'm dying...at 26:51, it thinks Tim said "stepped on ourself our own TOAST" lol. :p
@IAmTimCorey
@IAmTimCorey Год назад
Gotta love auto-generated closed captions.
@muttBunch
@muttBunch Год назад
@@IAmTimCorey indeed. I left them on. If I find any other funny ones, I’ll time stamp them ❤️
@stealth1726
@stealth1726 5 лет назад
Hey Tim, great series, i was just wondering if there was an overview/preview/course introduction of the MVC add on for the tournament tracker series, just so i could see what would be achieved in the course as i am interested in seeing where we can take the design when using MVC, many thanks
@IAmTimCorey
@IAmTimCorey 5 лет назад
That is a high priority on my todo list but it isn't done yet. I talk you through it but I don't show you. Hopefully I'll get that together in the next few months.
@GMorgan84
@GMorgan84 2 года назад
Out of interest is there any reason not to have some kind of singleton LoggedInUserHolder class which just references the LoggedInUserModel? It would allow you to just assign the new user rather than do a prop by prop update. It'd also let you set up your events and property change notifications on that one central property. Whereas now you'll either trigger events on every property update, have to pick some kind of canonical property that triggers the events or manually call some kind of method to drive the events all of which would be error prone IMO.
@johanhansson2531
@johanhansson2531 3 года назад
Hi Tim! Thank you for the good job you do, you are very educational and explain everything slowly and well. I have a thought, the easiest and best way to build authentication into a WPF application, is it to create a web api that you have done in this series?
@IAmTimCorey
@IAmTimCorey 3 года назад
Have you viewed this video yet? - ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-_LdiqQ13NBo.html I think it will help you.
@johanhansson2531
@johanhansson2531 3 года назад
I have viewed that video and I think it was great, that was why im asking you if that it the best solulation :) Thank you for great videos!
@martinivanov5919
@martinivanov5919 4 года назад
Hello Tim, Thanks for the brilliant content you are putting on youtube! Great stuff! My question is about the naming conventions of class fields - is it not considered a bad practice to name fields, starting with an underscore? Now I understand that your point here might be not to use the "this" keyword in order to setup the properties for the relevant fields, but anyways when I've learnt naming conventions for C# the best practice states to name fields with camel case, the same as variables. Please let me know your opinion and does that naming come due to your experience as a developer ? Thanks in advance!
@IAmTimCorey
@IAmTimCorey 4 года назад
There are a couple times when the underscore is recommended. First is when it is a private backing field for a public property (full property). The second is when you bring in the value from an external location (such as dependency injection). Both indicate that you shouldn't write directly to that item or overwrite it.
@ericjansen613
@ericjansen613 3 года назад
Hi Tim, thanks for the great content. About copying all the properties from the LoggedInUserModel to the singleton object. Just my thoughts: isn't it more useful to create a Clone() function in the LoggedInUserModel that returns a new LoggedInUserModel? So things stay together and it's almost impossible to forget copying properties as you're in the model itself. public LoggedInUserModel Clone() { return new LoggedInUserModel { Id = this.Id, ... }; }
@seideldaniel
@seideldaniel 3 года назад
Hi Tim, your videos are great and really helpful. I'm just getting started and I'm also reading the book Clean Architecture by Robert C. Martin. In your solution the API Project uses an object (for example the user object) and the DesktopUI also uses a different user object. Where should I create the entities which build the domain of the whole project? They build the core and should be reusable in all projects. Should I create for example a TRMLibrary with all these entities or do I miss something?
@IAmTimCorey
@IAmTimCorey 3 года назад
You could create a project type like that (maybe a new class library), but I'm often leery of doing so. If both sides rely on a model type and then the UI needs to have some UI-specific logic in the model, you have a mess. I am cautious where I use that approach for that reason.
@alexn4217
@alexn4217 3 года назад
@IAMTimCorey, in this video your public async Task GetLoggedInUserInfo(string token) method in the APIHelper class doesn't seem to return anything yet it still works. I can only get mine working by returning the local _loggedInUser object. What am I missing? Thanks in advance!
@kmtchl2195
@kmtchl2195 3 года назад
Presumably it would be better to do .Single() vs .First()? We're only expecting one entry for that user ID, if there's more than 1 entry - something is wrong somewhere... .Single() would allow us to discover the issue and handle the exception accordingly? Interested on your perspective on this!
@IAmTimCorey
@IAmTimCorey 3 года назад
It depends on what you are looking for. First is slightly more efficient but Single will throw an exception if there is more than one.
@elchureee
@elchureee 4 года назад
When you move the API Helper to the library, you still use bootstrapper to get the resources you need for that class. But bootstrapper lives in DesktopUI. Wouldn't that be a dependency in the opposite direction?
@IAmTimCorey
@IAmTimCorey 4 года назад
Yep. You always have dependencies but we inverted the dependencies (Dependency Inversion Principle) and the UI tells the libraries which items to rely on instead of the libraries forcing the UI to use certain items.
@MikeRM2
@MikeRM2 4 года назад
Great series so far Tim. This could possibly be another video that you do at some other time. At around 8.00 minutes you mention that you could have done the TRMDataManager and Library as one solution and the TRMDesktopUI and Library as another solution. That leads me to wondering how would you join those two solutions together? If you made a change to the TMRDataManager solution and didn't need to make changes to the TRMDesktopUI solution how would you ensure that the TRMDesktopUI solution contains the newer version of the TRMDataManager solution?
@akashdeepsinha5325
@akashdeepsinha5325 4 года назад
DesktopUI solution doesn't really have any connection(no dll's are referred) to the DataManger project, all it does it uses the WebApi's exposed by the DataManager. If you want you can have an android application built using Java/Kotlin in a different IDE and still use the same Api exposed by DataManager. Thats the beauty of WebApi's. When i started watching this course, I got a little worried when I saw him creating the WPF project in the same solution. But later i realised why this was done. Also, the question you have is correct. WebApi(DataManager) and WPFClient(Desktop UI) do evolve separately when in production. I mean The UI changes much more frequently in real life. But as long as the endpoints(WebAPIs don't change, its okay). If the API does change, the client has to be separately upgraded to use the new APIs. But even then the legacy APIs are still kept intact.
@IAmTimCorey
@IAmTimCorey 4 года назад
I will add it to the list. Thanks for the suggestion.
@timothywestern6488
@timothywestern6488 5 лет назад
Good lesson. My question is this. do you feel this entire section was right for a single git commit? Or could we have broken down the steps a bit more? Sometimes I don't think its possible because of all the things you had to change.
@IAmTimCorey
@IAmTimCorey 5 лет назад
Each commit should be a full change. I do make larger commits in these videos simply for time's sake but you do need to be careful that you don't push part of a change as a commit.
@99MrX99
@99MrX99 5 лет назад
Great video as always. Wouldn't make it sense for UserModel in DataManager.Library and LoggedInUserModel in DesktopUI.Library to share an Interface together maybe in an TRM.Shared project? So you can make sure the names of the properties match and did not get changed only on one side.
@IAmTimCorey
@IAmTimCorey 5 лет назад
I get the idea but not really. The reason why is that then those two projects are tied together. If you update the interface, both projects have to update. Treat this like an API outside your control. Just like the other APIs we have worked with. We don't have interfaces for them. Besides, we might not want to capture every field. That's ok to do except when you have an interface enforcing implementation.
2 года назад
@@IAmTimCorey I get your point, but if I have both client and API side of project under control and I would like to do not forget to add property in UI or in API, is it OK to create shared interfaces only for fields which has to be in both models? say ISharedUserModel (FirstName, LastName, Email, ...) and implement this interface on APIModel and UIModel, and other props which I do not want to transfer will not be part of Interface?
@Alumanix
@Alumanix 2 года назад
Could we have used interfaces to help with the code duplication? I'm aware I'm late to the party here, lol. Just curios
@michaeleichner9797
@michaeleichner9797 4 года назад
There are two items that aren't quite bugs, but I believe they are not what you intended: 1. The class authenticatedUser.cs is in the wrong namespace. It is in the TRMDesktopUI.Models namespace instead of the TRMDesktopUI.Library.Models namespace which is where I think you intended to put it. 2. The call to apiClient.GetAsync("/api/User") in APIHelper executes the method GetById in the UserController. The GetById returns an instance of UserModel. After the call to apiClient.GetAsync("/api/User") there's a call to ReadAsAsync . I believe that ReadAsAsync should return an instance of UserModel because that's what was returned from GetById, but it instead returns an instance of LoggedInUserModel. Since the UserModel class and the LoggedInUserModel are virtually identical, this is more of a semantic issue than an actual bug/error. The one caveat is that in order to correct this you need the TRMDesktopUI.Library to refer to the TRMDataManager.Library which I am not sure you want to do because it ties the libraries together. Am I correct that we should change the namespace for issue number 1 and return the UserModel from ReadAsAsync for issue number 2? Thanks
@IAmTimCorey
@IAmTimCorey 4 года назад
Yep, the namespace issue is on the bug list to fix. As for number 2, no, I don't want to mix the two. I am acting as though I have no control over the API, which is the right way to proceed when creating an API. What the front-end calls the models and how it interacts with them will be different than the back-end. I call the front-end model LoggedInUserModel because it is descriptive of what the model represents: the logged in user and their information.
@michaeleichner9797
@michaeleichner9797 4 года назад
@@IAmTimCorey Thanks for getting back to me. I wasn't aware that there is a bug list. As far as the second issue: I understand why you did this. What confused me was how ReadAsAsync was able to map the response data from the UserModel object into a LoggedInUserModel object. I think I figured it out. The mapping from UserModel into a LoggedInUserModel object ONLY happens if the field names are identical in the UserModel and LoggedInUserModel. Field names that are spelled differently return a null. I have to assume that it uses reflection to do this. Hopefully this makes sense. Thanks
@jakobhendrix1753
@jakobhendrix1753 4 года назад
Would it be beneficial to refactor the user properties onto an interface shared between the frontend and backend? Is that valuable if it only serves to reduce the property duplication?
@IAmTimCorey
@IAmTimCorey 4 года назад
I don't think that will benefit our application development. If we did that, we would need to have a library that both the front-end and back-end depended on. Then, if we changed that library, it would force both parts to update. At that point, there isn't a need for the API. We should just make it one application. Besides, the UI models are (or can be) different than the back-end models even if they appear to be identical today. They serve different purposes. Good thought though.
@kevinstephenbiswas1477
@kevinstephenbiswas1477 3 года назад
I was surprised to see that TRMDesktopUI.Library APIHelper's constructor initializing ILoggedInUserModel using DI. I guess you don't need to explicitly use DI in each library and can figure out from singleton setups.
@IAmTimCorey
@IAmTimCorey 3 года назад
Correct, you do not need to set up DI in the class library but the class library can expect DI to be in place.
@kevinstephenbiswas1477
@kevinstephenbiswas1477 3 года назад
@@IAmTimCorey I have a question: Is the library class's for example TRMDataManager.Library will contain only data access related functions or is it going to contain other functions as well. If it does contain only Data access functionality wouldn't adding more library for different purposes would make the naming really confusing. Same thing for the TRMDesktopUI.Library
@williamwade8119
@williamwade8119 9 месяцев назад
I ran into an issue where the API call to /api/User returned a list, but it seemed that it returned a single object in this video. I just changed my code to handle the list and use the first object (in this case LoggedinUserModel) in the list if there were any. If I missed this in the video I apologize.
@GowthamNatarajanAI
@GowthamNatarajanAI 4 года назад
Where is a good place to write complex logic? The Backend library or the UI library? If we have to read data from DB and do some complex calculations before the result is shown in the UI, the server could just pass the raw data to the UI library which does the calculation or the server can do the calculation and pass just the result to the UI. Which is better?
@IAmTimCorey
@IAmTimCorey 4 года назад
It depends on what the "calculations" are. If they are UI-specific then the UI layer. Otherwise, move them down to the business logic layer (in the class library). Only UI-specific code should go in the UI.
@rhinoz9743
@rhinoz9743 5 лет назад
Firstly Tim, thanks for the great tutorial videos. Could you in a future video explain the system architecture, in particular the API calls. Currently we have two databases, one which we use to create accounts with and another for our retail management system (which also stores our logged in user). My problem with this architecture is that we authenticate the user through the cloud but we then have to call the TRM database to retrieve the authenticated user details. Ignoring we haven't as yet resolved how we will duplicate the account to our TRM database, should the web API access our TRM database at all? I logically would think these databases would be on separate servers and we shouldn't have a dependency across the two, due to security, etc. And if you do have time, I would like to here your opinion why you have used Entity Framework to create the Web API but use Dapper for TRM database?
@IAmTimCorey
@IAmTimCorey 5 лет назад
I'll try to answer your questions here. First, yes, the WebAPI needs access to both databases because it is only when a user is authenticated that we can then use that authentication to access the rest of the data. The authentication grants the user the rights to get the sensitive data in the main database. As for duplicating the account, it isn't really duplication. We are just using the UserId as the primary key for a table with more information about the user. We can still separate these two databases onto two servers if we want (not necessary but possible) and access them both from the API. As for using EF for the authentication system but Dapper for the main database, the reason is that I'm locked into EF for authentication. Pulling out EF and replacing it is a headache I don't need so I treat the authentication system like a plugin. I just use it. I use Dapper for the other database because it is faster at runtime than EF, it gives me more control over my database, and it can be more easily secured compared to EF.
@rhinoz9743
@rhinoz9743 5 лет назад
Thanks Tim. I'm probably getting a bit ahead of myself as I've been curious how we are going to implement the registration process. Hence when I look at the AspNetUsers table definition, my thought is why not include any additional columns here instead of our TRMData.User table (is it because we don't what to modify EntityFramework code?)?
@jinjie8682
@jinjie8682 5 лет назад
Hi Tim, just wondering for the model sharing. Why don't we have a single library class that supplies the most basic data (like UserModel), then the DesktopUI or TRMDataManager inherit on the class and add changes based on their needs? They having different purpose but they should also using the same model. So, we should can have the code sharing and also certain level of code separation.
@IAmTimCorey
@IAmTimCorey 5 лет назад
I disagree with the "they should also be using the same model" concept. These are two different models with two different purposes. Inheritance isn't about just code sharing. It is about a relationship. That's where people get in trouble with inheritance. "If it has wheels and an engine, they can share the same base class" and suddenly you have an airplane, a car, and a lawn tractor sharing a base class. That sounds fine until you realize you have totally different concepts of what the engine does, what a transmission looks like, and so on. Same thing here. Just because they look similar does not mean that they should be the same or inherit from the same base. If, down the road, I decide to ask for less properties from the API, I'd be stuck. I couldn't do it. That's a design problem.
@jinjie8682
@jinjie8682 5 лет назад
@@IAmTimCorey Oh okay, thanks tim! Now i understand more
@aminebenhebba1891
@aminebenhebba1891 3 года назад
Hi Tim, was the response intentionly mapped to LoggedInUserModel even if the API return a UserModel (just because the JSON mapper can resolve it since they have relativly the same properties by returning null on token) or was it just a little unseen bug. thank you for the series, realy enjoying it.
@IAmTimCorey
@IAmTimCorey 3 года назад
It was intentional because that is the model we wanted it in. That's the benefit of using JSON - you can put it into any class that matches.
@kreide847
@kreide847 3 года назад
Wouldn't it be also good to add the AuthenticatedUserModel as a singleton?
@IAmTimCorey
@IAmTimCorey 3 года назад
We don't want to create a singleton for the AuthenticatedUser because we want a clean, new instance each time. Plus, we aren't getting that model from dependency injection.
@dan_
@dan_ 4 года назад
Hey Tim, quick question about your decision (at 3:27) to change GetById() to return a single UserModel rather than a list of them. By requesting the ".First()" item in the list aren't we risking a crash if it comes back empty? We're assuming that the logged in Identity/User's Id exists in the register's Users table, which it feasibly might not. What would be the best way to protect against this eventuality, if you feel it's even worthwhile? Also, a huge thank you for this resource you've put together.
@dan_
@dan_ 4 года назад
Not sure if this is the right way to resolve this, but using .FirstOrDefault() instead of .First() returns null rather than causing an exception if the list is empty.
@IAmTimCorey
@IAmTimCorey 4 года назад
Good question. Yes, we are risking a crash. Yes, FirstOrDefault will give you null instead. The question is, do you want that? I decided I wanted the application to crash. The reason why is if the user is in the system but no record is returned for them, that is a major issue. It is one the application cannot resolve gracefully. Therefore, I want to crash the application rather than having it continue in a bad state.
@SuperDre74
@SuperDre74 4 года назад
@@IAmTimCorey As I also said in the previous comment, why have the original function give back a list of users at all as the Id is unique so GetById would never return more than one user, and I'd rather deal with a null than first having to check if there are any users in the list before getting the user. So IMHO the problem already exists in the original design.
@aardvarkify
@aardvarkify 4 года назад
~10:11 When you populate the LoggedInUserModel by copy/paste the UserModel properties. If you had an interface IUserModel in your Data Access Library, would it be okay to implement that into LoggedInUserModel and then add any additional properties as needed??
@IAmTimCorey
@IAmTimCorey 4 года назад
I didn't want to do that because the class is just properties and I needed to change all of them (decorate them, actually). An interface would require me to keep all of the properties, too, which might not be what I always want.
@vivekacharya3110
@vivekacharya3110 5 лет назад
Can you show web api punished to iis and consumer from the ui. Token api itself has failed when I tried.
@IAmTimCorey
@IAmTimCorey 5 лет назад
If you change databases, you will need to make sure the user is created in the new database before you can use it. I will be pushing this project to Azure at some point.
@NickSteffen
@NickSteffen 2 года назад
Might it be better to separate the Models that both the UI and API are using into a common model project. That way the data access is still independent of the UI but the models are still shared. The common model could be held within another object holding data that is specific to the UI. Or the UI model could inherit from the common model.
@IAmTimCorey
@IAmTimCorey 2 года назад
I tend not to do that because of a couple of reasons. First, it tends to make me lazy. If I have a common library, I avoid creating UI-specific models when I need them. I know I could inherit from them, but that's messy. I'm ok with a bit of duplication, especially since it keeps my UI-specific code in my UI. It doesn't wander into the shared library. Second, it reduces my complexity. If I have a shared library, I have an additional reference to maintain, an additional place to look for the code, and if I make a change in the shared library, I can affect two (or more) projects negatively. I know a lot of people use shared libraries (including Microsoft), but I have mostly stayed away from them for these reasons. These are just personal preferences, though.
@magnus7538
@magnus7538 4 года назад
Hi Tim, Great video as always! I have a question; In the GetLoggedInUserInfo method when you do the manual mapping of the result, would it not be possible to just assign result directly to "_loggedInUserModel" seeing that they have the same type? I seems to me like the mapping is unnecessary, or am I missing something?
@IAmTimCorey
@IAmTimCorey 4 года назад
The reason is that the _loggedInUserModel is a singleton from dependency injection. We can't overwrite it, we need to use that instance Therefore, we replace the values instead of changing the instance.
@magnus7538
@magnus7538 4 года назад
@@IAmTimCorey I see, I guess it was my unfamiliarity to Automapper that made me miss your explanation in the video. Thanks for taking the time to answer!
@GowthamNatarajanAI
@GowthamNatarajanAI 4 года назад
Here you pass a string as a parameter from the UI to the server to get the user details. But what if we had to pass an object as a parameter? The the object definition should be available in the UI library and the server library?
@IAmTimCorey
@IAmTimCorey 4 года назад
When you pass something through an API, it gets converted to JSON. So, you can pass objects but you have to have that object defined at both ends (but it isn't the same object, it just has the same properties).
@heyjonbray
@heyjonbray 4 года назад
@Gowtham Natarajan This is what the Newtonsoft.Json library does. I would highly recommend reading the documentation, as fully understanding the concept of objects as data structures and JSON as a representation of that structure's format is IMO a milestone in your knowledge of programming. It's an interesting and really intuitive library, especially compared to options for other languages (*cough* Java).
@neilljamieson9606
@neilljamieson9606 4 года назад
Hi Tim. At around 12:50 you speak about MVC and use the term Front-End Model. Is this the same as a ViewModel?
@IAmTimCorey
@IAmTimCorey 4 года назад
No, a ViewModel is roughly equivalent to a Controller in MVC. MVC stands for Model-View-Controller. The front-end model is the M in MVC. It is (potentially) different than the back-end model in that the front-end model may have decorators or other UI-specific items in it.
@neilljamieson9606
@neilljamieson9606 4 года назад
@@IAmTimCorey Hmm, so if the front-end model is the M in MVC, what is the back-end model? Apologies, but this is the first time I have heard the terms 'front-end model' and 'back-end model' used within the context of MVC.
@Campesguy
@Campesguy 2 года назад
@@neilljamieson9606 I think there might have been some confusion somewhere as I think they might have thought you were asking about the ViewModel in MVVM. In MVC, if you add a view model, it acts as another layer between the view and the domain model. You may not want to expose everything (ex. sensitive data) from your domain model back to the view, so that's where the view model would come in. So in that way it would be a front-end model. The back-end model, or domain model would be the M in MVC since those tie back to the database.
@bobcohen2761
@bobcohen2761 2 года назад
Hi Tim, really enjoying the series. I've hit a snag, when I run the solution, the web api opens in my browser. But the Login screen is not showing up. I don't see any issues in the debugger screen. Any suggestions on where to look to figure out why Login screen isn't showing?
@IAmTimCorey
@IAmTimCorey 2 года назад
It sounds like you don't have the WPF project set as startup as well as the API.
@timothywestern6488
@timothywestern6488 5 лет назад
When we didn't get the data (the false on GetAsync) I was still getting 404... it turned out I'd accidentally inserted a space between User and its / in that call. Is it better practice to not have the trailing slash when building an API?
@IAmTimCorey
@IAmTimCorey 5 лет назад
I don't know if there is a best practice on the trailing slash but spaces are definitely an issue.
@jeremymyhan780
@jeremymyhan780 4 года назад
In the APIHelper code this returns "true" and you're authorized... apiClient.DefaultRequestHeaders.Add("Authorization", $"Bearer { token }"); and this returns "false" and you're not... apiClient.DefaultRequestHeaders.Add("Authorization", $"Bearer{ token }"); in other words check the space between Bearer and token in your code.
@IAmTimCorey
@IAmTimCorey 4 года назад
Yep, that space is important.
@elchureee
@elchureee 4 года назад
As fas as I understand, Data, DataManager and its library would be the server, and DesktopUI and its library would be the clients if you implement this as 'server with multiple clients'. Am I right? Would you need to do adaptations to the code to make it work that way?
@elchureee
@elchureee 4 года назад
I mean in an intranet
@IAmTimCorey
@IAmTimCorey 4 года назад
The API project would be a server and it could serve multiple clients (the WPF project). We will actually set this up down the road. There is nothing you need to do in addition for this to work. If you wanted it to work across the Internet, you would just need to make sure your API project is deployed to an Internet-accessible spot (like an Azure Web App or a web host).
@danirdd92
@danirdd92 5 лет назад
This is gonna be an ongoing comment I'll edit as I watch: 1) I actually thought it's smarter to interface everything, return an IEnumarble and ditch the .First(). 2) Wouldn't it be better to extract an interface from UserModel for reuse in DesktopUI.Library? What are the dangers of sharing an interface across the projects? 3) Finding the right references manually is a major headache, praise the Ctr + . 4) * Points back at 2) with a grin *
@IAmTimCorey
@IAmTimCorey 5 лет назад
Here are my replies: 1) By returning First, we ensure we only return one login record (no need for a list or a possible issue of people misunderstanding). If we expect only one record, we should return only one record. 2) I discussed the dangers somewhat in the video. First, we don't want coupling between our front-end and our back-end. They are two separate projects and we want to treat them as such. Second, we don't want to expose the direct data access to the front-end. Otherwise, people could bypass the API. Third, and most importantly, the models are not the same. Yes, they look the same but they don't have to be. If we tie them to the same interface, we can't then change the UI model to fit the UI (less properties, more properties, etc.) 3) Yup 4) Points back to my answer.
@danirdd92
@danirdd92 5 лет назад
@@IAmTimCorey 1) Wouldn't IEnumerable imply a single enumerable dataset of the user model? and in the case of feature development into the feature would be more expendable? as explained in your SOLID Principles video. Or would that actually be more prone to errors if we use it that way? 2) So basically we are not extracting an interface because we want to make sure it's clear that the front and back end are not coupled together and should never be, we are eliminating the chance of use cases of polymorphism between the two projects by design
@IAmTimCorey
@IAmTimCorey 5 лет назад
1) IEnumerable means it can return zero or more UserModels. We are expecting only one. That would be unexpected behavior to get more than one. When you log in, you shouldn't get back two accounts. That leaves the decision of which one is "correct" in the hands of the UI and that's not secure. Besides, it should be impossible to get back two records. If we want to expand the data in our model, we can still do that without returning multiple. 2) There are two different things here. We aren't sharing an interface between UI and API for the reason I specified. We aren't extracting an interface because it typically is not beneficial to do so with a model. For everything else, we will extract interfaces to be used with Dependency Injection (which isn't in place in the API just yet).
@herculesstrydom5808
@herculesstrydom5808 4 года назад
Hey Tim, I am getting an "Internal Server Error" as my response from HttpResponseMessage response = await apiClient.GetAsync("/api/User"). I checked my spacing around the $"Bearer {token} and my spelling of Authorization. Any idea where the error could lie?
@IAmTimCorey
@IAmTimCorey 4 года назад
I'm not sure, sorry. Try some debugging. Maybe it is hitting the endpoint but having an issue?
@siddharthshinde4480
@siddharthshinde4480 3 года назад
I am not sure if you changed the namespace in AuthenticatedUser class from 'SRMDesktopUI.Models' to 'SRMDesktopUI.Library.Models'. Maybe that's more logical.
@IAmTimCorey
@IAmTimCorey 3 года назад
Yep, we change that later in the series.
@kreide847
@kreide847 3 года назад
Why did you map each property seperately and not just assigned the whole result to the _loggedInUser? (38:00)
@IAmTimCorey
@IAmTimCorey 3 года назад
Because I didn't want to replace the instance, I wanted to update the existing instance.
@vuquynhduong7953
@vuquynhduong7953 5 лет назад
Great video as always! I got the "Unauthorized" error! I used break point and it still can access and get the token for the login part, but then it could not access to get other information using that token (Noted that I used another url not my localhost)! What should I do Tim?
@IAmTimCorey
@IAmTimCorey 5 лет назад
Did you include the "bearer " in front of the token when passing it in? Did you pass it in as a header value? Have you tried from Postman to see if you can get it to work?
@vuquynhduong7953
@vuquynhduong7953 5 лет назад
@@IAmTimCorey Thanks a lot for your advice Tim. I did it! I forgot the space between Bearer and token ^^!
@vuquynhduong7953
@vuquynhduong7953 5 лет назад
@@IAmTimCorey I got another error Tim! Which telling that, they require a JSON object, so cannot paste the value into LogInUserModel
@Dame4Lyf3
@Dame4Lyf3 5 лет назад
Tim - Thanks for the content, I've been following along with the series, however, when I try to run the api I'm getting a "Parser Error", where it could not load type TRMDataManager.WebApiApplication There's a Source Error: Line 1: I've done the Googling and suggestions were to use Dapper.StrongName, or remove the Global.asax.cs file..I used the StrongName, and it worked, so there a big enough difference between Dapper and Dapper.StrongName?
@IAmTimCorey
@IAmTimCorey 5 лет назад
Something else is going on here. You should not need to change that and no, don't get rid of global.asax.cs. My guess is that you actually have a naming issue somewhere (casing is not correct somewhere).
@Dame4Lyf3
@Dame4Lyf3 5 лет назад
@@IAmTimCorey Sounds good thank you senpai 🙏🏽
@stevenbusenitz6330
@stevenbusenitz6330 4 года назад
First off, great video series! Being new to programming, this series has been very helpful!! I'm getting an error when I run the application at the end of this video above the username: "An error occurred while sending the request". I've been trying to figure this out for several days now and can't seem to find what I'm doing wrong. Any idea what I'm doing wrong??
@IAmTimCorey
@IAmTimCorey 4 года назад
So that error message isn't the "real" one. See if you can put a breakpoint to catch the error so you can see the inner exception. That message should show you the real error. That's the place to start.
@stevenbusenitz6330
@stevenbusenitz6330 4 года назад
@@IAmTimCorey Ok, I figured it out. So if anyone else has this problem...this might be an answer... I was getting errors from a couple different places all saying that they threw "an exception of type 'System.NullReferenceException'." ... i.e. "response.Content threw an exception of type 'System.NullReferenceException' ". By accident, while debugging, I saw that the API Project URL was different...for some reason...from the BaseAddress used in the APIHelper Class. When I changed it to the right port in the TRMDataManager Project properties and created a new Virtual Directory, that fixed the problem.
@zdaghost
@zdaghost 4 года назад
Hi @IAmTimCorey I was wondering how we can pass the current logged in users details to another Screen, I'm thinking along the lines of passing instance of ApiHelper to the second view ("Screen") and then retrieving current logged in user through that. But the problem I'm having is how do I find the current users token to pass in to GetLoggedInUser info method without having to re-authenticate the user post log-in? Any help would be much appreciated!
@IAmTimCorey
@IAmTimCorey 4 года назад
We captured the logged in user's data in a Singleton class, which means wherever we ask for that class, we will get the same instance, including all of the data we put in it.
@zdaghost
@zdaghost 4 года назад
@@IAmTimCorey Ah yes, I got it.. Nice one!
@elinatt
@elinatt 2 года назад
Hi, I'm a big fun of those courses. Thanks Tim! I followed up to this tutorial, but in a login form I got an error "an error ocurred while sending the request", actually I do not even know where to look up in a code right now, so much behind already. Tried debug this error, could not find it, where is the problem in my side. Maybe it's kinda typo error by me, or need to look somewhere else. Anyone please could help me.
@tomthelestaff-iamtimcorey7597
@tomthelestaff-iamtimcorey7597 2 года назад
I'm afraid I can't offer help but I can offer encouragement. Debugging is a critical skill to learn for every programmer. Learning to trace the data and logic flows is very useful. If possible, back out changes to the last time it worked, then add code , testing after each piece. Alternatively, review each step you recently added, one at a time, testing each one to see the impact. Testing ands debugging are must have tools.
@oleksiy4618
@oleksiy4618 2 года назад
It seems worrying that in the UI Library, we are importing stuff from UI (e.g. AuthenticatedUser), whereas in UI, we are importing stuff from UI Library (IAPIHelper). Isn't this a circular dependency, or am I missing something?
@oleksiy4618
@oleksiy4618 2 года назад
Oh, you actually talk about it at 20:05. Never mind!
@jeffsherman9638
@jeffsherman9638 3 месяца назад
I noticed a container is used in this section. How does this relate to containers you mentioned in your video regarding creating containers using Docker?
@IAmTimCorey
@IAmTimCorey 3 месяца назад
Can you provide me a timecode? I don't remember using containers in this series.
@jeffsherman9638
@jeffsherman9638 3 месяца назад
@@IAmTimCorey 36:20
@jeffsherman9638
@jeffsherman9638 3 месяца назад
@@IAmTimCorey I see _ container
@IAmTimCorey
@IAmTimCorey 3 месяца назад
That's something different. It is referencing a Dependency Injection container (the thing that holds all of our dependencies).
@ludovicwagner2656
@ludovicwagner2656 4 года назад
Hi Tim, I have to admit that using frameworks makes me confused. If I understand Calibrun.Micro, it helps to bring the different WPF parts together by relying on syntax convention. When I launch the app I get a null value for the _loggedInUser variable. The programme goes through the constructor, but I don't really understand what gives the loggedInUser value in the constructor. I believe it comes from the container of the dependency injection with .Singleton(). Could you please tell me a little bit more? I don't think I've missed any step.
@IAmTimCorey
@IAmTimCorey 4 года назад
Yes, this is dependency injection. It isn't really a Caliburn Micro issue at this point, it is just a DI issue. The DI system will give you an instance of LoggedInUserModel when you request an ILoggedInUserModel through the constructor. The code in your container should look like this: .Singleton() (that's a bit different than what you listed).
@ludovicwagner2656
@ludovicwagner2656 4 года назад
@@IAmTimCorey Thanks Tim for your explanation and sorry for my error. Nevertheless, I've just realised that: - result.Id = null and it is also null in swagger. - Event if I assign _loggedInUser.Id to a string, let's say "XXXX", it doesn't appear in swagger. - Id has a value in (localdb)\MSSQLocalDB\..\dbo.User. I'm not an IT developper (even if I hope to become one a day), but I'm pretty sure I'm missing something somewhere (I don't really know what separates the client to the server). Have you already encounter a similar issue? Thanks again :-)
@ludovicwagner2656
@ludovicwagner2656 4 года назад
Hello Tim, I'm sorry to bother you again, but I haven't found the issue regarding my last message yet. Do you have an idea what it comes from? Many thanks for your help!
@devops_junkie9203
@devops_junkie9203 4 года назад
@@ludovicwagner2656 I might be guessing but doesn't hurt to try, one of the things that work best for me in these cases is: rewind to where your code was working before, than, have the tutorial in a separate monitor/screen, and start comparing word for word against your project. in most cases, you will see that you are missing one word. I had an error just now with my LoginViewModel constructor after I extracted my APIHelper Interface.I took almost an hour debugging, and the error was consistent. Turns out I had to make my Interface class public. I hope this helps
@jitendrapanchal8699
@jitendrapanchal8699 3 года назад
@@ludovicwagner2656 Hi, I'm not sure if you were able to solve your issue for Id yet, but you can check the Select statement in the stored procedure which is returning the data, and add Id column in the select query. I hope this helps.
@Tahmasib13
@Tahmasib13 5 лет назад
Thanks for another great video. Just wondering how string api = ConfigurationManager.AppSettings["api"]; in TRMDesktopUI.Library.Api.APIHelper InitializeClient method gets value from app.config in TRMDesktopUI? These are different projects and appSetings not even exists in TRMDesktopUI.Library.
@IAmTimCorey
@IAmTimCorey 5 лет назад
A class library cannot be run. We run the user interface project and it uses the class library. Therefore, the class library uses the app.config of the project that runs it (the UI).
@Tahmasib13
@Tahmasib13 5 лет назад
@@IAmTimCorey Thx!
@djangounchained7314
@djangounchained7314 4 года назад
@@Tahmasib13 What was the answer here? I am having that error on my application "Error CS0103 The name 'ConfigurationManager' does not exist in the current context " and I just cant move from here!!
@djangounchained7314
@djangounchained7314 4 года назад
So what is the solution for this error ? "Error CS0103 The name 'ConfigurationManager' does not exist in the current context " I just cant move from here!!
@djangounchained7314
@djangounchained7314 4 года назад
found the problem ... little details .... daaaammnn!!
@onyebuchiboss
@onyebuchiboss 5 лет назад
Mine returns an error "Sequence contains no elements " at this Line - return data.GetUserById(userId).First(); in the UserController file, and a userId is returned still ?? Pls Help Tim!!
@IAmTimCorey
@IAmTimCorey 5 лет назад
It sounds like you don't have any records in the table. Remember that I added a row manually. Might want to check to see if you have that row added.
@onyebuchiboss
@onyebuchiboss 5 лет назад
@@IAmTimCorey Yes, this is the problem. sorted!. Thanks for responding swiftly Tim.
@francomuriuki3964
@francomuriuki3964 3 года назад
Why I'm i getting this error cannot deserialize the current JSON array (e.g. [1,2,3]) into type...?
@IAmTimCorey
@IAmTimCorey 3 года назад
It sounds like you are trying to deserialize it into an incorrect type. An array of [1,2,3] would deseriealize into a List or int[].
@francomuriuki3964
@francomuriuki3964 3 года назад
var jsonString = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject(jsonString); This one worked for me
@francomuriuki3964
@francomuriuki3964 3 года назад
The problem with this you are stack to one instance. Mapping is the problem
@michaelschannong3755
@michaelschannong3755 5 лет назад
hi tim. I'm writing right, I'm running into an error called. " The object reference is not set to an instance of an object" I get all my data but now I press continue. comes the message in text TextBlock x:Name="ErrorMassage". Is it a natural mistake or I have to look closely. One more question is the possibility of running it all together in Database instead of 2. totally delicious work you do. it teaches me a lot here in Denmark Sincerely Michael Schannong
@jimlynch8313
@jimlynch8313 5 лет назад
Is your TextBlock x:Name="ErrorMassage" vs. the property name ErrorMessage? Massage vs Message?
@IAmTimCorey
@IAmTimCorey 5 лет назад
The Object Reference is not set... message is because you are attempting to use a class that has not been instantiated. My guess is that in the API, you are trying to use a model without first instantiating it (= new ModelName()). That is why it is passing down that message. As for the database question, it is definitely possible to do this in one database. There are just a few issues with that. First, you cannot scan the database for changes and bring them into your project because it will bring in the EF changes. Second, it mixes your generated SQL with EF generated SQL. Not necessarily an issue but it makes for a messy structure where no one system has the complete design. I prefer not to mix my authentication db with my data db.
@michaelschannong3755
@michaelschannong3755 5 лет назад
@@jimlynch8313 yes spelling mistakes are dyslexic :)
@michaelschannong3755
@michaelschannong3755 5 лет назад
@@IAmTimCorey thanks i try to look through the error
@michaelschannong3755
@michaelschannong3755 5 лет назад
@@IAmTimCorey I found it was a logging ... that was not an interface thanks
@MrDdepass
@MrDdepass 4 года назад
why am I getting back "CreatedDate": "0001-01-01T00:00:00" getutcdate() but in the database I have 4/28/2020 1:18:09 AM (the correct one) above has January first year 1
@MrDdepass
@MrDdepass 4 года назад
Solved this. It was a difference between CreatedDate vs CreateDate. CreatedDate was defined in the model and CreateDate was on the Database so it was null from model and getutcdate() bring back 01/01/0001\
@IAmTimCorey
@IAmTimCorey 4 года назад
That would do it. Glad you figured it out.
@Vespyro
@Vespyro 4 года назад
@@MrDdepass Thank you for this, I also mislabelled my CreatedDate column and didn't find my mistake until I saw your comment!
@davidramirez3322
@davidramirez3322 Год назад
Someone got a "bad request" mess after giving the credentials?
@IAmTimCorey
@IAmTimCorey Год назад
If you don't pass the type as bearer token or if you use http instead of https or if you use GET instead of POST, it can happen.
@parko1965
@parko1965 4 года назад
Copy, paste, errors, correct, very confused now.
@IAmTimCorey
@IAmTimCorey 4 года назад
I'm not sure what you are saying.
@A-M-F-A
@A-M-F-A 5 лет назад
My AcessToken is getting null with status code 401 Unauthorized after updating api/user. Why it might be?
@IAmTimCorey
@IAmTimCorey 5 лет назад
Your access token expires/changes when you change your user. Best practice is to get a new one every time you start the application.
@A-M-F-A
@A-M-F-A 5 лет назад
@@IAmTimCorey I am referirng to when I click log in in form and in the debugger it shows null
@IAmTimCorey
@IAmTimCorey 5 лет назад
It sounds like maybe you named your property something slightly different and so the system is not matching it up to the passed in property name. It wouldn't be a casing issue but it could be that the property is a letter off.
@A-M-F-A
@A-M-F-A 5 лет назад
@@IAmTimCorey It's really weird because the letters are correct. I have: - PostAsync("/Token", data) - _loggedInUser.Token = token - GetLoggedInUserInfo(result.AcessToken) In AuthenticatedUser: - public string AcessToken { get; set; }
@IAmTimCorey
@IAmTimCorey 5 лет назад
You have the property AcessToken but it should be Access_Token (notice the two "c" characters and the underscore). That's your problem most likely. The system doesn't know how to map "access_token" to "AcessToken" because it is more than a casing difference.
@brocknoldy4464
@brocknoldy4464 4 года назад
While trying to use the login page, I get the following error. I've tried troubleshooting all morning and can't seem to get the login screen to work. This is the error I receive when I click the login button: {System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Did anyone else get this error?
@IAmTimCorey
@IAmTimCorey 4 года назад
It sounds like you need to trust your development SSL certificate.
@ArmedMob
@ArmedMob 4 года назад
In the event you are unable to add as a trusted ssl during startup of your project you will need to export your localhost cert and import it to the Trusted Root Cert Store... Had same issue!
@alexy.3512
@alexy.3512 4 года назад
And this is where I am going to disagree. The reason you have duplication, because your remote API infrastructure and your persistence are sprinkled with your domain. But great lesson anyway :)
@IAmTimCorey
@IAmTimCorey 4 года назад
Thanks for the comment. I appreciate the kind disagreement (I'm being serious, not sarcastic).
@alexy.3512
@alexy.3512 4 года назад
@@IAmTimCorey And, as many many others, appreciate your effort to put this together. This is awesome. Thank you!
@MGD320
@MGD320 3 года назад
why every video start with Zero Git Changes?
@IAmTimCorey
@IAmTimCorey 3 года назад
Because I don't change anything off-screen. At the end of every video, I commit the changes and then I don't change the project until the next time I am recording.
@MGD320
@MGD320 3 года назад
@@IAmTimCorey Not all videos include You do commit , that what i want to say , like the video prev to this.
@IAmTimCorey
@IAmTimCorey 3 года назад
Sure. I do commits off screen mostly because it doesn’t add anything of value to continually do so.
@MrBan001
@MrBan001 4 года назад
I'm getting the Exeption"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'RMDesktopUI.Library.Model.LoggedInUserModel' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1."
@MrBan001
@MrBan001 4 года назад
When i use the ReadAsStringAsync() function i see the correct data, but somehow i cannot map it to the object;
@MrBan001
@MrBan001 4 года назад
I litteraly have no idea how to debug this... its this line of code that doesnt work var result = await response.Content.ReadAsAsync(); But the LoggedInUserModel is correct.
@MrBan001
@MrBan001 4 года назад
Ok i figuered it out.... for some reason i have to make it a list var result = await response.Content.ReadAsAsync(); fo me its obvious now /api/User returns a List of UserModel... but why isnt't that for you the case?
@MrBan001
@MrBan001 4 года назад
OHHHHHHHHHHHHH SHIT I missed the beginning Thats a way of wasting an hour
@IAmTimCorey
@IAmTimCorey 4 года назад
I'm glad you figured it out.