'You're Doing Validation Wrong in .NET' | Code Cop #023

preview_player
Показать описание


Hello, everybody. I'm Nick, and in this episode of Code Cop, I will talk about some of the worst validation code I've seen in .NET and as always this advice comes from LinkedIn.

Don't forget to comment, like and subscribe :)

Social Media:

#csharp #dotnet #codecop
Рекомендации по теме
Комментарии
Автор

To check everything else together or fail fast: I think it really comes down to the application itself. Most of the time, as a user, I would be infuriated, when I'm gettin a new error over and over again, like why didn't just give me all to errors at once, so I can fix all at once :D The only exception is when an error is caused by something that was previously empty for example, that could still cause new errors, but I'm ok with that.

hupett
Автор

Validation nomad: someone who wanders the world seeking positive reinforcement

jamesterwilliger
Автор

I think the Code Cop series is losing its way. In the example post, the list example is clearly superior. Sure there are even better ways, but most of the alternatives explored don't have the very basic functionality of returning every individual error without combining them all into a single string or exiting as soon as the first error is encountered.

Also, I think Nick has way overcooked the cost of allocating a list vs using yield. I get the impression that he gets into perf sensitive code a lot from his videos, but for the vast majority of LOB apps, it's a total non-issue.

Just because the "good" advice can be improved, doesn't make it bad advice.

StuartQuinn
Автор

I hate errors which only contain the error message as the identifier, because the error message may change. Sometimes you need to handle certain validation results in a special manner, especially on the frontend. I personally always make my validation results contain a human-readable identifier such as "WrongPassword", along with a description.

tedchirvasiu
Автор

I feel like fail fast or not is an application concern. If you are on the server-side, then you just need to know if the thing is valid or not for insertion. But, if you are returning a message to the user, then you want every error listed there. That's why I'd rather make the method ready for both cases using IENumerable as a return and a "yield return ValidationError(errorCode)". That way you could go for a "Any()" call if you want the fail fast approach or a ToList if you want to return all of the errors to the user depending on the use case.

SergiobgEngineer
Автор

I think in this example, the idea of not failing fast seems to have to do with something like form validation rather than, say, precondition checks. If you find all the issues at once, it's possible to annotate the UI with all the errors at the relevant place, allowing the user to correct mistakes without having to try again repeatedly until no errors are found.

marcusmajarra
Автор

Those advices are very funny. The left one is some junior code, the right one, some junior code with max 6 months of experience.

shinpansen
Автор

WHY is no one ASKING for more Fucntional episodes!!! Yes more functional concepts, please! That stuff is so f***ing cool! You have teased us before, but is it time for the Monad explanation?? What does it even mean??

tanglesites
Автор

Isn't there valid justification to return a list of all errors to make your API more user friendly, and relay everything wrong with the request that was received? I can see scenarios where end users get frustrated with an API not giving them the whole validation picture, forcing them to discover through trial and error what a valid request should look like.

MrBranyace
Автор

I prefer to apply functional concepts to the domain, instead of building my domain on top of a functional library.
So in this case, I might have a UserForm type, that has a Submit method which returns a Submitted<User> type, that has two properties User? and Errors?, which are null annotated to be not null when SubmittedUser.IsValid is true and false respectively.

TreatAllWarningsAsErrros means that the compiler knows and enforces that you submit the form and check validity before accessing the User or Errors properties.

Now I don't have to explain to devs unfamiliar with function programming what a monoid is, or why our code uses Lst<T> instead of List<T>

SamFerree
Автор

7:20 why do you need to do extra hoops to return null instead of just empty enumerable? This approach makes consumers make unnecessary checks which also invalidates why you have IsValid flag in the first place.

markovcd
Автор

the difference between yield return and creating a list is minimal. to consume the IEnumerable the caller has to convert to a list or array anyways. overall I think the suggested approach by the user good. It would be even better if using an enum for the error class plus a message string to make it easier for the caller to handle it. So honestly I don't get the point.

nothingisreal
Автор

true developers ONLY write to console 🗿

demarcorr
Автор

For form validation, you need to put the feedback next to the each element of the form, so none of these mechanisms are suitable.

So maybe your use case is a server validating its inputs before processing them. If that's the case, I'd consider 'parse, don't validate'. The server receives an HTTP request and attempts to parse a (valid) User out of it. If the parser returns a User, the server goes on to process it. If the parser doesn't return a User, it returns an error and the server handles or returns that error. It doesn't much matter how the parser signals errors - exceptions work fine for this case, as do Either- or Result-style discriminated unions. What I would try to avoid is the possibility of constructing a User object that might not be valid.

garethrowlands
Автор

I think that there are so many little class nooks and crannies in .NET, especially with the plethora of nuget and github packages out there, that videos like this are very useful. I wish there were more. Good job, Nick.

pw.
Автор

Interesting, good video, thanks. I don't see a horrible problem with empty or null errors meaning no errors were found. There comes a point where a consumer needs to be intelligent enough to follow a spec or interpret or code for the result.

rreiter
Автор

Not sure what the purpose of returning what was passed in for a success is?

leerothman
Автор

Everything you did with installing a separate extension seems like overkill, I'd probably hate the guy who would do this in my codebase.

collapsingspace
Автор

The email validation, checking for @ sign is better than most, especially better than any regex base ones which almost always rejects valid emails.

davidmartensson
Автор

I really love to see how 'senior' devs enjoy overcomplicating simple things. It would be a nightmare to see the same devs' code for a complex business logic problem.

LeandroDaminelli