Data Validation and Exception Handling in ASP.NET Core 6

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] okay gentlemen let's start into the last hour of today's lecture let's quickly recap what we did so far we did a blackboard session about why we should do logging monitoring telemetry part one part two we added serilog an alternative logging framework which adds a lot of functionality especially syncs to our asp.net core logging and now now we are going to tackle the topic of um of data validation data validation on the server side and of course that has also large implications on the client side let's first try it inside of controllers because that is the most easy thing to do please open up the log demo controller file and at the end or at the beginning i really don't care add a record public record uh let's simply call it customer and let's add two constructor parameters the first one should be string name and the second one should be int age but i would like to add data validation attributes on top of them you know them from entity framework something like required try that of course you are going to need a using statement here or something like what let's say max length 50. and the second one might have just for demonstration purposes a range area here the age might be between 0 and 100 just for demo purposes okay just add a record with these view data validation attributes you know the data validation attributes already and we will find out how asp.net core handles those data annotations so far we have primarily used data annotations for entity framework now we are going to take a look at them without entity framework by the way this code is of course also in my github repository now let's add a web api with http post and let's say here we can create the customer by posting towards customer to the customer route customers route multi plural public i async results something like this create customer and let's get the customer record from the body so if we specify just the customer here then asp.net core will take the customer from the http body let's quickly log something so that we know that the customer has been written to the database we will not really write it to the database we will just write a note log dot log information writing customer i don't know something like name 2 db and specify the customer.name as a parameter okay and at the end we just say return ok that's all we need to do i will zoom in so you can easily i cannot zoom in it's too large so i will just mark it for you this is the code pretty straightforward and simple and this is the record with the data annotation attributes don't get a wrong impression this is not real world code because when we would really create a customer we should definitely not return okay http 200 but we should return created 82 http 201. okay good should just work okay so let's give it a try let's run this app and then please use any http client tool any web api client that you want to use in my case i'm going to use visual studio code you know me and just for today i would like to use thunder i haven't installed thunder why haven't i installed thunder did i tell you about thunder in the past the thunder client yes no maybe okay yes you say yes good thank you very much yeah let me quickly show you what you can do with that you can just run thunder client with a new request okay seems that thunder did not install properly so i cannot show you thunder today i don't know why it works perfectly on my machine at home but not here whatever i'm going to do is request http with our good old friend rest client post https localhost use any client that you want you want to use postman that's perfectly fine too log demo customers content type json and specify the name which is whobar and the age which is 42. and if we run this guy we should get back okay nice nothing special that is not a surprise but now please watch what is going to happen if we mess up and for instance if we do not specify a customer name consciously making a mistake run the send request and wow what we get back is correctly a bad request and we will get back the correct status code we will get back a correct name a correct error and even we will get the information which field was wrong you see that one do you see the code that is responsible for this very detailed error handling exactly no that's the magic of asp.net core just by specifying a data transfer object this is what we call a data transfer object dto in short dto just by specifying a dto with data annotation attributes the entire so-called modal validation is done automatically without us having to do anything and it is properly logged so if we take a look at sec for instance and if i refresh this here i will see that i got the correct response here with the 400 i see that it was a post and i would see all the details which are inside of my code so the point of this demo was just use data annotations and you are good that's good news right at least i think that's good news unfortunately if we have good news there have to be bad news too and unfortunately i have bad news for you and i would like to show you what this means you do not absolutely have to follow along now it's also in my repository because this is more conceptual knowledge it's not necessary that you really do that because you will see what i'm going to show you now you will not like it so you will probably not do it so let's do an app map post this is now the minimal api it's not in the controller this is the difference here we are now using minimal api the thing that we learned at the beginning of this year and here we do a minimal customer something like this and again we are going to get the customer that's the customer that we have defined in the other file c and then we want to do exactly the same same thing that we did here boom inside of our other file and the logger should be i logger now i don't need the log i don't want to do the logging here it doesn't pay off results dot okay now we are good please imagine that we do the logging here that's not the point if i run that one now it's exactly the same code but now with minimal api so i go to my visual studio code i change my call a little bit i say minimal customer i post it i obviously made a mistake yeah not plural singular and you see no modal validation and that's the point what i wanted to show you if you write the minimal api outside of a controller you will not get validation and that's a big drawback isn't it so if you want to have validation like the one i showed you before and believe me you want to have that you should still use um not the minimal api but you should currently use the controller api there will be changes in that area so maybe in the next version of net you will have the possibility to either turn on validation or you will get validation out of the box we will see but currently it is like it is you do not get out of the box validation for your reference i created a sample implementation you see it here in the github repository where and it's not necessary that you can read every line where you need all this code in order to do the validation manually you could do that and it still isn't perfect because this is the code that you do for manual validation and it still doesn't work properly because it does not support records so you can only use classes with that so you have to write a lot of code more to achieve the same you are not allowed to use records currently to achieve the same so don't do it this is why i told you don't follow along because the point that you should take away from this demo is do not use minimal api if you want to build a real world api with model checking if you just have one or two http get requests that's perfectly fine we did that in the last homeworks but for a fully fledged web api stick with controllers at least for the moment good okay so this was more of a warning sign than anything else nice good speaking about error handling last demo of today can you remember we did a demo in the log demo controller in the last hour where i here it is where i threw an exception you see that one invalid operation exception let's try that again to refresh our memory what happened when we had an exception in our web api now you can follow along again makes absolute sense because that that is important and that is super practically relevant i've shown you how this exception is locked to sec block demo and i think it was nothing else just log demo and you see i get an exception i can continue and what i will get back is this nice little information directly in the browser so we'll get a human readable exception information with a proper stack trace i can take a look at the cookies the header the routing and a lot of other things if you think that this one is useful then i have bad news for you you will only get it on localhost on your machine because this website is the so-called developer exception page you get it out of the box but only on your machine don't think that this will be present when you run this thing on your production server let me show you what will happen when you run this thing on the production server please follow along go to properties and there you will find a file which you might have ignored so far but now we will take a look at it it's called launch settings.json find it first delete everything about iis have you ever heard of iis or are you too young internet information server ever heard about that if you not have heard about that you are on the lucky side believe me old guys like me we had to deal with this stuff it was not a lot of fun to just delete everything that is related to iis we simply don't want to be reminded of those days but the thing that i would like to uh that i would like you to do is i would like you to duplicate the profile with this web api error handling server please just copy it make a second entry and maybe rename it maybe something like production at the end and the important thing that i would like you to change is this one it's the asp.net core environment variable it's the environment variable called asp.net core environment and you see here you said development that would be a development server and on the development server you get a nice exception page this is for you as the developer to do troubleshooting but on a real server this would be either empty or set to something like production so please try to change that to production and then magically you have here the web api handling server and now you have first you have to save the file i'm sorry i did forget to save the file so again so i screwed up with all these curly braces it should be here thank you for pointing it out so let me check again if i did it correctly this one should be this one that is okay this one should be here this one and this one should be that one and i'm missing a final one here sorry i screwed up with the curly braces but now it should be correct so save it again and yoo-hoo now it works thank you for pointing out my mistake it's per you were perfectly right and now you see you have these two environments let's try the production version so let's go to the production version and run it again let's make sure that we get the exception log demo and boom we get the exception continue to run and this is what we see this is what we see we can even go to the network tab rerun it yes i know debugger and what i will get back you see just a 500 and if i go to response i see nothing believe me in a devsecops world this is your nightmare because your customer will call you and tell you the app doesn't work i see a blank screen then you ask him what is the error message can you have can you tell me any kind of error message here and he will say oh i don't see any error message it's completely empty i get a white screen saying something about http era 500 i have no idea what happened what do we need in this situation logging because now we can go to sac refresh this thing and immediately you see i get what i need to see but the problem is that your customer might not be the only one having an exception so you will have a pretty hard time finding out which requests came from which customer get the idea so what we essentially want to do we want to give the customer carefully selected details about the mistake we don't want to give the customer all the details that we as developers need with the stack trace and everything but wouldn't it be nice if we just give the customer enough information that he could tell us in a support call what his problem was and it in order to achieve that we can add unhandled exception handling we can handle unhandled exceptions and return proper error codes now this is a little bit more code and i've prepared it for you because it's not complicated and it doesn't pay off if you write it manually please open the program.cs and look for the code starting in line 44 and this is the code it starts with if app environment is development sorry if not app environment is development please copy this code this one and put it in your program.cs is it important where i would put it in front of the map controllers but it really is doesn't matter you will need to add a using statement that should be pretty simple and then your code should compile before we dive into the details let's just simulate the problem again run your server in production mode not in development environment and enforce the error log demo boom and what do we get back this is exactly what i wanted to see i get back a json content and this json content besides some textual information contains the request id see that one and that's the important one because now i can ask the customer hey could you please send me the request id via email for instance then we can take this request id this one copy it go to sec and say request id equals to this one and if we run this we immediately boom tracked down the exception and we know what the problem is for this specific customer for this specific case so it is best practice to add enough code to a production server to make it possible to identify the reason of the the error the customer does not need to be able to spend to to identify the reason but there should be enough information in it so that the customer can copy this information send it to you and if you have access to the logs you can find out what happened that's also a question of security because we do not want to expose our technical details to the customers because those customers might use them to i don't know to to maybe maybe use misuse a security flaw in our application or a known vulnerability question ah okay okay okay you're one step ahead yeah let's let's talk about that um i didn't just return any json but i returned a very specific json if you take a close look at the code that you just copied in you will see that i will return here in case of exceptions a problem details class can you find it in the code problem details this problem details class is a specific class of asp.net core and it reflects a standard a standard which is defined in the rfc 7807 you know rfcs huh no rfcs are standard pages this is where the http protocol is defined and things like that okay so if you follow this link here this one it will lead you to a standards document this one and this standards document it's from the internet engineering task force ietf it's from march 2016 and it defines a standardized return code for errors in web apis and this is what you should adhere to you should your response should follow the design the designs here in this rfc then you are standard conform and problem details give you exactly that now you asked what about this type here this type is a universal resource identifier it's a uri don't misunderstand that it's not a url that you can't really call there is no website there it's just an identifier for the root cause of the problem of course you can write more sophisticated code to find out what the error was and you can return different types for different situations did you have a database error you might return a different type did you have a division by serial error you might return different type it depends please take a look at this link that would be way too complex for now because it's not that easy to access the error the underlying error but in this link which i specified here you find all the details yep good so problem details is a very important class that you frequently use when writing real world web apis it will return a meaningful error message to the customer and of course all the log information will be all the the error information will be captured a last thing that i would like to mention here when we do those loggings never forget that there is a thing which is called gdpr general data protection regulatory dsg file you have heard about the dsg40 gdpr how does gdpr relate to logging why is that relevant yes exactly we track our users and we store personal identifiable information have you heard this term before p-i-i personal identific for identifiable information personal data pii americans say pii to it so if you store pii in your logs you are under the legislation of the gdpr and you have to follow the guidelines there that means you must not store the data longer than you absolutely need it so you need to remove this data so be very careful about what you store in your logs currently our log by default does not store the payload it only stores the headers the status code and so on but we don't see the data that the customer posted and that might be relevant because maybe the user posted some very highly sensitive data maybe some medical records and you do not want to store medical records about customers inside of a log file i understand what i mean so always think about what are you allowed to store what do you really need to store and only store this information that you really need to pinpoint errors for instance the ip address where the request came from is this personal information are you allowed to put that in log files or is this already covered by the gdpr it is covered exactly if you combine an identifier of the person with his or her ip address you are under the gdpr that's pii already so think about whether you want to store the client ip of the customer if you do not store the client ip and if you do not store the user id then you just get technical logs and then you are not under the gdpr understand what i mean so be very careful about that nice this is what i wanted to show you i wanted to talk with you about logging monitoring and telemetry i wanted to show you some error handling techniques how logging relates to error handling how we can do unhandled exception handling and show you some details about how asp.net core handles all that with that i promised you something homework okay homework for the next two weeks because next week is holiday is this one i will copy it into the discord server don't see this just as homework it's preparation for the upcoming exam if you do this homework properly you will not need to do additional learning for the for the exam okay it's pretty obvious what you have to do your job it's again in the share for future sample universe your job is to implement a web application with which users can create offerings we do not do a login just let the user enter the technical id of his or her record and assume that this is the login we do not need a real world login and then i want to have the following functionality get the list of all offerings for the current user display it in a table display at least those columns in the table for every offering i want to be able to toggle the currently available state that's just a boolean you already have the entity framework model we did that a few weeks ago i want to be able to create a new offering where i have to specify at least these data items i have to be able to alter an offering where i need to be able to alter at least these three fields and your form should include basic error handling so you should already in the angular client detect things like hey this is a required field but the user didn't enter anything here so not very complicated you should be able to do that within a few hours of course use asp.net core six use entity framework six come up with your own web api design where do you use http get post put patch how do you design the proper the paths the queries and things like that include an open api specification that's essentially a tick at the beginning of the project it will not be complicated include basic error handling in the api and write the angular client with the latest version want to earn extra points add serilog essentially just apply the three lines of code in the program.cs that we did today that's a cheap one that's really a cheap extra point and last but not least if you want you can incorporate the code that we wrote last week and replace the list of all offerings with a multi-word search that we did last week you get a second extra point for that this homework will take you i think between two and four hours depending depending on how much you practiced already and you have two weeks of time for it if you manage to to solve this problem within i would say three to four hours you're good if you struggle heavily with this homework practice because then you will have a problem in the exam any questions for the homework
Info
Channel: Rainer Stropek
Views: 4,694
Rating: undefined out of 5
Keywords: ASP.NET, ASP.NET Core, .NET 6, C#, Web API, RESTful Web API, Error Handling, Data Validation, Model Validation, HTL Leonding
Id: LRX3b1orE78
Channel Id: undefined
Length: 30min 27sec (1827 seconds)
Published: Wed Nov 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.