4

I'm currently working on a web app using ASP.NET Core (C#) on the backend and Next.js (TypeScript) on the frontend. I have a lot of forms that need to be validated and I don't want to write validation rules for them twice because it will be a hell to maintain and keep them synchronized. So I want to kill two birds with one stone.

Of course, it would be easier if both frontend and backend used the same language but then I'd need to use Node or Deno instead of .NET or F# + Fable (Too esoteric to me) or even something like Blazor but it still seems too experimental to me

The only reasonable solutions I can think of:

  • Use something like JSON Schema and use it for validation on both sides (Form generators exist too):
    • Write JSON Schema myself and generate code based on that schema? (Seems like a painful route to take)
    • Generate JSON Schema from C# or TypeScript types (Something I would prefer because JSON schema seems messy and I'd prefer not to write it manually)
  • Fetch validation rules from OpenAPI somehow?
  • Use protocol buffers instead of JSON?
  • Use WebAssembly module similar to how Blazor does it but only for validation
  • Convert C# validation rules e.g. using FluentValidation to some custom format or to TypeScript code, but then you need to write your own JS library that can read it
  • Write validation logic separately for frontend and backend (Something I'm trying to avoid)

Is there anything else I can do? How do you handle it in your apps? Is there any alternative to JSON Schema you know of?

Similar question Best practice in synchronized form data validations (Web apps - Client-Server)

14
  • 1
    I write it twice. generally you want it to do differebt things anyway. on the front end i want to validate a single field and display a helpfull message to the user, on the backend im assuming the input is fine and throwing exceptions if its not
    – Ewan
    Commented Apr 27, 2021 at 11:56
  • 1
    @Konrad: It's not that your intention isn't good, it'd be a great feature to have. But to implement such a conjoined system, you often run into additional effort and logical constraints that make it undesirable on the cost/benefit scale. For example, JSON Schema can tackle basic format validation, but it doesn't allow for rule logic, which is the predominantly more important validation business applications tend to rely on.
    – Flater
    Commented Apr 27, 2021 at 12:21
  • 1
    @Konrad: The point I'm trying to get across is that JSON schema is severely limited as to how much it can validate, especially when compared to something like FluentValidation. For example, while you can define ranges for properties, you can't define than one property must be larger than another, or that a string property doesn't contain profanity, or ... If there is a way to generate JS/TS from FluentValidation, great, but I'm doubtful given the very broad range of validation logic that FluentValidation can accommodate.
    – Flater
    Commented Apr 27, 2021 at 13:10
  • 1
    @Konrad: Exactly. But not just for multiple properties, also for logic that hasn't been predefined in JSON Schema (such as string format checks or int range checks). JSON Schema is really light on features in that regard.
    – Flater
    Commented Apr 27, 2021 at 13:16
  • 1
    Have you considered embedding a .NET JS engine into your server side application? In theory you could write your validation logic once in JS and use it in both places. I tend to agree with the idea that the logic isn't necessarily the same but you could use it as a first pass on the server I suppose.
    – JimmyJames
    Commented Apr 27, 2021 at 16:12

1 Answer 1

3

Since web browser and servers run on different languages and exist in completely separate processes, there is no good way of combining these validation rules. The best you can hope for is defining as many validation rules as you can in a generic manner.

Since you are using .NET and C#, a number of validation libraries exist in C# which have some integration with the .NET Core MVC framework. This integration puts special data-val-* attributes on the form fields based on the generic validation rules in your view model. JavaScript on the client reads these attributes after moving focus away from a field or on form submit to execute the same rules on the client.

Validation rules that cannot be abstracted away in a generic validator will simply need to be run on the server. Really, all validations should be run on the server. You can forge requests using most any programming language, so don't count on JavaScript validators.

Client side validations are a convenience for the end user. Do your best to consolidate server and client side validations, but sometimes you either need to duplicate the logic, or just simply don't run those validations on the client. Only run them on the server.

3
  • To me, client-side validations are just as important as server-side validations. Server-side validations are only for the developer and for security purposes in case someone tries to forge requests manually and client-side are for UX and to decrease the number of server requests.
    – Konrad
    Commented Apr 27, 2021 at 13:53
  • I think JSON Schema is a pretty good way of combining these validation rules at least to a certain degree but yeah all of the solutions I can think of seem tricky. Regarding integration with the MVC framework, that might work fine for projects that use razor views. In the question I mentioned I use next.js/react.js so this won't work for me.
    – Konrad
    Commented Apr 27, 2021 at 13:55
  • 1
    @Konrad I don't think the argument is that client-side validations are not important. The point is that server-side validation is absolutely essential. Client-side validations are beneficial but not strictly necessary. It's something that needs to be pointed out again and again due to the fact that so many vulnerabilities are created by leaving validation to the client.
    – JimmyJames
    Commented Apr 27, 2021 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.