What we're going to take a look at in this lesson.
And it's not particularly helpful to us at the moment due to the amount of code we've got, but we're
going to set it up so it's available to us whenever we need to use it.
And that's the dotnet debugger.
Now I'm going to demonstrate this using VS code.
Of course Visual Studio comes with its own debugger.
Rider as well comes with its own debugger.
If you're using that, I won't be able to demonstrate that I can't demonstrate everything about everything,
but I can demonstrate how to set up the debugger on VS code, because there are some steps you need
to take to get this to function.
So we'll head back to VS code.
Let's just close this stuff down.
And if we go on to this tab in VS code then this is our debugging tools effectively.
Now we can't do much at the moment.
We need to create one of these launch.json files to actually set up the debugger in C-sharp.
So I'm just going to click on this.
And then we select the debugger we wish to use.
Now for C-sharp code we use the C-sharp debugger of course.
And this is what it gives us.
It just gives us an empty file that just gives us some comments and not much else.
So we need to add some configurations, but there's a helpful little button down here that says add
configuration.
And then we've got our different options.
Now we're going to add two configurations here.
My personal favorite for debugging purposes is to use this one to attach to an already running dotnet
process.
So typically I like to keep the API server running pretty much all the time.
And if there comes a time where I feel I need to debug some code, then I'll just use this option to
attach a debugger to an already existing process.
We'll also add another configuration, because there are certain types of code where this will not work
for us, and for certain types of code, that system will not work for us.
Is the program class because we can only attach a debugger after we've got to this stage in our code,
and we're actually running our application.
If we wanted to debug something going on inside the DB initializer, Then we would have to use a different
approach, and the different approach we'd take is we'd have to launch the C-sharp project with the
debugger attached already.
So that's the other one we'll set here.
But this one needs a bit of configuration.
So I'm just going to say API debug as the name of the thing.
And then we need the relative path to the project folder which should be API csproj.
But we'll test that.
That's what it should be for this.
And the dotnet core attached, we don't need to add any additional configuration.
So I have the API server running.
So the first one we'll check or test is the attach the debugger option.
So let's go to our files in Solution Explorer.
And like I said we don't have a huge amount of code to look at at the moment.
And if I go to the products controller, then let's take a look at the getting of an individual product
and I'll just add a breakpoint.
We just click on the left hand side of the line numbers to get that red dots applied there.
Then we go back to our debugging tab, and then we choose which option we wish to use for the debugger.
So we've got our two options there.
We've got API debug that's going to launch the process.
And dotnet core attach is going to attach the debugger to an already running process.
So I already have a running process.
Now this part can catch a few people out because it might be slightly different.
And it does change sometimes as well between Windows and Mac.
So if we're going to attach to a process, we click the play button.
And then we have to find the process where our application is running.
And like I say, it can be somewhat tricky to find the process.
Now on a mac, it's pretty straightforward.
All I do is I look for the API.
Now, there's no details in here.
All I've got is just this API and this is the process I know that my application is running on because
I called it API.
Now if you're on windows and you're not seeing API, then your process.
Because processes on windows are different to processes on a mac.
Processes on windows are EXE or executable files.
So you may need to search for dotnet watch.
And I think you should see more detail about the DLL inside dotnet watch that you're looking for.
You'd be looking for something like api dll, because if we take a look at the file system and we go
to not the.
Net system this time, but we go to restore the file and folder view in API we have a bin folder.
Inside here we have a debug folder.
And this is the process that's running our API.
This API dll.
So effectively you're looking for something that matches this inside this search window.
I know sometimes people have had problems in the past locating the very specific process to debug.
So it might be a case you have to search around.
It should be either.
Net something, it could be API x and it might just be a bit of trial and error if it's not obvious.
And if this one really doesn't work for you, you can always stop your API server from running and then
pick the other option to start the debugger and launch it with your API, and that one will definitely
work.
So anyway, I'm going to go back and search for API and select this.
And what this should do is start our debugger, and it looks like I might have to give a bit of security
or pass through security to give the debugger access to the code.
And sure enough, now the debugger is up and running.
So what we have on the left hand side is we have our debugging tools.
We can see any variables.
We can see things that we want to watch.
And then we've got a call stack.
So we're just going to take a look at this variables section.
But the debugger is running.
We've got our tools at the top.
We can pause the debugger.
Once we've hit our break point, we can then step over the code that we're looking at.
We can step into the code and step out of the code, and we'll also have a play button to go to the
next breakpoint or just continue the request once we've hit this breakpoint.
So I'm just going to go to postman and I'm going to go back to section two.
And I'm going to get an individual product.
Just choose this one API product two I'll click send.
And what should happen is I get taken to the debugger.
Now if we take a look at the variables window, there's quite a lot of information.
Because we're in the context of an API controller, we can see quite a bit of information about the
request.
Also because we're injecting our store context in here.
Then there's also access to this as well.
So that gets a bit detailed because of the amount of information available from the Dbcontext.
So we won't look at that.
But I will take a brief look at the API controller context, because inside here we can see the request
that we've received from postman in this case and we can see the content type, the content, any cookies
we have, any headers that were sent up with this request, and the host values where we're going to.
And inside this request, is there anything else of use?
Well, we can see the path.
And what we'd also have inside an API controller endpoint is when it comes to identity, we can also
get access to the user information, the user that's authenticated to this API endpoint.
And that information is contained inside there.
And we see this.
This keyword is something that we see often.
And because I'm inside a controller and I've hit an API controller endpoint, then this refers to the
products controller itself and what the products controller has access to.
So it's got the controller context, the HTTP context, the model state we took a look at earlier on
in the buggy controller.
And this is where it tracks any potential errors or validation errors inside here it would be added
to this model state.
And then we've got things like our route data.
Where is the request going to in this case the Getproduct method inside the products controller.
And lots of useful information.
So great.
That's useful.
And if we step over we don't have anything about the product inside here yet.
Because whilst we're on this line, we haven't actually gone to our database to go and get the product.
So if I click on Step Over, then I'm going to step over that line of code.
And at this point we now have the product and we can see on the left hand side we've got the details
about the products we retrieved from our database.
So great.
And then we can go ahead and return the product.
And if I step over again and step over again and step over again, then we get taken down the rabbit
hole of what looks to be like the entity class, etc. so I'm just going to play out the rest of the
request.
And if we go back to postman, we can see we've got that returned.
Now, just as a quick example of the other approach where we used the launch the debugger, I'll just
stop the application and I just want to double check this one does work.
It's not something I use typically, because I typically just attach the debugger rather than use this
version.
But we know the DB initializer class is something that we wouldn't be able to add a breakpoint to,
and then find out what's going on by attaching the debugger.
So I'm just going to add a breakpoint here on line 23, just to check to see if we have any products
inside our context.
And I'll just make sure the application is stopped and it is stopped.
And I'll go back to the debugger and I'll choose the other approach this time.
And this time we're going to launch our application with the debugger.
So I'm going to press play.
And what I'd expect to see is I'd expect to stop on this breakpoint whilst our application is starting
up.
So I'll press play and we've got a build failure because let's see users blah blah blah restore forward
slash API csproj failed to build.
Would you like to continue and run the last successful build?
I'm going to say yes, and that didn't work either.
Okay, so what is the problem there?
And it looks like the path is a problem here because this just says restore API Csproj.
The folder that the API Csproj is contained in is actually called API.
So really that should be api API Csproj.
So let's just make that correction.
So I'll go back to the Launch.json and where we've got the project path that's going to need to say
forward slash API and then API Csproj.
So let's give that another go.
I'll hit the play button again.
And this time we should get success.
And I can see that I've hit the breakpoint inside the DB initializer, we can debug and troubleshoot
what is inside here.
So our first check for instance is to check the context dot products to see if there's any products
inside our database.
And just as a quick demo of taking a look at the DB context, because there is something that can catch
people out, if I go to context and I go to products and I go to results view, then we can see our
different products inside here.
So what this is going to tell us that we do have some products in our database.
So we're going to hit the return statement there.
And we're not going to create another new list of products.
So if I was to step over this then I go to the return statement.
And that would then take us out of this block of code.
So I'll just hit the play button.
And then our application would start up as normal.
But we're running in debugging mode as well so we can keep our debugger attached.
But the downside to this is when we make code changes then it normally interferes with a debugger.
and it's more of a case of stopping the application, restarting it again.
So that's one of the reasons I do prefer to use the attach approach when it comes to the debugger.
So that's just a brief overview of the debugger.
It is a very useful troubleshooting tool.
I do recommend practicing using this whenever you run into a problem, just to get used to using it,
just so you can inspect to see what's going on with your dotnet code.
So practice, practice, practice using this and you'll just get used to the tool and get used to seeing
what's going on inside your code.
So anyway I'm going to stop this and I'll just use the normal approach to start the application.
Anyway, this brings us to the end of the section, another milestone reached.
So we're going to save our changes into source control.
I'm just going to stage these changes and give this a message of end of section six and commit this
and sync these changes up with GitHub.
And we'll wrap up with a summary.