You might not agree with everything Tim says or does (there are certainly things I would have done differently), but that doesn't change that this series is the best there is, for new programmers, learning how to build something from scratch. And the fact that Tim takes his time to discuss and explain his choices on some of the gray zone areas, makes it event greater. Once again, good job Tim!
I would highly recommend to anyone who is doing this course to go thru these two Videos by tim as a prerequisite : 1. WPF in C# with MVVM using Caliburn Micro 2. How To Call An API in C# - Examples, Best Practices, Memory Management, and Pitfalls
Really like your explanation and risk analysis on static code analysis (when copying and pasting from other sources) and the handling of cleartext passwords. I have often explained to others that e.g. the reason that a browser is a major target for malicious hackers, is the fact that it processes cleartext passwords in initiating authentication flows.
Hey, Tim. Thank you again for addressing all the concerns from the previous videos. Also, it's really great to see the pieces coming together and talking to each other. Thanks for the video!
I know Im randomly asking but does someone know a trick to log back into an instagram account? I was dumb forgot the account password. I appreciate any help you can give me.
@Jeremias Alexzander Thanks so much for your reply. I got to the site thru google and Im waiting for the hacking stuff now. Takes a while so I will get back to you later with my results.
In 39:00 didn't work and i lost one hour to find the issue with a couple of others. The issue was that i wrote new KeyValuePair("passworde", password), instead of new KeyValuePair("password", password), and getting Internal error. After i resolved the issue and continue th video Tim show me where was the error!!!!!! I lost 1 hour to find it because i paused the video at 39:00 Thank you Tim this was indeed a good practise and i am thankful because of this hour spend searching the issue :)
If you have an error 500: --Check for FormUriEncodedContent (if everything is spelled correctly: for example grant_type NOT grand_type). --Check if in .PostAsync("/, FormUriEncodedContent) your URI is spelled correctly and if it is a correct api.
YAY! thanks for that, was getting a "Bad request" result, scrolled through the comments here to see if anyone else was getting that, turns out I had done a similar typo over there as well! Thanks for pointing me in the right direction!
@@IAmTimCorey Perhaps we should set up a IAmTimCorey slack / discord as a centralized troubleshooting forum for everyone following along with your courses... As always thanks for the great content! I love your teaching style!
One suggestion that I think would make the videos much more enjoyable: if you could provide a list of recommended videos to watch before the present video, that would be awesome. For example, at 13:54 you mention one of these videos. On the previous video, I was lost on why you were doing some things, and at one of your replies to questions you mentioned a video on "WPF with Caliburn Micro" that was somewhat essential to improve the understanding of that video. You could provide such lists to all of your videos when applicable.
Hey Tim: at 27:13 - Regarding Content.ReadAsAsync(); - when you added the Microsoft.WebApi.Client - What did the NewSoft install (in my case - update) have to do with the resolution? ;-)
I think he did this just to bring it up to current. He also did this in the beginning of the Configuring Swagger in WebAPI video. ua-cam.com/video/zQRgB6nasUc/v-deo.html
Hey Tim, I have a small dumb question. if I put AccessToken instead of Access_Token in AuthenticatedUser Model I get Null value. I was just wondering why is this happening?
Double whammy for me. I accidently had AcccessToken (notice the 3 c's), then Acccess_Token, finally noticed the extra 'c'. Tim, love your videos, but it would be even more amazing if you pointed out these weird idiosyncrasies about naming conventions.
Another awesome video, Tim. Again, I've learned a lot from you. I have two questions : 1. Is there a specific reason to make the API call methods async ? 2. In SimpleContainer, if you want to have multiple instances instead of a singleton, would this code to the trick ? var instance = GetType().Assembly.GetTypes().Where(type => type.IsClass && type.Name == ("ModelName")); container.RegisterPerRequest((Type)instance, instance.ToString(), (Type)instance); Once again, thanks for everything you're teaching us.
Question: at 34:45 you added a private field _apiHelper of type IAPIHelper. I thought interfaces were used directly but instead used to create classes. Why wouldn't you use APIHelper as the type?
We aren't using the interface directly. We are asking dependency injection for the class that it has that fits the interface. That way, we can change the implementation centrally in dependency injection and it will change which concrete type the dependents get.
@@IAmTimCorey thanks. I just thought that since you implemented IAPIHelper in the class APIHelper you would have used that class to instantiate _apiHelper. Again, I am nit fluent AT ALL with interfaces.
Hello Tim, first of all thank you very much for all the wonderful tutorials. I am facing an issue with this current tutorial. when i implement the login function around 38:40, I can see the UserName and Password values in debugging, but cannot see the result value in the next step of debugging. When i mouse over result in the code body it shows the variable type info. and the login form pops back up and upon clicking the login button nothing happens. In the Locals window everything stays grayed out and result value shows null. I had SSL enabled and thought that could be an issue, so i disabled the SSL settings in the project properties and checked in postman and swagger with http// and i get a token. I tried to step through the codes but with my very limited debugging ability and understanding of code, I am at the moment truly stuck. Do not know what will be the next step. I know its been a while since this video was posted, but any help will be greatly appreciated. Thank you.
Hi Tim: Forgive this next question! I have always heard the OOP Principle, "Always implement to an interface". Today I have actually seen an example - where you take the APIHelper and extract an interface from it, so that APIHelper is implementing IAPIHelper, with just the one method. Can you please use THIS example and explain the benefits (or potential future benefits) of implementing it this way. I should KNOW this - as it is one of the most fundamental of principles, but it would be great to see it in action finally and understand why.
Well, there is one definite reason to have an interface here and another possible reason. The definite reason is because now you can test a class that depends on IAPIHelper without bringing in the "real" dependency of APIHelper. If we want to create a unit test that tests to see how a class responds to a specific response from the HttpClient, we can do so by mocking the APIHelper class. That way we don't actually connect to the real API and make real calls. We can make fake calls that test what happens in various scenarios. That is the definite reason to use the interface. The possible reason to use an interface is if we ever wanted to swap out the APIHelper library for a different one, we could do so by changing one line of code (which concrete class dependency injection returns when the interface is requested). This keeps the system more loosely coupled.
Found the error apiClient.BaseAddress = new Uri("api"); when it should be apiClient.BaseAddress = new Uri(api); that's why the internaluri error. Thanks Tim. amazing videos,
sooo.. at 38:45 i kept getting an null value for the username field.. spent about 2 hours changing around string names and stuff. turns out at the AuthenticatedUser class i had it as Email instead of UserName (why it failed due that i have no idea, because i have used Email this entire course so far) but changing it to UserName resolved the null value and now im getting the actual value. now i can finally continue :D
@26:05 you used var result = await response.Content.ReadAsAsync(); and then added a Nuget package (Microsoft.AspNet.WebApi.Client) to support this, but there is a function available: var result = await response.Content.ReadAsStringAsync(); AuthenticatedUser authenticatedUser = JsonConvert.DeserializeObject(result); which is in my perspective does the same thing with only Newtonsoft.Json package, so is it a good way to do it or not?
Hi Tim, thank you for your effort in this playlist. How would i do those operations in .net 6? In WPF project there aren't neither app.config and appsettings.json. Thanks in advance.
If you follow along in the .NET Framework, you will have a better experience. This course was designed to start with the .NET Framework so that you could learn it, and so that you could learn how to upgrade a real application to .NET Core and beyond.
Thanks Tim, this is a great tutorial series. What would we have to do to call the Login method when the user hits the Enter/Return key inside the PasswordBox?
Hi Tim, I am getting a Unknown build error, ‘Cannot resolve dependency to assembly ‘WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4’ because it has not been preloaded. When using the ReflectionOnlyAPI’s, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnly AssemblyResolve event. I am using Visual Studio 2019, does it have something to do with that?
@@uttamchaturvedi Hey Uttam, Having the same problem. I just rolled back to my previous version of the project. My version now is on par with the end of part 10 of this video series. I'm going to go through this section again and see if I can more easily find the problem, and I'll get back to you if I find anything.
Great information in this video. I'm learning more than just MVVM coding. You give tips and tricks which is wonderful. One point I’m struggling is the button click event handler. I need to figure out how Calibrun.Micro was able to attach that click event and not the other possible event for a button.
APIs allow you to be flexible in your application. You can add a different UI later, add a mobile application, or even communicate directly between systems without a visible UI. I recommend them for a lot of situation, even when those situations might not include a web-based UI.
Hi Tim, Thank you for the great video. I'm asking about the deployment when i use webapi inside my solution to work as desktop application ! , it will be hosted locally or what will be happened ? and how ?
You would deploy the two projects independently. You would deploy the API to a web server and then deploy the WPF to whatever location it needs to go to.
Watching the gears starting to work is awesome... i can't wait for more!!!! Thanks again Tim, this series is much appretiated!. By the way... i recieved an email from GitHub with this message: Known moderate severity security vulnerability detected in bootstrap >= 4.0.0, < 4.3.1 defined in packages.config. packages.config update suggested: bootstrap ~> 4.3.1. Should i upgrade bootstrap for the WepAPI?
Does it already have 4.0? I though mine still had 3.7. If you are on major version 4, yes, go ahead and upgrade to the latest 4 version. If you are on 3, upgrade to the latest 3 version.
Finally got around to watching this, great episode Tim and glad you did the "rant" in the first 10 mins - it really needed to be stressed I think. Regarding the .config files where you put the api url - I like to add "custom configs" to my projects as default because when you do an updated version of the app and send out an update, the .config is overwritten with the application "defaults" and if the user has already changed it they need to modify it again. So when I do the
This is amazing Tim,. You have away of making difficult concepts easy. I an just having a hard time getting to the videos in sequence. Is there a a good way to find the next sequential video?
Hello Tim. Thank you so much for your tutorials, they are the best! I have a question regarding the singletons for the IAPIHelper. Since we are using the singleton to make sure we always use this one instance of the APIHelper, what are the needs for using an interface and not the class directly since we are always going to use only one instance of it? Or is there going to be another APIHelper inheriting from IAPIHelper in the future?
By using an interface, we can change out that class later to a different class. Say we had an UpgradedAPIHelper that still implemented IAPIHelper. We could replace the class in the DI system once and upgrade our entire app. Also, we can replace that class when testing classes that depend on it.
wow great video as always, i went on creating a xamarin.form application to consume the authenticate api end point the moment we created the api. i really wondered why i was not able to see ReadAsAsync as one of the methods under the HttpClient and had to resort to deserialising the json result so i could get a hold of the bearer token. Now i know that i was missing a reference to aspnet.webapi.client :D
Rule of thumb: assume it should not be a singleton. Make yourself prove the need for a singleton before you use it. Singletons are used to persist data for the lifespan of an application. The danger is that they then bloat the memory footprint of an application.
hi tim Thanks before for the Great tutorial, can u point to me whats wrong with this? i get error with apiClient.BaseAddress = new Uri(""); * System.UriFormatException: 'Invalid URI: The URI is empty.'* from what i see, the base addres uri get the data from the app.config i have the value of my localhost there, can i point out what is wrong? thanks.
Why are you setting your base address to be a blank URL? If you don't have a base address, don't set it. It isn't pulling from the app.config file here.
Were you able to solve this? I am getting the same error. Edit: Fixed it. I also had this line by mistake: apiClient.BaseAddress = new Uri(""); It needs to be changed to: apiClient.BaseAddress = new Uri(api); where we are receiving api address from the app.config
Hi Tim, Enjoying this series thus far. I might be jumping ahead of future coverage, but this video got me thinking. With the call to the API, assuming shorter time-out, will you be refreshing the token each time after your connected? If the application is already running would you create a different function that handles the token refresh so connection don't get dropped. Thanks for your videos, these are keeping me employed 👍🏽
I get the token when I pass username and password from swagger UI. But I am getting bad request in response(await apiClient.PostAsync("/token", data)) I have removed [Authorize] attribute and made a Get request it works. Any idea? Please help me. Thanks
I had username and password parameter in the LogIn method, which were null when LogIn button is clicked. So context.UserName and Password were null, so user was always null. I have removed these parameters and user the properties. It works now :) Thanks
Hi Tim, I understand that the Password being stored in clear text is less important, as abusing it would imply higher security risks in other areas; still for the sake of learning, I was thinking of breaking the MVVM just a bit, for the password box and call an event every time it changed, like below: In XAML for PasswordBox: cal:Message.Attach="[Event PasswordChanged] = [Action PasswordChanged($source)]" and in the viewmodel have a global boolean: isPasswordEmpty and check for this boolean in CanLogin (along with username) with the PasswordChanged event calling the following method: // not sure if putting PasswordBox as parameter is less safe than // putting object and casting it as PasswordBoxpublic void PasswordChanged(object obj) { isPasswordEmpty = true; // in case of error when casting "obj" as PasswordBox if (obj is PasswordBox passBox) { isPasswordEmpty = string.IsNullOrWhiteSpace(passBox.Password); } NotifyOfPropertyChange(() => CanLogin); } Similary pass the password box for the Login method as well
Awesome video Tim! Some questions, once the app starts, is there only one instance of SimpleContainer created for the entire application? If multiple users start using the app and data traffic between the WPF form and API becomes high, can SimpleContainer handle the load? Or is there other method for those type of application?
Hi Tim, though I have just come across your tutorial but I have found it very helpful, thanks. I have I arrived at this point and did exactly shown on the this video. However, when I test the login with break point on var result and closing bracket. the First break point did show the same result as in the video, but when I hit continue after remove the break point it did nothing. Please advise! thanks
@@IAmTimCorey thanks. Got it resolved, It was the key value of grant_type which I mistakenly wrote it grand_type. It took me hours without realizing it. anyway thanks.
I used to when I was doing the deploys locally but now I use Azure DevOps to do the transforms in a similar manner (if .NET Framework) and .NET Core makes even that unnecessary in a lot of cases.
I'm getting an error about not being able to attach to the database file when using the API. This was working previously. Any idea of what could go wrong here?
Getting error when going back to Data Manager after working on Desktop UI. Made it startup and getting error "Could not load file or assembly 'Microsoft.VisualStudio.DesignTools.Extensibility, Version=16.10.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040). UPDATE: This error occurred because I used the latest version of Caliburn Micro. I had to use version 3.2.0 . What I don't understand is if I simply down rev to 3.2.0, the errors remain permanent. I had to rebuild the project from scratch using version 3.2.0 for it to work.
Hey Tim! Does SimpleContainer only inject into constructors? I tried setting up an _container.PerRequest and then using this in a method call and the type was always null. Is there another way to do dependency injection than this that I'm missing?
You wouldn't inject it in a method. You would do constructor injection or property injection. You can also create instances by calling the container directly (I do that in this course I believe).
@@IAmTimCorey Thanks for the reply! I tried it in a method to see if it was possible, but when it wasn't working Google failed me on the specifics of "why". This course has been fantastic by the way. I'm developing a CRM as a semester long project and decided... with only 5 weeks left to switch from WinForms to WPF. It's exposed a lot about my data library that was insufficient but with your examples I'm improving it vastly! Thanks again!
Hello Tim I follow all steps on your video.except for key="api" on app.config, I put my own url for "api" which works on postman. Also Program form loads if I removed .Singleton(); from Bootstrapper when I leave .Singleton(); My program builds succesfully. But nothing happens. It did not even load the the form to input username /password. on the output window I am getting Exception thrown: 'System.UriFormatException' in System.dll Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll Any idea?
Hi Tim thanks to you I have my first software developer job. Many thanks and keep up the good work. Do you have any courses about Reactive Extensions or are you planning to implenent it to this project?
Awesome! Congratulations! I'm glad I was able to help, although you were the one that put in the effort. Keep up the good work. As for Rx, no I don't have a video on them yet but it is on the suggestion list.
You mention not liking EntityFramework because it generates code in your application that you are then responsible for managing. Does that apply to CodeFirst EntityFramework? It seems to me that with the CodeFirst approach you are writing the code. Fairly new and not aware of all the alternatives to EF, but I have enjoyed using the CF approach to EF on several applications now.
I just did a course in the Foundation in C# course series on data access ( www.iamtimcorey.com/p/foundation-in-c-data-access ). In there, I did a lesson on Entity Framework (Code First). When you do code first, it generates a bunch of SQL code for you. Then, when you do LINQ statements to get data, it creates ad-hoc queries to get the data. You are responsible for knowing what the generated SQL is and knowing how to optimize it because EF Core is still not great at optimization. For instance, one of the big things people love about EF is that you can bring in relationships easily. So if I have a PersonModel that has a list of AddressModels and PhoneNumberModels inside it, I can just ask for the PersonModel and everything inside to be populated and EF will do that. However, the way it does that is that it queries the SQL database for all of the People joined with all of their matching addresses joined with all of their matching phone numbers. That may sound fine until you look at the results. The query will create one row for each person, address, phone number combination. So one person could generate 30+ rows with mostly duplicate data. If you asked for 100 people, you could be transferring thousands of rows across the network. Inside C#, EF will strip out the duplicates and present you with 100 models and you might never know that you transferred thousands of records. If you create your own queries using something like Dapper, you can make much better decisions which leads to much faster data processing. That is why Dapper can be an order of magnitude faster than EF. Now EF Core is a LOT more efficient than EF (the .NET Framework version) and EF Core is getting closer to Dapper in terms of speed in a lot of scenarios. However, EF Core is still something that takes a lot more SQL knowledge to maintain and do well. People often use it as an excuse to not know SQL, which is a big mistake.
you are generating token using granttype with password with login page if we wants to add or get some record with same than how to generate token with action controller
Hi Tim, 1. I still didn't understand why we really need the WebAPI project? 2. What is the responsibility of it in our solution? 3. Could we change it with a simple class library? 4. My problem with it is that it comes with a lot of code(IDK if we need it) and it gives us access to web user interface (IDK if we need it) while we are developing WPF user interface).
I will answer my questions:(But I would be glad to hear a short answers from you also) "Our initial project is we need to build a desktop app that runs a cash register handles inventory and manages the entire store". "In order to grow we will create a WebAPI layer" Because for now we want a desktop app but it makes sense that tomorrow our client would like to sell online, using WebAPI layer will help us to cover and achieve this new requirement fast. "The WebAPI layer is going to service a desktop, web and mobile application".
Yep, you answered your own question (well, I guess I did, but you found that part). Initially, setting up an API can be a bit of extra work. However, by doing so, we set ourselves up for the future, where we can be resilient in the face of change. To give you a picture of the future of this application, we will upgrade to .NET Core. Because this is broken apart as it is, we can upgrade each project one at a time instead of needing to do all at once. Next, we are going to upgrade our projects to .NET 5. The cool thing is that this is as far as the WPF project will go. It will not progress to .NET 6 (or at least, that is the plan). However, it will continue to operate just fine even as we upgrade our API to .NET 6 and beyond. After the .NET 5 upgrade, we will be adding at least one, but probably two different user interfaces (Blazor WebAssembly at least). They will use the same API. There will be some additions to the API, which the WPF application may benefit from as well, but the core calls will stay the same. If there is a bug in the API, we can fix it and the fix will benefit both user interfaces. After that, we will be utilizing microservices to make our API more powerful and more capable of handling growth. That won't affect our user interfaces at all. Finally, by using an API, we can safely deploy a WPF project to the end users without giving them access to a database connection string or other sensitive data.
What could be the reason that when I add the “using TRMDataManager.Models;” I am getting an error message CS0246. I have been following the course and typing the code. But when I added the AuthenticatedUser class and added the using, the error came up all of the sudden. I have try to go to previous sessions and try to find an error in typing or reference additions, but I have not found anything different to what has been done in the course. I even changed from VS 2019 to VS2017 to have the same environment in the course. But I have not been able to remedy the error message. Any Ideas? thank you very much.
Hi Tim, If I am building a ASP.Net MVC application and choose Individual authentication, register and token exchange everything would be handled. We don't have to write any of these code. Are we doing all these manually because we are creating a WPF application? Why did you not create API controller for getting token but used swagger? What other ways we can do this? Here we end up having 2 DB, Is this how it goes in real world as well? Thanks
ASP.NET MVC doesn't need to do this because it lives in the same context as the API. Everywhere else needs to do this, even MVC applications that are disconnected from their API. We have an API endpoint for getting the token. We are using Swagger to call that endpoint. We end up with 2 databases because I don't like to mix my authentication database with my "regular" database.
Ok Thanks Tim. I understand that Swaager is just a UI for our API. I checked Startup.Auth.cs here I can see the /Token endpoint. I think aspnet identity is doing all this for us.
Firstly, another fantastic video - Only subscribed recently and working my way through this course. Seriously easy to understand As easy as the tutorial is, I must've made a mistake and having re-watched this video cant find my problem. When entering the username & password, no AccessToken returned is 'Null', based on that result, any idea or guidance on where to look in order to continue this course? Thanks in advance
Hello Tim, is there a reason to stay away from UWP? I recently started to port my company's software from Win Forms to WPF and then I see UWP. As a developer it's getting hard to keep up with all of the 'new' paradigms.
Corporate moves a lot slower the larger it gets so having Windows 7 is not uncommon. In fact, there are still organizations I work with that have large installations of Windows XP (shudder). However, there is a larger reason why I stick with WPF: simplicity. What do you expect from UWP that is better than WPF? Unless you are planning to distribute the software through the store (which isn't a good idea with corporate software), I don't see a benefit. It is limited to Windows 10, unless you side-load the app, it isn't something you can distribute easily, and you are more restricted on what you can put in your application. UWP is mostly for if you want to have your app work on the XBox or if you want to distribute through the Windows Store.
In Corporate there is never the question to use UWP. Be Happy you can stick with WPF and propably will for a loooong time :) You stick to WPF for Windows or you go QT with C++. UWP Should never be an Option
Hey Tim, I'm finding your videos super insightful for real world scenarios. I'm wondering if you ever run into any kind of race condition concerns when using a singleton HttpClient for your entire application when using asynchronous API calls? Is there a scenario where the client is waiting for a response from a previous call when you try to initiate a new one, or maybe that you're getting a response from a different call?
Good question. Since it is a WPF application, it is a singleton per instance of the app. So no, that shouldn't be an issue unless we write some type of weird code to step on our own toes. Going forward, though, we might consider using the HttpClientFactory to manage our HttpClients more efficiently.
Hi Tim, Awesome project! Learning a lot. At some point in this particular video, when I choose the two projects as startup, I get Unknown build error, 'Cannot resolve dependency to assembly 'WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' I am using VS2019, and as you say in an earlier comment, it should work, but no luck so far.
It sounds like there is an old NuGet package or something similar causing an issue. Try doing a Rebuild (not just a Build) and then running it again. If that doesn't work, check out the NuGet packages and see if any need an update.
@@IAmTimCorey Thanks Tim. Turns out my version was not capturing some of the packages for updating. Had to manually update some packages depending on the build errors I was getting and after manually updating the rest, the build went on okay.
@@njogusamuel Hi, I am relatvely new to these lessons. I am getting the same issue (Sep 2020) . My packages (except Bootstrapper 3.X) all seem to be up to date through VS2019. Would you be kind enough to explain how you solved this in more detail please? Thank you!
@@MrDareDare Hi Dan, at the time, when trying to get updates through Nuget package manager, some packages were not being picked for updating. Try going through the logs on your error list, then looking up the versions of those packages on the package manager, and resolve them(i'm hoping they are not that many).
Solved it: The clue is in the error message! You need WebActivatorEx and Microsoft Owin installed as References for TRMDesktopUI using the NuGet Package Manager. These are dependencies that the compiler could not find.
Hi, Anthony! Make sure that you don't use camel case for access_token. The response body seems like: { "access_token": "", "token_type": "", "expires_in": , "userName": "", ".issued": "", ".expires": "" } Ensure that you use the right naming for the properties in your AuthenticatedUser class public string access_token { get; set; } public string userName { get; set; }
@@spolus I hat the same problem but the reason was that I accidently created the property Access_Token {get; private set;} -> with private setter it surely fails. Your solution is interesting. Tim did name it Access_Token and UserName. Same did I and it runs.
Hi Tim. I have tried to build the RetailManager. Until this video, no problems at all. My issue atm is getting valid result from postasync("/token", data). It returns a bad request 400. However the same command works fine from swagger. Any ideas?? The .net franework api uses now https and ssl cert. Maybe has something to do with it? Could you try it with ssl/https activated? Thx in advance!!
Hello Tim, I followed everything. Double checked that everything matched. And my login was returning null. Postman worked fine. After Debugging. I got an error that's says could not establish secure channel for ssl/tsl. Is there a way to fix this with Visual Studio? Thanks!
Are you using the https version of the URL? You should be. Also, try going to it with a web browser using https. Maybe you need to trust the certificate.
Hello Tim, ive been following this course for a while now and the amount of information is huge, im learning a lot because of it. I finished this part of the course, but somehow my APIHelper remains null when launching the login form. I tried to debug where it goes wrong, but cant seem to find the root of the problem. Can it be that i named something wrong so Caliburn isnt picking it up properly?
Yeah, it sounds like a naming issue. Either that or when you called it and did the Ctrl+. to add the using, you accidentally created a new class instead.
Hi Tim, thank you so much for these great tutorials. I am getting the ex.Message "Object reference not set to an instance of an object". I am using .NET Core / VS 2019 Community, and my code is identical to yours. Everything has been working perfectly before this step. I can't figure out what I am missing here!
That means that somewhere you did not instantiate a class. For example PersonModel p = new PersonModel(); You left off the "= new PersonModel()" somewhere (PersonModel being a stand-in for the class that it says is not instantiated. My guess is that I've got a List in a class that I instantiate in the class like so: List Demo { get; set; } = new List();
In Minute 22 you say that the good thing about .NET Core is that it uses HTTPS by default. to me it looks like .NET Framework also does that now. I paid special attention when creating the projects to use .NET Framework (as I knew we'll upgrade to .NET core eventually) and right now my program also uses HTTPS already, without any changed settings.
There is an option now upon template creation to use HTTPS. This isn't as robust as what is in .NET Core. As far as I know, there isn't an automatic redirection to HTTPS, it doesn't force HTTPS (just enables it for development), and it does not deal with HSTS. So yes, they did bring in more HTTPS support into the .NET Framework in later versions, but the HTTPS story in .NET Core is still much better because it is baked in by default, not an add-on.
Hi Tim, everytim I login I cant seem to see any response from HttpResponseMessage. Its seems like Im experiencing deadlock and I dont know exactly how can i fix it. I just did everything just how you do yours
Hi Tim, I already got the solution for this one. I thought it was deadlock causing me the issue, the issue is on SSL/TLS. I'm using a VS2019 and everytime you create a solution with Individual Authorization it automatically adds up the HTTPS. Anyway, thanks for your awesome videos will continue this course.
@@IAmTimCorey I really appreciate your videos and it helps me to expand my knowledge and force (in a good/positive way) me to know something I don't know.
@@markboylan9215 My solution was: In Solution Explorer, right click on WebApp project (TRMDataManager) and click Properties. Under the Web Tab, change Project URL from https to http. Save changes. Next, in App.config file, under , for key="api", change value from localhost to localhost. Save changes. After doing these changes I got response from HttpResponseMessage. Hope it helped! Good Luck!
Not sure if that's the problem but: Make sure to right-click on "References", click "Add Reference", a Dialog opens, click "Assemblies" on the left and then search for "System.Configuration" in the top right search bar.
You mean that the username and password you are trying to capture from the form are null? It sounds like you have a naming issue between your property and your TextBox.
@@IAmTimCorey No, at api side when i am post my username and password to generate token for user, (Token/Create) method receive username and password as null. With postman everything work fine.
Hi Tim, I'm watching some of your videos, and I see something here that really threw me. Specifically, it seems like you're able to call an async method synchronously. You have your LoginViewModel, which had an existing public void LogIn() method prior to this video. So that LogIn() method was called from somewhere in the code, synchronously. In this video you changed it to be an async method, so it could call asynchronously into your new IAPIHelper interface/class. I don't see where you showed the code calling the LogIn() method (at least, not in this video), but it doesn't appear that that code changed. How are you able to continue to call LogIn() synchronously, now that Lo9gIn() is an async method? Any time I ever tried to do that, Visual Studio gave me fits. I was finally able to find an approach today that compiles, though with a warning. I wrote a simple WinForms application (I was always a desktop developer). By having a button on the main form, which calls the async LogIn method in the viewmodel (synchronously), which in turn calls an async method in IAPIHelper interface, I'm able to build, but with "Warning CS4014 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.". Is this the same thing that you get in your project, but are safely able to ignore it because LogIn() is a command in a view model, and the call to LogIn() isn't followed by any additional lines of code? Over the years, I've attempted to find good ways to call async code synchronously, because I worked on a half million line project, and the solutions I found (on Stack Overflow and so on) were always bothersome to say the least. I'm just curious as to how you were able to do it without batting an eyelash!
The LogIn() method is now an async method. If you call an async method without awaiting it, you will not get the return data (or capture any exceptions). That's not a good thing. You can use the ".Result()" on an async method to call it synchronously but that typically isn't a wise idea because you are forcing something that should be async to run synchronously.
We haven't added them yet. This project is meant to be a real-world simulator. So, we started with .NET Framework so we could upgrade to .NET Core. We also started with no unit tests so that we could add unit tests to an existing project (something very few tutorials cover).
You can watch all of the videos in order if you use the playlist: ua-cam.com/video/Xtt6mS0p2_c/v-deo.html They are labeled as to what each of them does in case you want to watch just one specific one.
This is a really good video. Have wanted to implement a login in WPF. However, I just don't understand your reluctance to you using EF. I mean I understand but you also use a lot of 3rd party tools. I would think something coming from MS is also "peer reviewed". Ultimately, you are responsible for the software you create whether you rely on your own code, MS code, or 3rd party code. Again though, this was a very instructional video.
I have a video on EF best practices on this channel that covers more about EF and my reluctance to use it, especially when training others. The simple version is that EF takes a lot of skill to get right. It is easy to get it working, it is hard to get it right. That's the big problem. I have seen too many apps that work in development that then cause major problems in production (when it is too late to change). I prefer to use Dapper because it doesn't hide bad code. You are forced to write good SQL. Also, by writing your queries in SQL, it is much easier to improve them compared to ad hoc queries from EF.
@@IAmTimCorey thanks, Tim. Agreed that EF does make getting going easier, perhaps much easier. I suppose one could suffer from if you don’t know what you don’t know…
It compiles. It runs. It never never execs the code under the using(){}. It just goes back to the login screen. I have spent hours trying to figure out why the using(HttpResponseMessage response = await apiClient.PostAsync("/Token", data)) postman works, swagger works, during step thru in debug I cannot find the key-value pairs added during instance creation of FormUrlEncodedContent var 'data' variable. I've checked rewatched, rewritten, debugged, but cannot get it to work.
God I'm a dumbass, I've spent like half an hour trying to figure out why I'm getting 400 from api and the reason was I was typying in wrong password. Please kill me.
@@tomthelestaff-iamtimcorey7597 found you can use Trace.WriteLine() to log to the output so guess it is built into WPF already. Just failed to Google it properly
Great tut again Tim. I hate to say it, but I think this is where you lost me. I have understood everything that you've shown for the most part up until this video, but this all seems too advanced now. I need to go learn what some of these things do especially extract interface. Never seen that before
This is a more advanced course. We are using techniques I've covered in other videos so you should be able to find tutorials that will get you up to speed.
@@IAmTimCorey Oh yeah, I'd rather sit and look blankly at the screen for an hour and eventually figure it out then do a copy pasta! Shout out from the the Garbage Collectors Discord! Quite a few of us like your stuff. Even some of the experienced guys approve of you 🤣
_container .Singleton() .Singleton() .Singleton(); with this code shellview did not show in the screen and when I add a break point in shellviewmodel the run did not hit it but when i delete .Singleton() from the container it show up but the authentication did not work (normal) here a have to look in my code Please help
@@aymanawadallah6948 Hmmm. Already using the same versions but for Newtonsoft.Json, and I've rolled that back now and it didn't fix. I'll have to dig in :-)
Hi Tim i am receiving "An error ocurred while sending the request", + InnerException {"The underlying connection was closed: An unexpected error occurred on a receive."} System.Exception {System.Net.WebException} In this line here in APIHelpert, I do have the data but the response is null HttpResponseMessage response = await apiClient.PostAsync("/Token", data) In postman it works though
You might not agree with everything Tim says or does (there are certainly things I would have done differently), but that doesn't change that this series is the best there is, for new programmers, learning how to build something from scratch. And the fact that Tim takes his time to discuss and explain his choices on some of the gray zone areas, makes it event greater. Once again, good job Tim!
I appreciate the kind words. I'm also glad you are thinking through the things you would have done differently. Keep that up.
I would highly recommend to anyone who is doing this course to go thru these two Videos by tim as a prerequisite : 1. WPF in C# with MVVM using Caliburn Micro 2. How To Call An API in C# - Examples, Best Practices, Memory Management, and Pitfalls
Thanks for sharing.
I am waiting every second for your videos to come out Tim. I am very appreciated what you've done
I am glad you are enjoying the videos.
Excellent video as always Tim. The time you take to produce this series is very much appreciated!!
Thank you!
Really like your explanation and risk analysis on static code analysis (when copying and pasting from other sources) and the handling of cleartext passwords. I have often explained to others that e.g. the reason that a browser is a major target for malicious hackers, is the fact that it processes cleartext passwords in initiating authentication flows.
Thanks!
Hey, Tim. Thank you again for addressing all the concerns from the previous videos. Also, it's really great to see the pieces coming together and talking to each other. Thanks for the video!
You are most welcome. Thanks for watching.
I know Im randomly asking but does someone know a trick to log back into an instagram account?
I was dumb forgot the account password. I appreciate any help you can give me.
@Kenzo Kendrick Instablaster :)
@Jeremias Alexzander Thanks so much for your reply. I got to the site thru google and Im waiting for the hacking stuff now.
Takes a while so I will get back to you later with my results.
@Jeremias Alexzander It worked and I now got access to my account again. Im so happy!
Thanks so much you saved my ass :D
In 39:00 didn't work and i lost one hour to find the issue with a couple of others. The issue was that i wrote
new KeyValuePair("passworde", password),
instead of
new KeyValuePair("password", password),
and getting Internal error. After i resolved the issue and continue th video Tim show me where was the error!!!!!! I lost 1 hour to find it because i paused the video at 39:00
Thank you Tim this was indeed a good practise and i am thankful because of this hour spend searching the issue :)
I am glad you stuck with it and figured it out. Debugging gives you great experience.
there is *nameof* expression...
If you have an error 500:
--Check for FormUriEncodedContent (if everything is spelled correctly: for example grant_type NOT grand_type).
--Check if in .PostAsync("/, FormUriEncodedContent) your URI is spelled correctly and if it is a correct api.
Thanks for sharing.
YAY! thanks for that,
was getting a "Bad request" result, scrolled through the comments here to see if anyone else was getting that, turns out I had done a similar typo over there as well! Thanks for pointing me in the right direction!
@@IAmTimCorey Perhaps we should set up a IAmTimCorey slack / discord as a centralized troubleshooting forum for everyone following along with your courses...
As always thanks for the great content! I love your teaching style!
Hi Tim, Glad to see your new video in the series
thank you very much.
You are welcome.
Another great tutorial Tim. I think I understood it better because I saw your other video as a primary to WebApi and WCF.
Thanks!
22:16 I guess the few things they changed in VS2019 is they made project URL https for .netFramework.
They have made it a lot easier to develop and test with HTTPS.
One suggestion that I think would make the videos much more enjoyable: if you could provide a list of recommended videos to watch before the present video, that would be awesome. For example, at 13:54 you mention one of these videos. On the previous video, I was lost on why you were doing some things, and at one of your replies to questions you mentioned a video on "WPF with Caliburn Micro" that was somewhat essential to improve the understanding of that video. You could provide such lists to all of your videos when applicable.
Thanks for the suggestion.
I love hearing good tips and practices. As always, big fan.
Thank you!
Hey Tim: at 27:13 - Regarding Content.ReadAsAsync(); - when you added the Microsoft.WebApi.Client - What did the NewSoft install (in my case - update) have to do with the resolution? ;-)
I think he did this just to bring it up to current. He also did this in the beginning of the Configuring Swagger in WebAPI video. ua-cam.com/video/zQRgB6nasUc/v-deo.html
Nicholas is correct.
Hey Tim, I have a small dumb question. if I put AccessToken instead of Access_Token in AuthenticatedUser Model I get Null value. I was just wondering why is this happening?
Wow... so that was the problem I was having. I definitely did not expect that...
Double whammy for me. I accidently had AcccessToken (notice the 3 c's), then Acccess_Token, finally noticed the extra 'c'. Tim, love your videos, but it would be even more amazing if you pointed out these weird idiosyncrasies about naming conventions.
Thanks very much once again for all your hard work .... Like the way you reason through each design and development decision.
You are most welcome. Thanks for watching.
Another awesome video, Tim.
Again, I've learned a lot from you.
I have two questions :
1. Is there a specific reason to make the API call methods async ?
2. In SimpleContainer, if you want to have multiple instances instead of a singleton, would this code to the trick ?
var instance = GetType().Assembly.GetTypes().Where(type => type.IsClass && type.Name == ("ModelName"));
container.RegisterPerRequest((Type)instance, instance.ToString(), (Type)instance);
Once again, thanks for everything you're teaching us.
Hi Tim, Fantastic implementation of token authentication with swagger.
Thank you.
You are welcome.
Question: at 34:45 you added a private field _apiHelper of type IAPIHelper. I thought interfaces were used directly but instead used to create classes. Why wouldn't you use APIHelper as the type?
We aren't using the interface directly. We are asking dependency injection for the class that it has that fits the interface. That way, we can change the implementation centrally in dependency injection and it will change which concrete type the dependents get.
@@IAmTimCorey thanks. I just thought that since you implemented IAPIHelper in the class APIHelper you would have used that class to instantiate _apiHelper. Again, I am nit fluent AT ALL with interfaces.
Great job Tim, I liked the example of password security.
Thanks!
Hello Tim, first of all thank you very much for all the wonderful tutorials.
I am facing an issue with this current tutorial. when i implement the login function around 38:40, I can see the UserName and Password values in debugging, but cannot see the result value in the next step of debugging. When i mouse over result in the code body it shows the variable type info. and the login form pops back up and upon clicking the login button nothing happens. In the Locals window everything stays grayed out and result value shows null.
I had SSL enabled and thought that could be an issue, so i disabled the SSL settings in the project properties and checked in postman and swagger with http// and i get a token. I tried to step through the codes but with my very limited debugging ability and understanding of code, I am at the moment truly stuck. Do not know what will be the next step. I know its been a while since this video was posted, but any help will be greatly appreciated. Thank you.
Well I managed to find the problem. Got it all working.
@@tanzib82 I have the same problem how did you solve it?
@@tanzib82 could you please explain what you did? I am having the same problem and I am just banging my head against the wall
@@jasonm5995 hello, honestly I do not remember what I did. Ill look at the project again see if I can remember.
I just renamed "AccessToken" property inside the AuthenticateUser class to "access_token" and it worked.
Hi Tim: Forgive this next question! I have always heard the OOP Principle, "Always implement to an interface". Today I have actually seen an example - where you take the APIHelper and extract an interface from it, so that APIHelper is implementing IAPIHelper, with just the one method. Can you please use THIS example and explain the benefits (or potential future benefits) of implementing it this way. I should KNOW this - as it is one of the most fundamental of principles, but it would be great to see it in action finally and understand why.
Well, there is one definite reason to have an interface here and another possible reason. The definite reason is because now you can test a class that depends on IAPIHelper without bringing in the "real" dependency of APIHelper. If we want to create a unit test that tests to see how a class responds to a specific response from the HttpClient, we can do so by mocking the APIHelper class. That way we don't actually connect to the real API and make real calls. We can make fake calls that test what happens in various scenarios. That is the definite reason to use the interface.
The possible reason to use an interface is if we ever wanted to swap out the APIHelper library for a different one, we could do so by changing one line of code (which concrete class dependency injection returns when the interface is requested). This keeps the system more loosely coupled.
Thanks!
Thank you!
Found the error apiClient.BaseAddress = new Uri("api"); when it should be apiClient.BaseAddress = new Uri(api); that's why the internaluri error. Thanks Tim. amazing videos,
Glad you figured it out.
sooo.. at 38:45 i kept getting an null value for the username field.. spent about 2 hours changing around string names and stuff.
turns out at the AuthenticatedUser class i had it as Email instead of UserName (why it failed due that i have no idea, because i have used Email this entire course so far) but changing it to UserName resolved the null value and now im getting the actual value. now i can finally continue :D
Way to stick with it.
@26:05 you used
var result = await response.Content.ReadAsAsync();
and then added a Nuget package (Microsoft.AspNet.WebApi.Client) to support this, but there is a function available:
var result = await response.Content.ReadAsStringAsync();
AuthenticatedUser authenticatedUser = JsonConvert.DeserializeObject(result);
which is in my perspective does the same thing with only Newtonsoft.Json package, so is it a good way to do it or not?
It is a similar process. I'm not sure if there is a double convert in your method or not compared to mine. It would be interesting to investigate.
@@IAmTimCorey I'll let you know if I'll get the chance to play with it a little more 😎
Thanks a lot for your courses!
My pleasure!
Hi Tim, thank you for your effort in this playlist. How would i do those operations in .net 6? In WPF project there aren't neither app.config and appsettings.json. Thanks in advance.
If you follow along in the .NET Framework, you will have a better experience. This course was designed to start with the .NET Framework so that you could learn it, and so that you could learn how to upgrade a real application to .NET Core and beyond.
@@IAmTimCorey ok, thank you very much. Do you suggest a video for api configuration and authentication with net 6?
Thank you so much for your tutorials !!!
You are welcome.
13:56 you mention your other video 'consuming API', but i can't find it
I believe "How To Call An API in C# - Examples, Best Practices, Memory Management, and Pitfalls" is the video I was referencing
Thank you very much and waiting for next video
Great!
Thanks Tim, this is a great tutorial series. What would we have to do to call the Login method when the user hits the Enter/Return key inside the PasswordBox?
Just set up an event listener on the Password box to listen for the enter key event and then fire off the Login event when it happens.
Hi Tim,
I am getting a Unknown build error, ‘Cannot resolve dependency to assembly ‘WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4’ because it has not been preloaded. When using the ReflectionOnlyAPI’s, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnly AssemblyResolve event.
I am using Visual Studio 2019, does it have something to do with that?
This error occurred when trying to run both projects at the same time in the connecting the api video
Not sure. Maybe a bad version of a NuGet package? I'm using VS2019 so that shouldn't be a problem.
Hi did you get any solution?. I am ruuning out with same problem
@@uttamchaturvedi Hey Uttam,
Having the same problem. I just rolled back to my previous version of the project. My version now is on par with the end of part 10 of this video series. I'm going to go through this section again and see if I can more easily find the problem, and I'll get back to you if I find anything.
Great information in this video. I'm learning more than just MVVM coding. You give tips and tricks which is wonderful. One point I’m struggling is the button click event handler. I need to figure out how Calibrun.Micro was able to attach that click event and not the other possible event for a button.
Caliburn Micro uses the default of click for attaching the event. If you wanted a different event to fire, you would need to bind to it manually.
Merci beaucoup!!
I really would love to see an implementation of this using asp.net core.
That comes later in this series (we upgrade everything to .NET Core).
Wonderful demonstration!
Thank you!
Hi Tim, thank you for the nice video, if I am not going to have a web version of my application, is there still a reason to use API endpoints?
APIs allow you to be flexible in your application. You can add a different UI later, add a mobile application, or even communicate directly between systems without a visible UI. I recommend them for a lot of situation, even when those situations might not include a web-based UI.
really enjoy your life story. Do you know where I can find some dotnet tutorials, thanks
This channel has hundreds of videos on .NET.
Hi Tim, Thank you for the great video. I'm asking about the deployment when i use webapi inside my solution to work as desktop application ! , it will be hosted locally or what will be happened ? and how ?
You would deploy the two projects independently. You would deploy the API to a web server and then deploy the WPF to whatever location it needs to go to.
Hi Tim,
Why did you decide to put APIHelper in the UI Project? Isn't better to put it in deeper project?
Check out 12:25 and beyond. I explain why I put it there. In the future, we do move it to a class library that supports the UI.
How does the switching between Visible and Hidden work, w/o implementing the Converter class?
Is the converter part of Caliburn Micro?
Im wondering the same... Must have something to do with the "Can" keyword befor the name of the button
Yes, that is a part of CM. The Can keyword tells the system that it makes the control visible or invisible depending on the output.
Watching the gears starting to work is awesome... i can't wait for more!!!! Thanks again Tim, this series is much appretiated!. By the way... i recieved an email from GitHub with this message: Known moderate severity security vulnerability detected in bootstrap >= 4.0.0, < 4.3.1 defined in packages.config.
packages.config update suggested: bootstrap ~> 4.3.1.
Should i upgrade bootstrap for the WepAPI?
Does it already have 4.0? I though mine still had 3.7. If you are on major version 4, yes, go ahead and upgrade to the latest 4 version. If you are on 3, upgrade to the latest 3 version.
Finally got around to watching this, great episode Tim and glad you did the "rant" in the first 10 mins - it really needed to be stressed I think.
Regarding the .config files where you put the api url - I like to add "custom configs" to my projects as default because when you do an updated version of the app and send out an update, the .config is overwritten with the application "defaults" and if the user has already changed it they need to modify it again. So when I do the
Interesting take. Thanks for sharing.
This is amazing Tim,. You have away of making difficult concepts easy. I an just having a hard time getting to the videos in sequence. Is there a a good way to find the next sequential video?
Here you go: ua-cam.com/play/PLLWMQd6PeGY0bEMxObA6dtYXuJOGfxSPx.html
They are in a playlist on this channel.
Hello Tim. Thank you so much for your tutorials, they are the best!
I have a question regarding the singletons for the IAPIHelper. Since we are using the singleton to make sure we always use this one instance of the APIHelper, what are the needs for using an interface and not the class directly since we are always going to use only one instance of it?
Or is there going to be another APIHelper inheriting from IAPIHelper in the future?
By using an interface, we can change out that class later to a different class. Say we had an UpgradedAPIHelper that still implemented IAPIHelper. We could replace the class in the DI system once and upgrade our entire app. Also, we can replace that class when testing classes that depend on it.
@@IAmTimCorey Makes sense. Thank you!
wow great video as always, i went on creating a xamarin.form application to consume the authenticate api end point the moment we created the api. i really wondered why i was not able to see ReadAsAsync as one of the methods under the HttpClient and had to resort to deserialising the json result so i could get a hold of the bearer token. Now i know that i was missing a reference to aspnet.webapi.client :D
I'm glad that helped. It is a bit confusing.
Hi Tim, how can I know when a class should be used as singleton or not?
Rule of thumb: assume it should not be a singleton. Make yourself prove the need for a singleton before you use it. Singletons are used to persist data for the lifespan of an application. The danger is that they then bloat the memory footprint of an application.
I know I didn't miss anything but when did the swagger/ui/index discuss?
You mean in the Swagger video? ua-cam.com/video/zQRgB6nasUc/v-deo.html
hi tim
Thanks before for the Great tutorial, can u point to me whats wrong with this?
i get error with apiClient.BaseAddress = new Uri(""); * System.UriFormatException: 'Invalid URI: The URI is empty.'*
from what i see, the base addres uri get the data from the app.config i have the value of my localhost there, can i point out what is wrong?
thanks.
Why are you setting your base address to be a blank URL? If you don't have a base address, don't set it. It isn't pulling from the app.config file here.
Were you able to solve this? I am getting the same error.
Edit: Fixed it. I also had this line by mistake:
apiClient.BaseAddress = new Uri("");
It needs to be changed to:
apiClient.BaseAddress = new Uri(api);
where we are receiving api address from the app.config
Hi Tim,
Enjoying this series thus far. I might be jumping ahead of future coverage, but this video got me thinking.
With the call to the API, assuming shorter time-out, will you be refreshing the token each time after your connected?
If the application is already running would you create a different function that handles the token refresh so connection don't get dropped.
Thanks for your videos, these are keeping me employed 👍🏽
Awesome! We'll look into the token expiration in the future. Right now, the token is long-enough lived that it won't be an issue (it is days).
I get the token when I pass username and password from swagger UI. But I am getting bad request in response(await apiClient.PostAsync("/token", data)) I have removed [Authorize] attribute and made a Get request it works. Any idea? Please help me.
Thanks
I had username and password parameter in the LogIn method, which were null when LogIn button is clicked. So context.UserName and Password were null, so user was always null. I have removed these parameters and user the properties. It works now :)
Thanks
I am glad you figured it out.
@@vivekacharya3110 I have the same issue .
Thank you !!!
but in my case it null only password that send to Login method.
and it has explain in the previous video.
Hi Tim,
I understand that the Password being stored in clear text is less important, as abusing it would imply higher security risks in other areas; still for the sake of learning, I was thinking of breaking the MVVM just a bit, for the password box and call an event every time it changed, like below:
In XAML for PasswordBox:
cal:Message.Attach="[Event PasswordChanged] = [Action PasswordChanged($source)]"
and in the viewmodel have a global boolean: isPasswordEmpty and check for this boolean in CanLogin (along with username)
with the PasswordChanged event calling the following method:
// not sure if putting PasswordBox as parameter is less safe than
// putting object and casting it as PasswordBoxpublic
void PasswordChanged(object obj)
{
isPasswordEmpty = true;
// in case of error when casting "obj" as PasswordBox
if (obj is PasswordBox passBox)
{
isPasswordEmpty = string.IsNullOrWhiteSpace(passBox.Password);
}
NotifyOfPropertyChange(() => CanLogin);
}
Similary pass the password box for the Login method as well
I'm glad you were able to expand your knowledge and get this working.
Awesome video Tim! Some questions, once the app starts, is there only one instance of SimpleContainer created for the entire application? If multiple users start using the app and data traffic between the WPF form and API becomes high, can SimpleContainer handle the load? Or is there other method for those type of application?
One instance per instance of the application. Every user, when they open the WPF application, creates their own instance.
Figured out the issue. In the AIPHelper.cs I didn't change the string for the username and password from grant_type when I copied them.
I am glad you figured it out.
Hi Tim, though I have just come across your tutorial but I have found it very helpful, thanks.
I have I arrived at this point and did exactly shown on the this video.
However, when I test the login with break point on var result and closing bracket. the First break point did show the same result as in the video, but when I hit continue after remove the break point it did nothing.
Please advise! thanks
Not sure what is happening. Maybe step through the code from the first breakpoint.
@@IAmTimCorey thanks. Got it resolved, It was the key value of grant_type which I mistakenly wrote it grand_type. It took me hours without realizing it. anyway thanks.
@@joaocorreiafreitas712 I did the same 😂 Thanks for this hint ;)
Do you ever use SlowCheetah to override your config settings?
I used to when I was doing the deploys locally but now I use Azure DevOps to do the transforms in a similar manner (if .NET Framework) and .NET Core makes even that unnecessary in a lot of cases.
I am getting a 400 error when using the login window, even though the username and password are correct.
That grant_type will get you every time.
I'm getting an error about not being able to attach to the database file when using the API. This was working previously. Any idea of what could go wrong here?
Look at the changes you made inside and outside the app. Debugging and testing are critical skills to develop and this ia a great opportunity.
Getting error when going back to Data Manager after working on Desktop UI. Made it startup and getting error "Could not load file or assembly 'Microsoft.VisualStudio.DesignTools.Extensibility, Version=16.10.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
UPDATE: This error occurred because I used the latest version of Caliburn Micro. I had to use version 3.2.0 . What I don't understand is if I simply down rev to 3.2.0, the errors remain permanent. I had to rebuild the project from scratch using version 3.2.0 for it to work.
Hey Tim! Does SimpleContainer only inject into constructors? I tried setting up an _container.PerRequest and then using this in a method call and the type was always null. Is there another way to do dependency injection than this that I'm missing?
You wouldn't inject it in a method. You would do constructor injection or property injection. You can also create instances by calling the container directly (I do that in this course I believe).
@@IAmTimCorey Thanks for the reply! I tried it in a method to see if it was possible, but when it wasn't working Google failed me on the specifics of "why".
This course has been fantastic by the way. I'm developing a CRM as a semester long project and decided... with only 5 weeks left to switch from WinForms to WPF. It's exposed a lot about my data library that was insufficient but with your examples I'm improving it vastly! Thanks again!
Excellent! I'm so glad it has been helpful.
Hello Tim
I follow all steps on your video.except for key="api" on app.config, I put my own url for "api" which works on postman.
Also
Program form loads if I removed .Singleton(); from Bootstrapper
when I leave .Singleton();
My program builds succesfully. But nothing happens. It did not even load the the form to input
username /password.
on the output window I am getting
Exception thrown: 'System.UriFormatException' in System.dll
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
Any idea?
Hi Tim thanks to you I have my first software developer job. Many thanks and keep up the good work.
Do you have any courses about Reactive Extensions or are you planning to implenent it to this project?
Awesome! Congratulations! I'm glad I was able to help, although you were the one that put in the effort. Keep up the good work. As for Rx, no I don't have a video on them yet but it is on the suggestion list.
@@IAmTimCorey Thanks, I'm looking forward for your Rx videos, your explanation is far the best. Cheers. Have nice day.
You mention not liking EntityFramework because it generates code in your application that you are then responsible for managing. Does that apply to CodeFirst EntityFramework? It seems to me that with the CodeFirst approach you are writing the code. Fairly new and not aware of all the alternatives to EF, but I have enjoyed using the CF approach to EF on several applications now.
I just did a course in the Foundation in C# course series on data access ( www.iamtimcorey.com/p/foundation-in-c-data-access ). In there, I did a lesson on Entity Framework (Code First). When you do code first, it generates a bunch of SQL code for you. Then, when you do LINQ statements to get data, it creates ad-hoc queries to get the data. You are responsible for knowing what the generated SQL is and knowing how to optimize it because EF Core is still not great at optimization. For instance, one of the big things people love about EF is that you can bring in relationships easily. So if I have a PersonModel that has a list of AddressModels and PhoneNumberModels inside it, I can just ask for the PersonModel and everything inside to be populated and EF will do that. However, the way it does that is that it queries the SQL database for all of the People joined with all of their matching addresses joined with all of their matching phone numbers. That may sound fine until you look at the results. The query will create one row for each person, address, phone number combination. So one person could generate 30+ rows with mostly duplicate data. If you asked for 100 people, you could be transferring thousands of rows across the network. Inside C#, EF will strip out the duplicates and present you with 100 models and you might never know that you transferred thousands of records. If you create your own queries using something like Dapper, you can make much better decisions which leads to much faster data processing. That is why Dapper can be an order of magnitude faster than EF. Now EF Core is a LOT more efficient than EF (the .NET Framework version) and EF Core is getting closer to Dapper in terms of speed in a lot of scenarios. However, EF Core is still something that takes a lot more SQL knowledge to maintain and do well. People often use it as an excuse to not know SQL, which is a big mistake.
you are generating token using granttype with password with login page if we wants to add or get some record with same than how to generate token with action controller
Hi Tim,
1. I still didn't understand why we really need the WebAPI project?
2. What is the responsibility of it in our solution?
3. Could we change it with a simple class library?
4. My problem with it is that it comes with a lot of code(IDK if we need it) and it gives us access to web user interface (IDK if we need it) while we are developing WPF user interface).
I will answer my questions:(But I would be glad to hear a short answers from you also)
"Our initial project is we need to build a desktop app that runs a cash register handles inventory and manages the entire store".
"In order to grow we will create a WebAPI layer" Because for now we want a desktop app but it makes sense that tomorrow our client would like to sell online, using WebAPI layer will help us to cover and achieve this new requirement fast.
"The WebAPI layer is going to service a desktop, web and mobile application".
Yep, you answered your own question (well, I guess I did, but you found that part). Initially, setting up an API can be a bit of extra work. However, by doing so, we set ourselves up for the future, where we can be resilient in the face of change. To give you a picture of the future of this application, we will upgrade to .NET Core. Because this is broken apart as it is, we can upgrade each project one at a time instead of needing to do all at once. Next, we are going to upgrade our projects to .NET 5. The cool thing is that this is as far as the WPF project will go. It will not progress to .NET 6 (or at least, that is the plan). However, it will continue to operate just fine even as we upgrade our API to .NET 6 and beyond. After the .NET 5 upgrade, we will be adding at least one, but probably two different user interfaces (Blazor WebAssembly at least). They will use the same API. There will be some additions to the API, which the WPF application may benefit from as well, but the core calls will stay the same. If there is a bug in the API, we can fix it and the fix will benefit both user interfaces. After that, we will be utilizing microservices to make our API more powerful and more capable of handling growth. That won't affect our user interfaces at all. Finally, by using an API, we can safely deploy a WPF project to the end users without giving them access to a database connection string or other sensitive data.
@@IAmTimCorey Thanks Tim
What could be the reason that when I add the “using TRMDataManager.Models;” I am getting an error message CS0246. I have been following the course and typing the code. But when I added the AuthenticatedUser class and added the using, the error came up all of the sudden. I have try to go to previous sessions and try to find an error in typing or reference additions, but I have not found anything different to what has been done in the course. I even changed from VS 2019 to VS2017 to have the same environment in the course. But I have not been able to remedy the error message. Any Ideas?
thank you very much.
Sorry, never mind. I got it working now. Thanks.
I’m glad you figured it out.
Hi Tim,
If I am building a ASP.Net MVC application and choose Individual authentication, register and token exchange everything would be handled. We don't have to write any of these code.
Are we doing all these manually because we are creating a WPF application?
Why did you not create API controller for getting token but used swagger? What other ways we can do this? Here we end up having 2 DB, Is this how it goes in real world as well?
Thanks
ASP.NET MVC doesn't need to do this because it lives in the same context as the API. Everywhere else needs to do this, even MVC applications that are disconnected from their API.
We have an API endpoint for getting the token. We are using Swagger to call that endpoint.
We end up with 2 databases because I don't like to mix my authentication database with my "regular" database.
Ok Thanks Tim.
I understand that Swaager is just a UI for our API. I checked Startup.Auth.cs here I can see the /Token endpoint. I think aspnet identity is doing all this for us.
Firstly, another fantastic video - Only subscribed recently and working my way through this course. Seriously easy to understand
As easy as the tutorial is, I must've made a mistake and having re-watched this video cant find my problem.
When entering the username & password, no AccessToken returned is 'Null', based on that result, any idea or guidance on where to look in order to continue this course?
Thanks in advance
Hello Tim, is there a reason to stay away from UWP? I recently started to port my company's software from Win Forms to WPF and then I see UWP. As a developer it's getting hard to keep up with all of the 'new' paradigms.
Windows 7 is still strong and will be for the next 5+ years
@@DamianWalczak Almost all of my customers are running Windows 10.
Corporate moves a lot slower the larger it gets so having Windows 7 is not uncommon. In fact, there are still organizations I work with that have large installations of Windows XP (shudder). However, there is a larger reason why I stick with WPF: simplicity. What do you expect from UWP that is better than WPF? Unless you are planning to distribute the software through the store (which isn't a good idea with corporate software), I don't see a benefit. It is limited to Windows 10, unless you side-load the app, it isn't something you can distribute easily, and you are more restricted on what you can put in your application. UWP is mostly for if you want to have your app work on the XBox or if you want to distribute through the Windows Store.
@@seanmiller7889 "Almost"
In Corporate there is never the question to use UWP. Be Happy you can stick with WPF and propably will for a loooong time :)
You stick to WPF for Windows or you go QT with C++. UWP Should never be an Option
Hey Tim, I'm finding your videos super insightful for real world scenarios. I'm wondering if you ever run into any kind of race condition concerns when using a singleton HttpClient for your entire application when using asynchronous API calls? Is there a scenario where the client is waiting for a response from a previous call when you try to initiate a new one, or maybe that you're getting a response from a different call?
Good question. Since it is a WPF application, it is a singleton per instance of the app. So no, that shouldn't be an issue unless we write some type of weird code to step on our own toes. Going forward, though, we might consider using the HttpClientFactory to manage our HttpClients more efficiently.
Hi Tim,
Awesome project! Learning a lot.
At some point in this particular video, when I choose the two projects as startup, I get Unknown build error, 'Cannot resolve dependency to assembly 'WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' I am using VS2019, and as you say in an earlier comment, it should work, but no luck so far.
It sounds like there is an old NuGet package or something similar causing an issue. Try doing a Rebuild (not just a Build) and then running it again. If that doesn't work, check out the NuGet packages and see if any need an update.
@@IAmTimCorey Thanks Tim. Turns out my version was not capturing some of the packages for updating. Had to manually update some packages depending on the build errors I was getting and after manually updating the rest, the build went on okay.
@@njogusamuel Hi, I am relatvely new to these lessons. I am getting the same issue (Sep 2020) . My packages (except Bootstrapper 3.X) all seem to be up to date through VS2019. Would you be kind enough to explain how you solved this in more detail please? Thank you!
@@MrDareDare Hi Dan, at the time, when trying to get updates through Nuget package manager, some packages were not being picked for updating. Try going through the logs on your error list, then looking up the versions of those packages on the package manager, and resolve them(i'm hoping they are not that many).
Solved it: The clue is in the error message! You need WebActivatorEx and Microsoft Owin installed as References for TRMDesktopUI using the NuGet Package Manager. These are dependencies that the compiler could not find.
I just ran the app per your instructions in the above video and my Access Token kept showing up as null. Not sure why as of yet. Please advise.
I'm not sure. You will have to do some debugging. Something is different. Have you tried logging on using Postman to see if it gets the same result?
Hi, Anthony! Make sure that you don't use camel case for access_token.
The response body seems like:
{
"access_token": "",
"token_type": "",
"expires_in": ,
"userName": "",
".issued": "",
".expires": ""
}
Ensure that you use the right naming for the properties in your AuthenticatedUser class
public string access_token { get; set; }
public string userName { get; set; }
@@spolus Thanks, had the same issue and this solved it
@@spolus I hat the same problem but the reason was that I accidently created the property Access_Token {get; private set;} -> with private setter it surely fails.
Your solution is interesting. Tim did name it Access_Token and UserName. Same did I and it runs.
@Pavel Solomin You are a life saver thank you!!
Hi, When we know that authenticate is going to return a model and we know the type, why do we still use var?
It is quicker. That's about it. It is up to you if you prefer to see the full type or not.
@@IAmTimCorey Thank you!
You can only use var when you know the type anyway. Thats what it is for.
Hi Tim. I have tried to build the RetailManager. Until this video, no problems at all. My issue atm is getting valid result from postasync("/token", data). It returns a bad request 400. However the same command works fine from swagger. Any ideas?? The .net franework api uses now https and ssl cert. Maybe has something to do with it? Could you try it with ssl/https activated?
Thx in advance!!
I found something. The problem seems to be the password itself. It contains $ and that seems.to be the problem. The same password works via postman...
I'm glad you figured that out.
Hello Tim, I followed everything. Double checked that everything matched. And my login was returning null. Postman worked fine. After Debugging. I got an error that's says could not establish secure channel for ssl/tsl. Is there a way to fix this with Visual Studio? Thanks!
Are you using the https version of the URL? You should be. Also, try going to it with a web browser using https. Maybe you need to trust the certificate.
Hello Tim, ive been following this course for a while now and the amount of information is huge, im learning a lot because of it.
I finished this part of the course, but somehow my APIHelper remains null when launching the login form. I tried to debug where it goes wrong, but cant seem to find the root of the problem. Can it be that i named something wrong so Caliburn isnt picking it up properly?
Yeah, it sounds like a naming issue. Either that or when you called it and did the Ctrl+. to add the using, you accidentally created a new class instead.
Anyone getting an error on the LoginViewModel constructor:: Inconsistent accessibility: parameter type 'type' is less accessible than method 'method'?
Found this issue. I had to make the interface public.
Good catch.
Hi Tim, thank you so much for these great tutorials. I am getting the ex.Message "Object reference not set to an instance of an object". I am using .NET Core / VS 2019 Community, and my code is identical to yours. Everything has been working perfectly before this step. I can't figure out what I am missing here!
That means that somewhere you did not instantiate a class. For example PersonModel p = new PersonModel(); You left off the "= new PersonModel()" somewhere (PersonModel being a stand-in for the class that it says is not instantiated. My guess is that I've got a List in a class that I instantiate in the class like so:
List Demo { get; set; } = new List();
Why we didn't inject dependency here: apiClient = new HttpClient();?
We probably should have. In looking at it, I don't see a reason why we didn't.
In Minute 22 you say that the good thing about .NET Core is that it uses HTTPS by default.
to me it looks like .NET Framework also does that now.
I paid special attention when creating the projects to use .NET Framework (as I knew we'll upgrade to .NET core eventually) and right now my program also uses HTTPS already, without any changed settings.
There is an option now upon template creation to use HTTPS. This isn't as robust as what is in .NET Core. As far as I know, there isn't an automatic redirection to HTTPS, it doesn't force HTTPS (just enables it for development), and it does not deal with HSTS. So yes, they did bring in more HTTPS support into the .NET Framework in later versions, but the HTTPS story in .NET Core is still much better because it is baked in by default, not an add-on.
@@IAmTimCorey I hadn't noticed the option when creating the project. Thanks for the explanation!
Hi Tim, everytim I login I cant seem to see any response from HttpResponseMessage. Its seems like Im experiencing deadlock and I dont know exactly how can i fix it. I just did everything just how you do yours
Hi Tim, I already got the solution for this one. I thought it was deadlock causing me the issue, the issue is on SSL/TLS. I'm using a VS2019 and everytime you create a solution with Individual Authorization it automatically adds up the HTTPS. Anyway, thanks for your awesome videos will continue this course.
Glad you got it figured out.
@@IAmTimCorey I really appreciate your videos and it helps me to expand my knowledge and force (in a good/positive way) me to know something I don't know.
Hi Julius, how did you manage to solve the issue?
Thanks
Mark
@@markboylan9215 My solution was:
In Solution Explorer, right click on WebApp project (TRMDataManager) and click Properties. Under the Web Tab, change Project URL from https to http. Save changes.
Next, in App.config file, under , for key="api", change value from localhost to localhost. Save changes.
After doing these changes I got response from HttpResponseMessage.
Hope it helped! Good Luck!
In Authenticate Method it never hit the if Statement and respone always Null.... --> It was SSL i disable https in project prop
cant find system.configuration in properties :( pls help tim
Not sure if that's the problem but:
Make sure to right-click on "References", click "Add Reference", a Dialog opens, click "Assemblies" on the left and then search for "System.Configuration" in the top right search bar.
Hey Tim, i am receiving username and password as null? Any help.
You mean that the username and password you are trying to capture from the form are null? It sounds like you have a naming issue between your property and your TextBox.
@@IAmTimCorey No, at api side when i am post my username and password to generate token for user, (Token/Create) method receive username and password as null. With postman everything work fine.
Hi Tim, I'm watching some of your videos, and I see something here that really threw me. Specifically, it seems like you're able to call an async method synchronously. You have your LoginViewModel, which had an existing public void LogIn() method prior to this video. So that LogIn() method was called from somewhere in the code, synchronously. In this video you changed it to be an async method, so it could call asynchronously into your new IAPIHelper interface/class. I don't see where you showed the code calling the LogIn() method (at least, not in this video), but it doesn't appear that that code changed. How are you able to continue to call LogIn() synchronously, now that Lo9gIn() is an async method? Any time I ever tried to do that, Visual Studio gave me fits. I was finally able to find an approach today that compiles, though with a warning. I wrote a simple WinForms application (I was always a desktop developer). By having a button on the main form, which calls the async LogIn method in the viewmodel (synchronously), which in turn calls an async method in IAPIHelper interface, I'm able to build, but with "Warning CS4014 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.". Is this the same thing that you get in your project, but are safely able to ignore it because LogIn() is a command in a view model, and the call to LogIn() isn't followed by any additional lines of code? Over the years, I've attempted to find good ways to call async code synchronously, because I worked on a half million line project, and the solutions I found (on Stack Overflow and so on) were always bothersome to say the least. I'm just curious as to how you were able to do it without batting an eyelash!
The LogIn() method is now an async method. If you call an async method without awaiting it, you will not get the return data (or capture any exceptions). That's not a good thing. You can use the ".Result()" on an async method to call it synchronously but that typically isn't a wise idea because you are forcing something that should be async to run synchronously.
Are you going to port this to .NET Core?
Yes, that's the plan. We are developing in .NET Framework so that we can demonstrate how to port over an existing application.
Great tutorial... looking for headache pills now..... :)
Thanks! And I'm sorry? :-)
Why there is no UnitTest?
We haven't added them yet. This project is meant to be a real-world simulator. So, we started with .NET Framework so we could upgrade to .NET Core. We also started with no unit tests so that we could add unit tests to an existing project (something very few tutorials cover).
Great catch
Why am I getting internal sever error 500
You will have to debug to figure out why.
for me,result is always null
when I do this trough swagger,its ok
but from login form I always get bad request
It sounds like something is different. Are you marking the grant_type as password? Are you send a POST request?
@@IAmTimCorey I found a bug :D
Instead of grant_type,I wrote grant-type hahahah
please show me link video TRMDataManager
You can watch all of the videos in order if you use the playlist: ua-cam.com/video/Xtt6mS0p2_c/v-deo.html
They are labeled as to what each of them does in case you want to watch just one specific one.
This is a really good video. Have wanted to implement a login in WPF. However, I just don't understand your reluctance to you using EF. I mean I understand but you also use a lot of 3rd party tools. I would think something coming from MS is also "peer reviewed". Ultimately, you are responsible for the software you create whether you rely on your own code, MS code, or 3rd party code. Again though, this was a very instructional video.
I have a video on EF best practices on this channel that covers more about EF and my reluctance to use it, especially when training others. The simple version is that EF takes a lot of skill to get right. It is easy to get it working, it is hard to get it right. That's the big problem. I have seen too many apps that work in development that then cause major problems in production (when it is too late to change). I prefer to use Dapper because it doesn't hide bad code. You are forced to write good SQL. Also, by writing your queries in SQL, it is much easier to improve them compared to ad hoc queries from EF.
@@IAmTimCorey thanks, Tim. Agreed that EF does make getting going easier, perhaps much easier. I suppose one could suffer from if you don’t know what you don’t know…
It compiles. It runs. It never never execs the code under the using(){}. It just goes back to the login screen. I have spent hours trying to figure out why the using(HttpResponseMessage response = await apiClient.PostAsync("/Token", data)) postman works, swagger works, during step thru in debug I cannot find the key-value pairs added during instance creation of FormUrlEncodedContent var 'data' variable. I've checked rewatched, rewritten, debugged, but cannot get it to work.
Forgot to add that searched though the comments. found others with what seem to be the same or similar issue. but those answers did not work for me.
Got it! rename of ApiClient to apiClient failed to rename all uses in the code.
I'm glad you got it figured out.
God I'm a dumbass, I've spent like half an hour trying to figure out why I'm getting 400 from api and the reason was I was typying in wrong password. Please kill me.
lol, it happens to all of us.
Think a console would of been a good thing to add from the beginning, breakpoints are really slow to navigate through for something like this.
Thanks for sharing the idea. It's always clearer when we look back over the work.
@@tomthelestaff-iamtimcorey7597 found you can use Trace.WriteLine() to log to the output so guess it is built into WPF already. Just failed to Google it properly
Great tut again Tim. I hate to say it, but I think this is where you lost me. I have understood everything that you've shown for the most part up until this video, but this all seems too advanced now. I need to go learn what some of these things do especially extract interface. Never seen that before
This is a more advanced course. We are using techniques I've covered in other videos so you should be able to find tutorials that will get you up to speed.
Build the wall, build the wall :D
The API security wall? Done.
I refuse to give you $5!!! I'll cheat if I have access to the code lol
I like it. Way to push yourself to learn.
@@IAmTimCorey Oh yeah, I'd rather sit and look blankly at the screen for an hour and eventually figure it out then do a copy pasta!
Shout out from the the Garbage Collectors Discord! Quite a few of us like your stuff. Even some of the experienced guys approve of you 🤣
_container
.Singleton()
.Singleton()
.Singleton();
with this code shellview did not show in the screen and when I add a break point in shellviewmodel the run did not hit it but when i delete .Singleton() from the container it show up but the authentication did not work (normal) here a have to look in my code Please help
I think the reason is the Nuget versions compatibility but I still have other types of execption when I play with the versions
I'm running into the same issue 😟
@@Thunderbuck if I remember it was a nuget version problem try to use the same nuget versions that tim use
@@aymanawadallah6948 Hmmm. Already using the same versions but for Newtonsoft.Json, and I've rolled that back now and it didn't fix. I'll have to dig in :-)
Hi Tim i am receiving "An error ocurred while sending the request", + InnerException {"The underlying connection was closed: An unexpected error occurred on a receive."} System.Exception {System.Net.WebException}
In this line here in APIHelpert, I do have the data but the response is null HttpResponseMessage response = await apiClient.PostAsync("/Token", data)
In postman it works though