Improving testability of ASP.NET site without rewriting to MVC or WCSF - asp.net

I have an ASP.NET web app which is growing.
It is done in traditional web forms. While I would like to convert it WCSF to improve testability, this is time-prohibitive. I have taken the action to only make method calls in ASPX code behind which call the appropriate methods in the classes in App_Code so the spaghetti code is gone, which is good.
What else could I do to improve testability without any fundamental rewrite?
Thanks

Is this a Web Site project? I find Web Applications are more structured and easier to maintain. I'm not sure if they are more testable. Then do use namespaces where a web site does not.
Have you considered using a UI pattern such as MVP? You also might get partial coverage with creating interfaces for your code-behinds and testing against the interface. Watch out for hidden side-effects (changing the state of a dropdown within a method, it hidden behavior).
A book I found helpful was 'Working Effectively with Legacy Code' by Michael Feathers.

Related

Why is Razor Pages the recommended approach to create a Web UI in Asp.net Core?

Learning new things needs an investment of time, space and energy. I am currently learning Asp.Net Core MVC 2.0. This ASP.NET Core tutorials overview states:
Razor Pages is the recommended approach to create a Web UI with ASP.NET Core
This information confused me in deciding whether I have to stop learning Asp.net Core MVC and start learning Asp.net Core Razor Pages.
Why is Razor Pages the recommended approach to create a Web UI in Asp.net Core?
Any directions are welcome.
From this article in Microsoft docs:
MVC: Using controllers and views, it was common for applications to have very
large controllers that worked with many different dependencies and view models and returned many
different views. This resulted in a lot of complexity and often resulted in controllers that didn’t follow
the Single Responsibility Principle or Open/Closed Principles effectively.
Razor Pages addresses this
issue by encapsulating the server-side logic for a given logical “page” in a web application. A Razor Page that has no server-side logic can simply consist of a Razor file (eg. “Index.cshtml”). However, most non-trivial Razor Pages will have an associated page model
class, which by convention is named the same as the Razor file with a “.cs” extension (for example, “Index.cshtml.cs”). This page model class combines the responsibilities of a Controller and a ViewModel. Instead of handling requests with controller action methods, page model handlers like “OnGet()” are
executed, rendering their associated page by default.
Razor pages simplify the process of building
individual pages in an ASP.NET Core app, while still providing all the architectural features of ASP.NET Core MVC. They are a good default choice for new page-based functionality.
When to use MVC:
If you’re building web APIs, the MVC pattern makes more sense than trying to use Razor Pages.
If your project will only expose web API endpoints, you should ideally start from the Web API project
template, but otherwise it’s easy to add controllers and associated API endpoints to any ASP.NET Core
app. You should also use the view-based MVC approach if you’re migrating an existing application
from ASP.NET MVC 5 or earlier to ASP.NET Core MVC and you want to do so with the least amount of
effort. Once you’ve made the initial migration, you can evaluate whether it makes sense to adopt
Razor Pages for new features or even as a wholesale migration.
Note:
Whether you choose to build your web app using Razor Pages or MVC views, your app will have
similar performance and will include support for dependency injection, filters, model binding, validation, etc.
Update: Some more reasons i read on this github issue commented by scott sauber:
We're using Razor Pages for a [complex] Health Insurance portal... We have 60+ pages and I can say that for Server-rendered HTML, I will never go back to MVC. It's also not just for simple things. The Health Insurance domain is inherently complex and combine this with the fact that it's a multi-tenant app (we sell the product to other insurance companies), which adds more complexity as the app is highly configurable as different insurance companies do things a bit differently.
Why use it?
Razor Pages is more secure by default. Razor Pages gives you AntiForgeryToken validation by default. Plus you opt-in to what properties you want to be model bound via [BindProperty] which limits your exposure to over-posting attacks.
Razor Pages has a better folder structure by default that scales better. In MVC, the default folder structure simply does not scale. Having separate folders for Views, Controllers, and often ViewModels when all three are ultimately tightly coupled to one another is a huge PITA to work with. You end up bouncing to all 3 folders and navigating a bunch anytime you need to add or change a feature. It's horrible. This is why I advocated for Feature Folders. With Razor Pages, your PageModel (Controller + ViewModel) are in the same folder as your View. You can just hit F7 to toggle between them which is also super convenient.
Leads to more maintainable code that scales better. With MVC it was super easy to bloat a Controller with 10+ Actions. Often, these Actions weren't even related to one another in any way (except maybe a Redirect between the two). This made navigating the Controller to find code very difficult. It got worse if there were private methods in the Controller too, further adding to the method bloat. With Razor Pages, it's nearly impossible to bloat up your Page Model with unrelated methods to your page. Everything you put in your PageModel is related to your Page.
Unit Testing is easier. With a Controller, you might have 8 Actions and some of your dependencies you inject in were only related to one or two Actions. So when unit testing a single Action either you need to mock those out unnecessarily or pass a null, both of which feels gross (this can be solved a bit with the Builder pattern). With Razor Pages, the dependencies you inject in are 100% related to GET and POST actions you're working with. It just feels natural.
Routing is easier. By default in Razor Pages, routing just matches your folder structure. This makes nesting folders way easier to accomplish. For instance, all of our HR Admin pages are under the /Administrator folder and all the Employee pages are under the /Employee folder. We can authorize an entire folder and say the person must be an Administrator to get to any subfolder of /Administrator, which was way easier to do that than with multiple Controllers that make up the Administrator features.
I think that's the big stuff.
Update 2:
This is about some complexity of MVC pattern, does not directly answer the question but can be useful: An Engineering Manager at Facebook, said (here) for their “sufficiently” large codebase and large organization, “MVC got really complicated really quickly,” concluding that MVC does not scale. The complexity of the system went exponential every time they attempted to add a new feature making the code “fragile and unpredictable.” This was becoming a serious problem for developers new to a certain codebase because they were afraid to touch the code lest they might break something. The result was MVC was falling apart for Facebook.
Razor Pages are optimized for page-based workflows and can be used in these scenarios with fewer moving parts than traditional MVC models. This is because you don't need to deal with Controllers, Actions, Routes, ViewModels, and Views (as you typically would). Instead your route is convention-based, and your PageModel serves as your Controller, Action(s), and ViewModel all in one. The page, of course, replaces the View. You also don't have to have as many folders as you would in MVC, further simplifying your project.
From ASP.NET Core - Simpler ASP.NET MVC Apps with Razor Pages, a Sept. 2017 MSDN article by Steve Smith:
[Razor Pages] provide
a simpler way to organize code within ASP.NET Core applications, keeping implementation logic and view models closer to the view implementation code.
They also offer a simpler way to get started developing ASP.NET Core apps,
That article has more information on why to use Razor Pages over MVC for page-based workflows. Obviously, for APIs, you will still want to use Controllers.
3rd party edit - disadvantages of classical MVC folder organization
ASP.NET Core - Feature Slices for ASP.NET Core MVC, an older MSDN article from Sept. 2016, describes why the classical MVC convention to organize views and controller might have disadvantages for larger projects. The article gives an example of four loosely related application concepts: Ninjas, Plants, Pirates and Zombies. The article outlines a way to structure them outside of the default folder convention by organizing files into folders by feature or area of responsibility.
Microsoft is coming back to the WebForms approach to simplify the project structure trusting in the "Convention over configuration" mantra, while hiding the configuration from developer to make things faster. But it has the disavantage that everything will be mixed again. It doesn't look like a smart move for organizing. But... Hey! Something new must catch the attention of the dev towards Microsoft.
If your page uses an MVC Web API for the REStful, it's really more easy to just use Razor pages. If not, I would recommend you to use Core MVC.
In huge projects, where the model and controller are together in the same file, maintenance will be a nightmare. It works well for clases that are just 2 properties long, but it violates the Open Close Principle of OOP. You should design and use an architecture that can grow with time (Extensible) and still be stable and logic(No reestructuring the project), just extend it using the same pattern.
As a Software Architect I use design patterns automatically. What I like a lot is the Facade design pattern. You hide everything related to Home behind a HomeController and you can do the same with Repositories.
Want to know a funny thing? A tour guide explained where the name
Facade comes from. In Amsterdam you have big houses across the waters.
From the outside they look luxureous. But from the behind they can be
messy. The facade of the house hides whats behind it. Design patterns
comes from the building world. Well whats behind in my applications
also looks good but it was nice to know from the tour guide about the
explanation.
What about support for Sharing and Grouping actions in Razor pages. If you look at MVC Controllers you can see that you can Group controller actions based on functionality. You could say the Home page is such a functionality. Then you have a HomeController with About() and Contact() in it, but with Razor Pages this would be different pages. May be you have a big HomeController with lets say 5 other Views in it. They can all be grouped in the same HomeController.
A Controller has two things a Razor Pages does not have:
Sharing: You can share Controller actions between different pages, sometimes controller actions are not bound only to one page but can be shared between several pages. Remember Controller actions can also only return Data (JSON/XML/etc). Sometimes what they return can be used by different pages too.
Grouping: You can group related Controller actions together in one Controller. Ok if you are a fan of small Controller files you won't do this. I do. I group my Controllers based on functionality. That makes navigation much easier.
What is the Razor pages way of handling this: Use of directories I think:
Grouping: If we have the HomeController, then we could make a subdirectory Home with all the Home pages in it.
Question: For a simple Home that would be enough. But lets say we have an XController that uses for all actions the same Repository. You could initialize that Repository in the Initializer function of the XController. But for pages in the X subdirectory you would have to do that for all X actions again. Is that DRY?
Sharing: You could make a "Share" subdirectory and under that, directories with functionality that should be shared between pages.
Question: If you look at my fix you can see I use directories to solve the Share and Grouping problem of Razor pages.
How would you do this?
or...are Razor pages just meant to be for simple websites, could this be the conclusion for this version of Razor pages.
Blazor server has a strange architecture. It looks like a chat application by use of SignalR. My experience with applications like that is that events can get lost. I don't want to lose events, better is they are stacked and guaranteed to be processed like mail.
Developers were on forums in 2013 asking "What does Microsoft mean, Silverlight is not the recommended ...???"
Only this time, it is that MVC is going to be pronounced dead and long live MVVM.
And you can likely expect MVC to be thrown to the scrap heap, slowly, but sped up in about 18 months from now, and any and all time you spent learning MVC will go to that same scrap heap.
Also, MVVM looks easy but it takes a year to get the hang of it and really do it right.

