-
Notifications
You must be signed in to change notification settings - Fork 568
01. Tour of the ASP.NET MVC and WebForms apps implementation code
In this walkthrough, you can simply explore the initial implementation of two sample legacy applications, with monolithic architectures, created with classic ASP.NET. One is based on ASP.NET 4.x MVC (eShopLegacyMVCSolution) and the second based on ASP.NET 4.x Web Forms (eShopLegacyWebFormsSolution). They're both in this GitHub repository. Another example shows how you could containerize a classic WCF service (Windows Communication Foundation) that could be consumed by a desktop application (eShopModernizingWCFWinForms).
Although in order to understand these apps you don't really need to know how they are internally made, this intro's goal is just to get you familiar with these apps' code and configuration. You can configure the app so it generates and uses mock-data without using the SQL Database, if you want, for testing purposes. This optional config is based on Dependency Injection, in a decoupled way.
There are no specific steps in this walkthrough. The goal is for you to get a basic understanding of the staring point of the walkthroughs: the legacy applications. After reading the information below, download the code and run the legacy apps to see them in action.
The diagram below explains the simple scenario of the original legacy applications.
You can see the eShopLegacyMVC original legacy application loaded in Visual Studio 2022.
Note that this application is a single monolithic application based on a single ASP.NET MVC project. In a similar way, the eShopLegacyWebForms applications is also a monolith and single-project-based app. The only point in common for both applications is the catalog database, which is also the same database for the catalog microservice in eShopOnContainers. These current monolithic scenarios we are covering here have nothing to do with microservices architecture. They will, however, make use of containers.
From a business domain perspective, both apps offer the same catalog management features, and would be used by members of the eShop enterprise team to view and edit the product catalog. You can see initial screenshots below.
These are web applications used to browse and modify the catalog entries. The fact that both apps deliver the same business/functional features is simply because of comparison reasons so you can see a similar modernization process for apps created with the ASP.NET MVC and ASP.NET Web Forms frameworks. The dependency taken on ASP.NET 4.x or older (either for Web Forms or MVC) means these applications will not run on .NET Core unless the code is fully re-written and instead uses ASP.NET Core MVC. But this is precisely the point, in this case you don’t want to re-architect or re-write any code but just containerize these existing applications while still using the same .NET technologies and the same code. You will see how you can run applications like these in containers without changes.
These monolithic web applications are designed as web applications containing all the code, including the data access logic. The database would typically run in a separate high-available environment, like a SQL Server cluster.
For development environments you have several choices in these applications for the SQL Server database:
- Run the database as a SQL localdb database running on the same Windows (Or Windows Container afterwards)
- Run the database as a separate SQL Server Windows Container
- Mock the database with mock data based on in-memory lists and objects (UseMockData=true)
In the third mode, access to a database is simulated in the sample code by using in-memory objects. However, this scenario is just for testing the application in case you want to isolate the application from the real database for tests or for demo purposes.
For production environments, we encourage you to deploy the databases using one of the following options:
- Azure SQL Database (Recommended for eShopModernizing as it is a simple SQL DB)
- Azure SQL Database Managed Instance
- SQL Server VM in Azure
In any case, this series of walkthroughs will demonstrate the simplest migration path, where you move existing assets to run in a container without any code changes at all. This path is appropriate for applications that are monolithic or standalone.
Before you go ahead and containerize the apps in the later walkthroughs, you should run the apps as-is. To do so in the development environment, you can simply load the solution, select the “Set as Startup Project” application project to the app you want to run, and run the application with F5 as a standalone application on IIS Express.
In a first attempt configuration, you can run the application by using mock data, meaning that will generate sample data and store it into in-memory lists and objects, no real database here. You can enable/disable that with the following variable in the web.config settings:
<appSettings> <add key="UseMockData" value="true"/> </appSettings>
You can run and test the apps right away in Visual Studio by just opening the solutions and hitting F5. The data will get populated either from a SQL Server localdb or from objects in-memory if the configuration is set to "UseMockData = True".
**IMPORTANT: ** Note that when running the app in standalone mode in Windows (like now from Visual Studio) you configure that setting from the web.config file. However, when running the app in a Windows Container (in future steps) you will configure that "UseMockData = True/False" in the environment variables specified in the docker-compose.override.yml or comparable metadata files from Kubernetes or Service Fabric.
In this configuration, instead of a persistent storage database, the application uses a fake service or fake implementation of data access classes to return data. The way it is implemented is pretty much decoupled thanks to the use of Dependency Injection techniques using Autofac (https://autofac.org/) as an inversion of control (IoC) container. Using Dependency Injection (DI), for this case you can configure the application to use the fake data or the live catalog database. (We will explain more about DI shortly.) The startup code reads a useMockData setting from the web.config files, and configures the Autofac container to inject either the fake data implementation or the live catalog database access implementation.
Most of the techniques used in this application should be very familiar to anyone who has used MVC or Web Forms. However, they might be unfamiliar for some developers.
Note that we’re explaining DI approaches so you can explore the application in different ways. DI is definitely not a requirement for using Windows Containers or containers in general. They are orthogonal subjects, but both are best practices for modernized applications. Even when it might be obvious for many people, it is important to highlight that you don’t need to change the code of your existing applications and support DI in order to containerize your application. In most cases you shouldn’t need to modify your C# code. DI inverts the typical object-oriented strategy of writing classes that allocate all needed resources. Instead, classes request their dependencies from a service container. The advantage of DI is that you can replace implementations of interfaces with separate implementations, like in this case replacing an external database access with fakes (mocks) to support testing or other scenarios.
The DI container uses the web.config useMockData configuration to control whether to use the fake catalog data or the live data from the running service. The application registers an HttpModule object that builds the container and registers a pre-request handler to inject dependencies. You can see that code in the Modules/ApplicationModule.cs
file, which is pretty similar for the MVC and the Web Forms apps.
Here is an example ApplicationModule
:
public class ApplicationModule : Module
{
private bool useMockData;
public ApplicationModule(bool useMockData)
{
this.useMockData = useMockData;
}
protected override void Load(ContainerBuilder builder)
{
if (this.useMockData)
{
builder.RegisterType<CatalogServiceMock>()
.As<ICatalogService>()
.SingleInstance();
}
else
{
builder.RegisterType<CatalogService>()
.As<ICatalogService>()
.InstancePerLifetimeScope();
}
builder.RegisterType<CatalogDBContext>()
.InstancePerLifetimeScope();
builder.RegisterType<CatalogDBInitializer>()
.InstancePerLifetimeScope();
builder.RegisterType<CatalogItemHiLoGenerator>()
.SingleInstance();
}
}
You can see in that code how you can have different implementations injected in the application constructors when instancing an object of the type ICatalogService
. When the useMockData is true, it is registering a class named CatalogServiceMock
but a class named CatalogService
when the flag is false.
In the case of the MVC application, the ICatalogService
implementation is injected into the Controllers constructors (DI based on constructors), like in this example CatalogController
:
public class CatalogController : Controller
{
private ICatalogService service;
public CatalogController(ICatalogService service)
{
this.service = service;
}
//...
}
In the case of the WebForms application, the ICatalogService implementation is injected in page properties (DI based on properties), like in this case (it could also use constructors, it is a matter of preference):
public partial class _Default : Page
{
//...
public ICatalogService CatalogService { get; set; }
//...
}
- Home
- Release notes
- e-books
-
MVC & Web Forms Samples
- Tour of the "legacy" ASP.NET web apps to modernize
- How to containerize the .NET Framework web apps with Windows Containers and Docker
- Publishing your Windows Container images into a Docker Registry
- Deploying the Apps to Azure Web Apps for Containers
- Deploying the Apps to ACI (Azure Container Instances)
- Deploying your Windows Containers based app into Azure VMs (Including CI CD)
- Deploying into local Kubernetes in Windows 10 and Docker for Windows development environment
- How to deploy your Windows Containers based apps into Kubernetes in Azure Container Service (Including CI CD)
- How to add authentication authorization with Azure Active Directory
- How to migrate the SQL database to Azure with the Azure Database Migration Service
- Using Application Insights in eShopOnContainers
- N-Tier sample: WinForms app and WFC service
- ASP.NET to Azure App Service Migration Workshop