The Best Way to Validate Your Settings in .NET

  Рет қаралды 62,748

Nick Chapsas

Nick Chapsas

Күн бұрын

Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will show you how you can validate your settings or options for your .NET and ASP.NET Core applications. I'm also going to show you how you can extend that to use FluentValidations too.
Workshops: bit.ly/nickwor...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasG...
Follow me on Twitter: bit.ly/ChapsasT...
Connect on LinkedIn: bit.ly/ChapsasL...
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 105
@daheefman
@daheefman Жыл бұрын
I understand the limitations of data annotations, but I really liked the beautiful simplicity of it. As soon as your started delving into Fluent Validation the code suddenly drowned in boilerplate. Thank you so much though, I will be using data annotation validation going forward!
@FleetingDream755
@FleetingDream755 Жыл бұрын
Agreed. For the simple type of validations he used in the video, FluentValidation is overkill. But once your validation logic because more complex, I can see the sense in going down this route.
@nickchapsas
@nickchapsas Жыл бұрын
I you don't need to do anything custom or complex then sure, it's good enough. The moment you start implementing more custom logic that requires injection of DI registered service, DataAnnotations fall apart.
@dcuccia
@dcuccia Жыл бұрын
@@nickchapsas I also like generally that the fluent approach decouples your business data model from the validation rules. Maybe not a big deal for a simple option type, but a good way to keep the SoC pattern consistent with other parts of the code where AOP on business objects falls apart.
@_iPilot
@_iPilot Жыл бұрын
And it is still possible to implement logic in class derived from ValidationAttribute, which one perfectly works with DataAnnotationValidation.
@BittermanAndy
@BittermanAndy Жыл бұрын
Data annotation puts the validation right where it needs to be, right where everyone knows where to find it. Baffling why anyone would do something different.
@AdityaGupta-qd8iv
@AdityaGupta-qd8iv Жыл бұрын
I had started using it as it is quite easy to make a typo in your configuration. And more generally, I have found that self-checking code is just an awesome way to guard your solution any crazy spanner that your QA tester might throw at it. ;)
@johannesprinz
@johannesprinz Жыл бұрын
❤ it. Thank you Nick. Now I'm battling with build time settings and secrets and how to validate those. Further down the rabbit hole we go.
Жыл бұрын
I think it would also be interesting to see how to have a similar effect when options change. For example if you have settings within an Azure Vault and you would like to validate it as soon as it changes? Clearly this is no longer possible on application startup as application is already running, however it would be interesting to react immediately (if even possible?) and do something (log it or send email etc). It would be nice to see an additional video for solving such a problem :)
@nickchapsas
@nickchapsas Жыл бұрын
The code in the video will work fine you just need to replace the IOptions to IOptionsMonitor. Then every time you get the value, validation will kick in
Жыл бұрын
@@nickchapsas Does it also work for the first time (on startup)? Or do I have to do both? Where does the validation exception end up in?
@robertnull
@robertnull Жыл бұрын
@ The rule is that the exception is called when you try to resolve .Value from one of the IOptions wrappers. ValidateOnStartup() just calls an additional validation before .Value is first resolved.
@robertnull
@robertnull Жыл бұрын
Another rule is not to believe people on the Internet and to just test it yourself ;)
@richardmcnamee
@richardmcnamee Жыл бұрын
Very interesting. I always learn a lot from watching your videos, although I usually have to watch them a few times as there is so much information in such a short space of time. I would love to know how this technique could be implemented when using the named IOptions pattern.
@AdamWeigert
@AdamWeigert Жыл бұрын
I particularly like putting both the configuration and validation of options in their own class. Microsoft did a good job when they designed the options library/pattern for .NET.
@hectorbas9850
@hectorbas9850 Жыл бұрын
Wish an example would have been shown of using it with asynchrous code, like validating that an API key is valid as he had mentioned. Also would the validation logic be re-called if the settings are reloaded with the other option patterns (IOptionsMonitor I believe)?
@lordicemaniac
@lordicemaniac Жыл бұрын
i will incorporate this into my current project, this could save me headaches later
@mehdizeynalov1062
@mehdizeynalov1062 Жыл бұрын
You are the best, even better than chat gpt
@escobar4599
@escobar4599 Жыл бұрын
Like the approach using FluentValidation over attributes personally. Options Pattern is really powerful, if a bit dense for something so important (and at the same time so un-exciting) to a project setup. I have tended to follow a similar approach with a validator (today explicit, maybe next time ill look at using FV), but not using the OnStartup bit as it is out of my control. Instead I cause validation to occur prior to the host Run so that I can log individual events for bad configuration bits and not just get the exception/stack trace output. Combine all that with using postconfigure for some options to smart-default or otherwise derive values and its a bunch for work for sure - but work that leads to a polished end result.
@MrDaedra88
@MrDaedra88 Жыл бұрын
To bring OnStartup into your control you should configure liveness and readiness probes and check for ready state in your CD pipeline. Then deployment will fail if an application couldn't start and you will see a deployment error in your build server (and probably an alery in a chat, email, etc)
@matthewcollings3387
@matthewcollings3387 Жыл бұрын
How can this be implemented for options that need to be used to register other services? Is this validation performed when the services are built?
@stephenadams6959
@stephenadams6959 Жыл бұрын
I love this approach. Thanks for sharing.
@FilipCordas
@FilipCordas Жыл бұрын
I always wanted to make a code generator to auto create json schema for an option class so you get validation and auto complete.
@sultonbekrakhimov6623
@sultonbekrakhimov6623 Жыл бұрын
Love your videos. Never stop making them ))
@mustafizurrohman88
@mustafizurrohman88 Жыл бұрын
Hats off Nick Chapsas!
@reikooters
@reikooters Жыл бұрын
I'm doing this but it's a bit different. My AppSettings class as a Validate() function and I have an IStartupFilter which runs that function. In the end provides the same functionality i.e. throw a list of errors for any invalid settings on startup.
@jerryjeremy4038
@jerryjeremy4038 Жыл бұрын
This is very very good! Thanks Nick
@carlinhos10002
@carlinhos10002 Жыл бұрын
Right on lunchtime 👌
@franciscovilches6839
@franciscovilches6839 Жыл бұрын
Would be neat if there were an additional fluent validation nuget package for this
@roman.koliada
@roman.koliada Жыл бұрын
Why do you use AddOptions and Bind methods? There is an overload of Configure method which accepts IConfiguration
@ksdvishnukumar
@ksdvishnukumar Жыл бұрын
Very nice..Lot of good things learning from you..
@oranhal
@oranhal Жыл бұрын
This works if using the options in endpoints but it doesn't work if the options are needed during startup. Looks like ValidateOnStart() happens after ConfigureServices() and potentially after Configure(). Is there a way to validate earlier in the initialisation?
@julienraillard3567
@julienraillard3567 Жыл бұрын
Hey Nick ! :) For thanks sharing this technique, i use to manage all my checks with DataAnnotations but i can understand that sometimes FluentValidation could be better for more complex case ^^ Juste have one questions on it, would you're technique also for "hot reload settings" case ? 🤔
@a_b_t_s
@a_b_t_s Жыл бұрын
Still waiting for ConfigureAwait vid
@conradpetrich5093
@conradpetrich5093 Жыл бұрын
I love the idea! But my attempt at implementation has failed due to Scoped services that cannot be resolved from root provider. I'm trying to figure out a way to get around this when not being done within a minimal api like in your example. Any ideas?
@Petoj87
@Petoj87 Жыл бұрын
Awesome content as usual!
@iammahie
@iammahie Жыл бұрын
Hey Nick , can you make a video on how to write an exception middleware such that if any exception happens it should add it to output object and returns to the place where exception was thrown and continues execution
@fathichabane384
@fathichabane384 Жыл бұрын
Nice and clear way to validate settings 👌. Thanks Man
@martinhans4121
@martinhans4121 Жыл бұрын
Very cool!
@smirnability
@smirnability Жыл бұрын
Awesome!
@julienlefevre1661
@julienlefevre1661 6 ай бұрын
Any idea how to address the issue that when you inject an IOptions, if you haven't configured it, you get a default instance with all properties with their default value. Even if your setting object has required properties. For example, you end up with a null string that wasn't nullable and required.
@mateuszszczuka2311
@mateuszszczuka2311 Жыл бұрын
Thanks 👍
@koushiksaha8198
@koushiksaha8198 Жыл бұрын
This is going over my head. It tried but didn't understand why it is used.
@fllvoid
@fllvoid Жыл бұрын
But what if a string is entered into the Retries field instead of a number? How can we check for this case, since the error will occur during binding?
@snapching
@snapching Жыл бұрын
I get stuck on terminology of options, as it's not an option they are settings within configuration. A section has configuration settings ...any reason why they called it options? On top of that is the default providers after configuration is instantiated. I think there are 7 default providers. I always clear then, and add back the provider I need
@nickchapsas
@nickchapsas Жыл бұрын
I don’t know why they went with options either. I clashes with the appsettings name too. Always annoyed me
@spoonfuloftactic
@spoonfuloftactic Жыл бұрын
This looks like it would mix well with IValidatableObject does that happen automatically?
@diegonombela5169
@diegonombela5169 Жыл бұрын
Why not simply create an extension method that supports: var configSection = configuration.GetSection("key"); services.Configure(configSection); var settings= new T(); configSection.Bind(settings); settings.Validate(); Where T is of type IValidate and contains a Validate method.
@iammahie
@iammahie Жыл бұрын
How to add data annotation for a string that take http/https endpoint as a setting , to validate using ValidateDataAnnotations()
@FarukLuki111
@FarukLuki111 Жыл бұрын
What would be the solution do turn this off if it is on "developer machine" ?
@DevonLehmanJ
@DevonLehmanJ Жыл бұрын
I hate that to bind options i have to pass the config object. I wanted a way to do it using the registerd IConfiguration so i had to create me own extension methods to do that. imo that should be out of the box, idk why you wouldn't want your IConfiguration in your Iservicecollection so that you can inject it as needed and define more services (such as options) that are based on that.
@Martin-kj1od
@Martin-kj1od Жыл бұрын
Also would not it be nice to have appsettings in C# and load them dynamically on startup? Would that be possible ?
@briumphbimbles
@briumphbimbles Жыл бұрын
They are dynamically loaded on startup. You can do the configuration in C# already the whole point is that JSON is a structured declarative markup syntax that makes specifying configuration easier. Any imperative logic you then use on top of that configuration is obviously done in C# already. You could do the whole lot in C# but its not going to be nicer which is why people dont do it.
@alvarezbarbosa12
@alvarezbarbosa12 Жыл бұрын
This cannot be done in an Azure Function App since it doesn’t use the Hosting package. Any workaround?
@user-tk2jy8xr8b
@user-tk2jy8xr8b Жыл бұрын
You would have that exception on startup if you registered the setting class as a singleton
@johnnyirish9852
@johnnyirish9852 Жыл бұрын
Fantasic, is there a place where I can find the code you showed us in this video?
@nickchapsas
@nickchapsas Жыл бұрын
Yea, my Patreon
@johnnyirish9852
@johnnyirish9852 Жыл бұрын
@@nickchapsas Ah ok, I feared I need to ask an AI to extract the code from the video ;-) Which Patreon, is it available with the KZbin membership for your channel?
@cedricvereecke6108
@cedricvereecke6108 Жыл бұрын
Hi Nick! Small heads up; theres a typo in the description “settions” presumably in stead of “settings” Cheers
@ilyakurmaz
@ilyakurmaz Жыл бұрын
Sadly, it doesn't work for non-host apps like Azure Function or Aws Lambda.
@KingOfBlades27
@KingOfBlades27 Жыл бұрын
I was just thinking does this work in functions. Thanks for the info 👍
@harindaka
@harindaka Жыл бұрын
Just discovered this myself trying this in maui and console types
@cocoscacao6102
@cocoscacao6102 Жыл бұрын
Ungh... Back in my days, developers copied code only from verified sources, such as StackOverflow. Never from the official framework... ☹
@eliobatista2368
@eliobatista2368 9 ай бұрын
It looks like fluent validation is still the best approach in .NET 8.
@IMarvinTPA
@IMarvinTPA Жыл бұрын
Why not put the validation in the init methods themselves and throw exceptions?
@nickchapsas
@nickchapsas Жыл бұрын
Because it will make the options objects incredibly bloated. If that approach works for you then that’s fine, but I wouldn’t go down that path
@IMarvinTPA
@IMarvinTPA Жыл бұрын
​@@nickchapsas Is there a way to keep the Fluent validation in the same class file as the options object so they stay coupled in the editor? Hiding the validation in another file breaks visual continuity.
@MartinFaartoft
@MartinFaartoft Жыл бұрын
@@IMarvinTPAyou can nest you Validator class inside your options class
@qnikbud
@qnikbud Жыл бұрын
Even validation at start time is too late IMHO. Validation should be done in the text editor while the user types in the values. Also there should be the IntelliSense suggestions and tooltips when hovering your mouse on top of the parameter names. This is achievable with schemas. I've been using XML schemas (xsd.exe) for my settings for more than a decade now. There was just no other alternative for the functionality I've described. But now JSON schema seems to be catching up with XSD, so the setting validation/documentation should also start using the schema and provide the validation/IntelliSense at edit time. But while we are not there yet this video is very helpful, thank you!
@nickchapsas
@nickchapsas Жыл бұрын
Most modern systems don’t store settings in a file but rather a server and load it on startup. Validating on compilation is both impractical and a security issue because it assumes you have secrets in your settings
@Ristogod
@Ristogod Жыл бұрын
I see you put your source code behind a paywall, which is fine. However, I can't in good conscience endorse Patreon usage to do so considering their immoral business practices. Also, would love to watch your videos on Rumble.
@alexandreparent3942
@alexandreparent3942 Жыл бұрын
Honestly... Both design are horrible. An object should not exist in an invalid state. You can create simpler types that have the proper types (LogLevel enum, a type representing an int range or just using an unsigned int)... And handle reading the options as a deserialization problem. Goal is to remove boilerplate and have explict types.
@nickchapsas
@nickchapsas Жыл бұрын
ValueObjects for option types surely will remove all the boilerplate, but they are boilerplate in themselves. Terrible design
@alexandreparent3942
@alexandreparent3942 Жыл бұрын
@@nickchapsas But they encapsulate their own boilerplates... Which I find merely terrible rather than horrible.
@kabal911
@kabal911 Жыл бұрын
MORE classes!!! It’s the OOP way 😂 Seriously, creating value types for every setting in every section sounds horrible
@joephillips6634
@joephillips6634 Жыл бұрын
I get why people don't use it. Looks really annoying
@TechySpeaking
@TechySpeaking Жыл бұрын
First
@FilipCordas
@FilipCordas Жыл бұрын
One of the worst decisions I made was using Fluent validations instead of Data Annotation in a project. Strongly recommend not using them, just creates unnecessary boilerplate that leads to people not using simple validations because it requires too much. code and the validation is separate from your domain so it's much harder to figure out required rules. Not to mention that any sort of generation (OpenAI) is not native and requires extra setup.
@nickchapsas
@nickchapsas Жыл бұрын
How do you have custom logic in the data annotation that requires resolving a service from the di container?
@FilipCordas
@FilipCordas Жыл бұрын
@@nickchapsas The question their is should you have that in your validation logic. For example, if you use CQRS that additional logic is related to your business rules, and you can use things like pipelines in mediator to separate it. But even that leads to double query problems like with exists validation on updates so there is a good case to be made you should keep it in your commands. To me validation is transferable between systems you should be able to do it on the frontend and the backend the same way and services mean you can't do it.
@nickchapsas
@nickchapsas Жыл бұрын
It doesn’t matter if you use CQRS or any other form of separation of concerns. Settings validation is infrastructure related not business logic related.
@FilipCordas
@FilipCordas Жыл бұрын
@@nickchapsas Yes but that is only true for validation rules that don't require you use services can you give me an example of a service you would need that isn't related to requirements coming from the concrete requirements of the project you are working on?
@FleetingDream755
@FleetingDream755 Жыл бұрын
@@FilipCordas I think you both have a point. Nick is talking about the specific case of appsettings, you're talking about the concept in general and I think (if what I said is correct) that you are both correct.
@claucometa
@claucometa Жыл бұрын
Very useless to much work
@hermanbohnet7808
@hermanbohnet7808 Жыл бұрын
booooooooooooooooooring !
How to use Discriminated Unions Today in C#
17:09
Nick Chapsas
Рет қаралды 60 М.
The CORRECT way to implement Retries in .NET
17:01
Nick Chapsas
Рет қаралды 88 М.
Incredible Dog Rescues Kittens from Bus - Inspiring Story #shorts
00:18
Fabiosa Best Lifehacks
Рет қаралды 39 МЛН
Cute
00:16
Oyuncak Avı
Рет қаралды 7 МЛН
The Joker wanted to stand at the front, but unexpectedly was beaten up by Officer Rabbit
00:12
The Logging Everyone Should Be Using in .NET
15:34
Nick Chapsas
Рет қаралды 65 М.
The Secret HttpClient Feature You Need To Use in .NET
10:41
Nick Chapsas
Рет қаралды 72 М.
How To Connect Your React Frontend To Your AspNetCore Backend
23:13
The New Way of Parsing ANY Type in .NET
13:03
Nick Chapsas
Рет қаралды 68 М.
The Best Way to Add Health Checks in Any .NET App
12:31
Nick Chapsas
Рет қаралды 90 М.
Double the Performance of your Dictionary in C#
15:12
Nick Chapsas
Рет қаралды 67 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 258 М.
The List Best Practice That .NET 8 Makes Possible
8:40
Nick Chapsas
Рет қаралды 44 М.
The "Problem" with .NET 9...
9:38
Nick Chapsas
Рет қаралды 17 М.
The Easiest Way to Measure Your Method’s Performance in C#
12:51
Nick Chapsas
Рет қаралды 78 М.
Incredible Dog Rescues Kittens from Bus - Inspiring Story #shorts
00:18
Fabiosa Best Lifehacks
Рет қаралды 39 МЛН