Frameworks don't dictate code quality. Developers do.
There's been some chat recently about the probability of Web Forms won't survive the transition into the new .NET Core era. And, as folks are apt to do about anything that they have spent hundreds or thousands of intimate hours of their lives with, many people are reacting pretty strongly at the idea. Some are rejoicing at the Death of Web Forms. Some are ready to give a pretty flattering eulogy. I'm sure there are also those out there that are in complete denial and will continue to use it to build brand new projects for years to come (though I haven't actually met those people that I'm aware of).
I'm not saying Web Forms is dead in the next release of ASP.NET. How would I know, anyway? Just because I'm posting this on weblogs.asp.net doesn't mean I'm privvy to Microsoft's plans. What I do know is that I and many other folks who used Web Forms to pay the bills for many years have happily moved on to ASP.NET MVC (and eventually ASP.NET 5)...
And we continue to write bad code.
It seems many folks who are rejoicing about the death of Web Forms like to prove their point by pointing out all of the bad things you can do with it. Huge ViewState and SessionState, gigantic code-behind files, data access right from the view (SQLDataSource, anyone?), etc. The rejoicing seems to come from the idea that with this next framework these problems won't exist anymore. With this next framework, those developers will finally start writing good code!
There's one problem, though:
Bad developers write crappy code. Great developers write less crappy code.
Folks who think the death of Web Forms means the death of crappy code are sadly, depressingly, unfortunately, mistaken. You think simply using ASP.NET MVC rather than Web Forms will automatically result in better code quality? Well, please, allow me to retort!
- Session State is no longer a first-class citizen, but that doesn't stop developers from writing a base controller that copies TempData over to the next request every time.
- ViewState is gone, but that doesn't stop developers from wrapping the whole page in one form, serializing a giant object to a hidden form field, and rehydrating it again (in a base controller, of course) when the form is posted... which happens in reaction to any button click on the page
- Code-behind files are gone, but that doesn't stop developers from writing 5,000 line controllers (+100 points for dynamic SQL in the controller)
- SQLDataSource is gone, but that doesn't stop developers from making a static helper that calls the database from the view (plus another 100 points for more dynamic SQL!)
All true stories. And the list goes on.
The framework can make bad patterns harder to implement but, god help 'em, developers are gonna write bad code anyway.
Even great developers.
In my experience, developers write the code that they know how to write -- they use the patterns, practices, APIs, etc. that they know. After all, what else would you expect?
The common trait among all of those examples I just gave is that they were implemented by developers with years of experience with Web Forms. They understood the Web Forms paradigm. They knew how to get stuff done with Web Forms. Then, they switched to ASP.NET MVC - either because they wanted to or were told to, doesn't matter - and they started learning that, too. The API is the easy part. There's no shortage of tutorials, blog posts, and docs to tell you which methods to call and which attributes to use.
Then it becomes crunch time. You HAVE to implement this feature by tomorrow or you're going to miss your deadline. You don't feel like you have time to read all those docs to figure out the "right" way to do it -- you don't have time to worry about what logic belongs in the view and what belongs in the controller. But, you knew how Web Forms did it. In Web Forms, you'd just use SessionState. Or ViewState. Or do a PostBack with the state automatically rehydrated for you. Those techniques worked great, right? It's what we know, so let's reimplement them!To butcher the cliche: not everything is a nail, but when all you've got is a hammer and a deadline to meet - and you don't have time to go get a screwdriver - you're damn well gonna whack that screw with that hammer anyway. We all find a way to get the job done.
At crunch time, you always fall back to what you know. As far as I'm concerned, the answer is pretty straight-forward: expand the scope of what you know. Take time to learn the new framework, and by that I don't mean just memorize the API. I mean learn why the framework is designed the way it is. What is the Model-View-Controller pattern? What are its benefits? What are its drawbacks? When is the right time to use it? When's the wrong time?
At the risk of sounding pessimistic, if you do all of that, then you'll still right bad code. I've been aggressively learning and practicing for almost 20 years and I still write bad code. More frequently than I'd like to admit!
Hopefully, though, you'll write much less of it.