My name is William Gross, and I am not a writer.
I build and maintain web applications. Specifically, enterprise web applications, according to Martin Fowler’s definition. And I’d still be building and maintaining them right now too, if it weren’t for the white-hot ball of fire inside me that won’t let me rest until I trap myself in this Substack editor, kicking and screaming, and tell you what I’ve learned.
My development experience lies wholly in the Microsoft universe, beginning with Visual Basic and Active Server Pages, continuing into .NET, C#, and Web Forms, and finally moving to .NET 6/7/8/9. But that’s not the interesting part. The interesting part is that along that journey, in my foolish youth, I decided to bushwhack off the Microsoft-recommended trail and ended up in the wilderness of custom web frameworks. I worked with a few others to build what we call the Enterprise Web Framework (EWF), which is a part of the larger EWL.
After two decades of iteration and improvement, this is likely a good place to be. Our small group has shepherded several applications from their Web Forms inception to their modern life with .NET 9. We have protected their essential business logic from the destructive “total rewrites” that are common in the industry. But what’s certain is that this web framework is unique, and as the only steward of it at the moment, I feel obligated to get the word out.
With that said
This article is part one of the forms series:
Part 1: Forms in web apps: a new approach (this article)
Part 2:
Let’s start with the framework’s approach to forms, which are a key part of these applications. Consider some questions:
What if you could build forms in an entirely programmatic way, with no separation of logic between HTML and code?
What if your validation/post logic was inline with the rendering of the form?
What if your forms could talk directly to an automatically-generated data access layer, at least in the simpler parts of your application where separate domain modeling isn’t necessary?
Here’s what that looks like, in the context of a movie database app that is intentionally similar to the one in the Blazor tutorial. Take a page that lets users add new movies:
This is the C# code for that page:
![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cfa240-27d3-436e-86f3-9d648f2627cf_2560x1440.png)
Aside from database schema (a Movie
table with a few columns), what you see above is all there is. No model class, no scaffolded code, no HTML. Just a small amount of application-level configuration (commensurate with what you’d see in Blazor or other frameworks), some generated code, and a URL pattern defined at the parent level:
But why?
Why abstract away the HTML?1 Fully-programmatic UI is certainly not a good choice for every page in every application. It’s not good particularly if some of the people making changes are web designers, who may feel quite comfortable editing HTML-based templates but would never touch C# code.
But it can be an amazing time saver for full-stack developers. Notice that all of the logic for each form control is located together. The control itself, the label, the validation rules. You aren’t forced to jump around to different files, or scroll to different parts of a file, to add a new control to the form.
You may wonder how the validation logic on this form even executes, or more generally how a POST
request is processed. Answer: the page UI is built again, just as it was on the initial render. And during this process, the validation methods for each control are registered with the PostBack
object. After the framework finishes building the UI, it executes the validations in the PostBack
followed by its modificationMethod
, which in this case performs the SQL insert of the new movie. Finally, it executes the post-modification action, which returns the user to the Movies
list page.
It would be fair to consider this rebuilding-on-post a slight performance compromise. In practice it’s not a problem due to other optimizations in the framework. On the flip side, it elegantly prevents overposting (i.e. mass assignment) attacks, because the full context of the form is available during validation. In other words, the framework knows which fields the user has available to edit, and will only accept submitted values for those same fields.
For next time
This is the first part in a series about forms, and I’d love to expand on these brief explanations and also cover the more advanced features of the framework. Please let me know if you have questions or if there are specific topics you’d like me to write about.
The framework does support placing blocks of raw HTML on a page, but they can’t be used for controls that need to send data back to the server. They are mostly intended for regions of the page that contain “administrator-editable” content such as the terms and conditions of a purchase, which may change every few months or from year to year.