What, why or when it is better to choose cshtml vs aspx?

I would like to know what, why or when it is better to choose cshtml and what, why or when it is better to choose aspx technologies? What are these two technologies intended for?
Thank you,
As other people have answered, .cshtml (or .vbhtml if that's your flavor) provides a handler-mapping to load the MVC engine. The .aspx extension simply loads the aspnet_isapi.dll that performs the compile and serves up web forms. The difference in the handler mapping is simply a method of allowing the two to co-exist on the same server allowing both MVC applications and WebForms applications to live under a common root.
This allows http://www.mydomain.com/MyMVCApplication to be valid and served with MVC rules along with http://www.mydomain.com/MyWebFormsApplication to be valid as a standard web form.
Edit:
As for the difference in the technologies, the MVC (Razor) templating framework is intended to return .Net pages to a more RESTful "web-based" platform of templated views separating the code logic between the model (business/data objects), the view (what the user sees) and the controllers (the connection between the two). The WebForms model (aspx) was an attempt by Microsoft to use complex javascript embedding to simulate a more stateful application similar to a WinForms application complete with events and a page lifecycle that would be capable of retaining its own state from page to page.
The choice to use one or the other is always going to be a contentious one because there are arguments for and against both systems. I for one like the simplicity in the MVC architecture (though routing is anything but simple) and the ease of the Razor syntax. I feel the WebForms architecture is just too heavy to be an effective web platform. That being said, there are a lot of instances where the WebForms framework provides a very succinct and usable model with a rich event structure that is well defined. It all boils down to the needs of the application and the preferences of those building it.
Razor is a view engine for ASP.NET MVC, and also a template engine. Razor code and ASP.NET inline code (code mixed with markup) both get compiled first and get turned into a temporary assembly before being executed. Thus, just like C# and VB.NET both compile to IL which makes them interchangable, Razor and Inline code are both interchangable.
Therefore, it's more a matter of style and interest. I'm more comfortable with razor, rather than ASP.NET inline code, that is, I prefer Razor (cshtml) pages to .aspx pages.
Imagine that you want to get a Human class, and render it. In cshtml files you write:
<div>Name is #Model.Name</div>
While in aspx files you write:
<div>Name is <%= Human.Name %></div>
As you can see, # sign of razor makes mixing code and markup much easier.
While the syntax is certainly different between Razor (.cshtml/.vbhtml) and WebForms (.aspx/.ascx), (Razor's being the more concise and modern of the two), nobody has mentioned that while both can be used as View Engines / Templating Engines, traditional ASP.NET Web Forms controls can be used on any .aspx or .ascx files, (even in cohesion with an MVC architecture).
This is relevant in situations where long standing solutions to a problem have been established and packaged into a pluggable component (e.g. a large-file uploading control) and you want to use it in an MVC site. With Razor, you can't do this. However, you can execute all of the same backend-processing that you would use with a traditional ASP.NET architecture with a Web Form view.
Furthermore, ASP.NET web forms views can have Code-Behind files, which allows embedding logic into a separate file that is compiled together with the view. While the software development community is growing to be see tightly coupled architectures and the Smart Client pattern as bad practice, it used to be the main way of doing things and is still very much possible with .aspx/.ascx files. Razor, intentionally, has no such quality.
Cshtml files are the ones used by Razor and as stated as answer for this question, their main advantage is that they can be rendered inside unit tests. The various answers to this other topic will bring a lot of other interesting points.

ASP.NET MVP vs ASP.NET MVC

My company is trying to make an informed decision about how to pursue future development.
We seem to have narrowed down our future internal and external Applications to being web applications. But we are still a bit confused from that point.
There is a large amount of support for Sharepoint here. As I understand it, Sharepoint is basically ASP.NET using MVP.
Others want to use normal ASP.NET using the newer MVC style.
I am also told that these don't easily play well together.
It is looking like Sharepoint (and ASP.NET MVP) is going to be the winner. Before we go that direction, I wanted to ask:
If we choose to base the next 5-10 years of our development efforts off of Sharepoint (ie ASP.NET and MVP) what are we giving up? And is it a big deal or just some "nice to haves" that we are loosing.
(It would have to be a fairly big deal to get management to change direction now.)
Whatever happens, WebForms will turn into a big ugly mess at some point. If you have to use webforms, don't use the postback and page lifycycle model - have aspx pages with presenters for get requests, and have a handler or empty aspx per post. It'll feel a lot more like MVC that way
I would say that what you choose depends heavily upon who your developers are, and what kind of apps you intend to build.
If you build largely crud-like apps that make a lot of use of third party (or your own) custom controls, then staying with Webforms is probably a good idea.
If you build largely "web" style apps with lots of client-side functionality, then MVC is a much better choice.
If you have largely newbie developers, Webforms may be better. If you have more experienced developers, even if they're new to asp.net then MVC may be a better choice.
If you are building very data-centric applications with complex interconnections, then MVC may be a better choice.
There are lots of reasons why you might choose one or the other, and it's always "it depends on...".
Also, MVC and Webforms are not completely incompatible. You can't use them in the same page, but you can use both in the same site. Also, like the comment above says, Sharepoint is not Webforms or MVP per se.. it's kind of it's own thing that is based on webforms. It's very "Webpart" oriented, which is just a way of saying you build lots of custom controls.
I have been a strong proponent of Separation of Concern (SOC) being built into software whether you use MVVM, MVC or MVP all three patterns are quite nice. With this being completely specific to ASP.NET, I would state you should use MVC3.
I have been a .NET developer for years now and have written my MVP pattern that is built on top of StructureMap (lots on my blog about it) and for a while I never saw the benefit of dealing with the changes associated from leaving webforms to goto MVC. However after dealing with ASP.NET for so long I've just had it with ASP.NET webforms errors that are completely out of my control.
The main errors from webforms occur with the ViewState timing out resulting in the generic cryptographic exception and the 2nd is where the ViewState is just truncated by the client or post somehow resulting in legitimate cryptographic errors. With MVC these errors just aren't applicable anymore. With .NET4 I attempted to create a webforms application without ViewState with the new features they added in .NET4 and that completely didn't work which cemented by decision that webforms time is past.
Out of MVC, MVC2 and MVC3 the feature set that comes with the MVC3 and the Razor view-engine is the most robust. You get all of the enhancements that came with MVC2 along with the much cleaner Views that the Razor view engine lets you create, on top of that you get global action filters and the baked jQuery client side templating (I'm 90% sure).
I would also approach MVC very similarly to MVVM where I would have 3 distinct sets of entities, my view models, my domain entities and my physical database models. (The last set may, or may not be the domain entities, I've started to realize trying to make your pure domain entities work with your database layer can be suboptimal at advanced stages)
If you are performing page post-backs to handle events, I would suggest MVP as the Presenter would contain the event handlers for all versions of the view (Different user interfaces such as web pages, iPhone, Android, Windows forms), with a uniform behavior. In other words, you would not need to write control events in a code-behind for every view. At least, they'd do nothing more than call the Presenter's event handler method or raise an event the Presenter handles.
If you are creating web applications and heavily using Ajax for page updates, with one or more web views and a cross-browser JavaScript library, such as jQuery, I would recommend MVC.
So it comes down to how you want to handle page events. MVP & MVC both have separation of concerns. MVP is more server based and easier to add multiple UI's and MVC is more client based, for event handling and more web centric.
From my experience, a strongly enforced MVP pattern has been much better for data centric complex LOB applications.
MVP offers greater seperation as your presenters have no knowledge of web centric concepts.
Code coverage is also increased as you have no conditional code in the views.
We have several apps that where the presenter is used between both web and windows apps.
You presenter referes to a complete abstraction of the view, asp.net MVC relies on abstractions of view dependants (HttpContextBase etc.)
That all said you need to design this into web forms, its not out of the box, but if you do it right first time and have developers that understand it and stick to it you end up with a very clean solution.
there are some solid frameworks out there to support MVP in webforms:
http://www.codeguru.com/csharp/.net/net_general/patterns/article.php/c15173
webformsmvp dot com as well.

Usefulness of asp.net MVC framework as opposed to coding MVC style with regular asp.net?

I am new to the asp.net world (but not new to .net) and I have been playing around with various things to see how I want to architect a web application I am developing. In my playing around I have decided I did not want to use asp.net's controls, as I have done enough php and ruby on rails to be decently familiar with regular HTML, and a decent amount of javascript.
I see a lot of comparisons between asp.net webforms and asp.net MVC, however when ti comes down to it I am not seeing that much of a difference (and I'll admit that it's probably me missing the differences rather than them not being there). I already have coded my asp.net application using a MVC type of architecture (aspx has the view, aspx.cs has the controller code, and models are separate classes in the app_code directory).
If I do not intend to use asp.net controls and just intend to use pure html and javascript, what are the advantages of using the MVC framework? As of right now, the only one that I am seeing is routing, and I'm sure if I look more I can find easy ways to do custom routing without using the whole MVC framework.
Anyways, if anyone could go into details of asp.net webforms minus the asp controls versus mvc framework, I would be greatly appreciated.
You're going to find a number of differences and reasons to use MVC over WebForms but it's going to depend on whether those differences are important to you or your project. Routing is definitely a big advantage for MVC. Although you can implement custom routing configurations in WebForms it's significantly less intuitive.
Another big advantage is unit testing. Along with an IoC container and a mocking framework, MVC makes unit testing a cinch. It's much easier to isolate actions and behaviors with MVC and test those specifically.
A third advantage is that MVC will help reduce the spaghetti code you're going to write. If you're not planning on using any User Controls then it won't be long before you're missing the HTML helpers in MVC. The Html, Url, ViewModel, TempData, etc make working with raw HTML much easier.
The inherent validation in MVC is also impressive. It's getting better in MVC2 and now with the integration with client side validation libraries it will save you a ton of time and add a lot of functionality.
No more VIEWSTATE.
There are many others but again it depends on whether those features are important to you. Good luck with your decision!
ASP.NET MVC is built on interfaces, which makes it extensible, easy to write unit tests for, and encourages clean, loosely-coupled architecture.
If you're using 'classic' ASP.Net without using any of the server-side controls, there's not much of ASP.Net that you're using -- it's basically classic ASP with .Net instead of VBScript behind it at that point.
Giving up webcontrols is the biggest reason not to use ASP.Net MVC. If you're fine giving that up, I'd just use ASP.Net MVC and be done with it. It's got all the parts you'd need to write yourself anyway, and the parts you don't like, you don't have to use.
In my playing around I have decided I
did not want to use asp.net's
controls, as I have done enough php
and ruby on rails to be decently
familiar with regular HTML
Thats not a good reason to decide against ASP.NET controlls. The importand thing about ASP.NET is Viewstate. It allows you to use event driven programming in Webapplications. This makes a lot of things very easy and productive.
Anyway - as you know ruby on rails I guess you will pick up ASP.NET MVC pretty fast.
First up, if you use ASP.NET MVC you'll be using a supported framework that has books, online resources and hundreds of blog posts surrounding it.
Second, I suspect you need to play with ASP.NET MVC to see it's power. There is way more than WebForms in ASP.NET MVC. For many, the fact that WebForms is optional (you can use different view engines) is a major plus.
For me, the extension points, the cleaner code, and the unit-testability of everything I do are major reasons to never go back to ASP.NET "classic".
My recommendation to you is to get a decent tutorial (look for the Nerd Dinner tutorial), play with ASP.NET MVC, and find out for yourself.
Note: ASP.NET MVC is not for everyone, and if you're heavily into the post-back mechanisms in ASP.NET, or have a heavy investment in server and user controls, then you might not want to take ASP.NET MVC right now. But for your next project you should at least know what your options are.

Tips from ASP.NET MVC and lessons for ASP.NET WebForms developers

What are some helpful things that ASP.NET MVC developers could suggest that would help us ASP.NET WebForms developers to write better code/web apps?
I'm a WebForms guy but with all the new hype around MVC I'd value some comments on helpful tips, tricks and strategies that might be able to be used in a webforms app.
Something that occurred to me a while ago when learning about the new MVC framework, is that WebForms was, I think, an attempt at MVC in many ways. The markup and code-behind comprise View and Controller, and you're left to write your own Model.
This idea goes hand in hand with the important design considerations I gained from learning about MVC. The most important of which is solidifying the core domain of your system as a whole and making sure all common logic is defined at a level that is reusable within this domain. This is your Model, and I like to call the logic that lives at this level Domain Logic (I mix terms, I know). Your Model should be reusable across different applications (a main web/winforms app, winforms apps for utility and configuration, background processing services, web services, etc.). Your applications should stay very specific to their purpose: they consist of Presentation Logic (their views) and Application Logic (their controllers). Anything that crosses the line of needing to be used in other applications is easily classifiable as Domain Logic, and should not be part of the application code for any given application.
I hope that makes sense.
The gist of it is, even if you're not using a pure MVC framework or object model or whatever, this high level look at design can be applied with great effect. Isolate common logic in a domain layer that is reusable across applications and your applications are much easier to write and extend and maintain.
Forget about page life cycle
There is no ViewState (by default that is)
There are no postbacks
You need to know the HTTP protocol basics (GET/POST). The same goes with HTML (DropDownList is actualy a tag)
I would recommend geting started by watching the screencasts on Microsoft's Learn site:
ASP.NET MVC Videos
There you will learn the differences between the WebForms postback model, and the way that MVC directly routes your URLs to Actions & Methods.
The second major difference is to remember that in ASP.NET MVC you do not use controls that do postbacks. It might feel a bit more like Classic ASP where code is inline on the page within server side blocks, but it is worth it. You will have full control over the HTML that is generated, and this is very good for things like Search Engine Optimization.
Some advices
Don't use standard controls. Instead pay attention jQuery, MooTools.
Use strongly typed Models
It's good practice to use some IoC like Spring.NET
I'm also coming from webforms, but have been learning asp.net MVC since around preview 3.
I'm not exactly sure how to bring anything from MVC into webforms, they are two entirely different frameworks. I'm probably too new with it to understand how any of it could be applied to webforms, but right now it seems they have very little in common.
Some of the strengths of MVC are it's rigid structure on how you need to do things and where you put code. It also does away with the form runat=server and I believe does not promote the usage of any of the asp.net server controls (you need to write all the HTML yourself). That is pretty much the definition of webforms right there. MVC pretty much replaces webforms with it's own framework.
If you ever did Classic ASP or PHP, I would call ASP.net MVC a more structured framework for what people might do with those older scripting languages. It's kind of like the FuseBox framework, but even more structured and evolved.

Resources