You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* address ch1 feedback
* ch2 feedback
* ch4 updates
* remove static variable from Startup
* Update docs/architecture/porting-existing-aspnet-apps/configuration-differences.md
Co-authored-by: David Pine <[email protected]>
* Update docs/architecture/porting-existing-aspnet-apps/middleware-modules-handlers.md
Co-authored-by: David Pine <[email protected]>
* Update docs/architecture/porting-existing-aspnet-apps/understand-update-dependencies.md
Co-authored-by: David Pine <[email protected]>
Co-authored-by: David Pine <[email protected]>
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/configuration-differences.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ public class TestModel : PageModel
54
54
55
55
**Figure 2-2.** Accessing configuration values with `IConfiguration`.
56
56
57
-
Using the options pattern, settings access is similar but is strongly typed and more specific to the setting(s) needed by the consuming class, as Figure 2-3 demonstrates.
57
+
Using the [options pattern](/dotnet/core/extensions/options), settings access is similar but is strongly typed and more specific to the setting(s) needed by the consuming class, as Figure 2-3 demonstrates.
When considering how to port an app's configuration settings from .NET Framework to .NET Core, the first step is to identify all of the configuration settings that are being used. Most of these will be in the *web.config* file in the app's root folder, but some apps expect settings to be found in the shared *machine.config* file as well.
95
+
When considering how to port an app's configuration settings from .NET Framework to .NET Core, the first step is to identify all of the configuration settings that are being used. Most of these will be in the *web.config* file in the app's root folder, but some apps expect settings to be found in the shared *machine.config* file as well. These settings will include elements of the `appSettings` element, the `connectionStrings` element, and any custom configuration elements as well. In .NET Core, all of these settings are typically stored in the *appsettings.json* file.
96
96
97
97
Once all settings in the config files have been cataloged, the next step should be to identify where and how the settings are used in the app itself. If some settings aren't being used, these can probably be omitted from the migration. For each setting, note all of the places it's being used so you can be sure you don't miss any when you migrate the code.
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/example-migration-eshop.md
+5-12Lines changed: 5 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@ Most of the incompatible types refer to `Controller` and various related attribu
53
53
54
54
## Update project files and NuGet reference syntax
55
55
56
-
Next, migrate from the older *.csproj* file structure to the newer, simpler structure introduced with .NET Core. In doing so, you'll also migrate from using a *packages.config* file for NuGet references to using `<PackageReference>` elements in the project file.
56
+
Next, migrate from the older *.csproj* file structure to the newer, simpler structure introduced with .NET Core. In doing so, you'll also migrate from using a *packages.config* file for NuGet references to using `<PackageReference>` elements in the project file. Old-style project files may also use `<PackageReference>` elements, so it usually makes sense to migrate all NuGet package references to this format first, before upgrading to the new project file format.
57
57
58
58
The original project's *eShopLegacyMVC.csproj* file is 418 lines long. A sample of the project file is shown in Figure 4-6. To offer a sense of its overall size and complexity, the right side of the image contains a miniature view of the entire file.
59
59
@@ -69,7 +69,7 @@ In addition to the C# project file, NuGet dependencies are stored in a separate
69
69
70
70
**Figure 4-7.** The *packages.config* file.
71
71
72
-
After upgrading to the new *.csproj* file format, you can migrate *packages.config* in class library projects using Visual Studio. This functionality doesn't work with ASP.NET projects, however. [Learn more about migrating *packages.config* to `<PackageReference>` in Visual Studio](/nuget/consume-packages/migrate-packages-config-to-package-reference). If you have a large number of projects to migrate, [this community tool may help](https://github.com/MarkKharitonov/NuGetPCToPRMigrator).
72
+
You can migrate *packages.config* in class library projects using Visual Studio. This functionality doesn't work with ASP.NET projects, however. [Learn more about migrating *packages.config* to `<PackageReference>` in Visual Studio](/nuget/consume-packages/migrate-packages-config-to-package-reference). If you have a large number of projects to migrate, [this community tool may help](https://github.com/MarkKharitonov/NuGetPCToPRMigrator). If you're using a tool to migrate the project file to the new format, you should do that after you've finished migrating all NuGet references to use `<PackageReverence>`.
73
73
74
74
## Create new ASP.NET Core project
75
75
@@ -307,20 +307,13 @@ Building again reveals one more error loading jQuery Validation on the *Create*
Thelastthingtofixintheviewsisthereferenceto `Session` todisplayhowlongtheapphasbeenrunning, andonwhichmachine. Wecandisplaythisdatadirectlyinthesite's *_Layout.cshtml* by using `System.Environment.MachineName` and `System.Diagnostics.Process.GetCurrentProcess().StartTime`:
318
311
319
312
```razor
320
313
<sectionclass="col-sm-6">
321
314
<imgclass="esh-app-footer-text hidden-xs"src="~/images/main_footer_text.png"width="335"height="26"alt="footer text image"/>
@@ -442,7 +435,7 @@ public void ConfigureServices(IServiceCollection services)
442
435
}
443
436
```
444
437
445
-
TheprecedingcodeistheminimalconfigurationrequiredtogetMVCfeaturesworking. Therearemanyadditionalfeaturesthatcanbeconfiguredfromthiscall, butfornowthiswillsufficetobuildtheapp. Runningitnowroutesthedefaultrequestproperly, butsincewe've not yet configured DI, an error occurs while activating `CatalogController`, because no implementation of type `ICatalogService` has been provided yet. We'llreturntoconfigureMVCfurtherinamoment. Fornow, let's migrate the app'sdependencyinjection.
438
+
TheprecedingcodeistheminimalconfigurationrequiredtogetMVCfeaturesworking. Therearemanyadditionalfeaturesthatcanbeconfiguredfromthiscall (someofwhicharedetailedlaterinthischapter), butfornowthiswillsufficetobuildtheapp. Runningitnowroutesthedefaultrequestproperly, butsincewe've not yet configured DI, an error occurs while activating `CatalogController`, because no implementation of type `ICatalogService` has been provided yet. We'llreturntoconfigureMVCfurtherinamoment. Fornow, let's migrate the app'sdependencyinjection.
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/hosting-differences.md
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -11,11 +11,12 @@ ASP.NET MVC apps are hosted in IIS, and may rely on IIS configuration for their
11
11
12
12
[ASP.NET Core apps can run on a number of different servers](/aspnet/core/fundamentals/servers/). The default cross platform server, Kestrel, is a good default choice. Apps running in Kestrel can be hosted by IIS, running in a separate process. On Windows, apps can also run in process on IIS or using HTTP.sys. Kestrel is generally recommended for best performance. HTTP.sys can be used in scenarios where the app is exposed to the Internet and required capabilities are supported by HTTP.sys but not Kestrel.
13
13
14
-
Kestrel does not have an equivalent to IIS modules (though apps hosted in IIS can still take advantage of IIS modules). To achieve equivalent behavior, middleware configured in the ASP.NET Core app itself is typically used.
14
+
Kestrel does not have an equivalent to IIS modules (though apps hosted in IIS can still take advantage of IIS modules). To achieve equivalent behavior, [middleware](/aspnet/core/fundamentals/middleware/) configured in the ASP.NET Core app itself is typically used.
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/identify-migration-sequence.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -56,8 +56,8 @@ Watch an overview of how to employ this approach in this [dotNetConf presentatio
56
56
57
57
- Migrate third-party NuGet dependencies
58
58
- Migrate apps to use new *.csproj* file format
59
-
- Migrate apps to ASP.NET Core (targeting .NET Framework)
60
59
- Update internal NuGet dependencies to .NET Standard
60
+
- Migrate apps to ASP.NET Core (targeting .NET Framework)
61
61
- Update all apps to target .NET Core 3.1
62
62
63
63
When automating a large suite of apps, it helps significantly if they follow consistent coding guidelines and project organization. Automation efforts rely on this consistency to be effective. In addition to parsing and migrating project files, common code patterns can be migrated automatically. Some code pattern examples include differences in how controller actions are declared or how they return results.
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/incremental-migration-strategies.md
+10-8Lines changed: 10 additions & 8 deletions
Original file line number
Diff line number
Diff line change
@@ -7,12 +7,20 @@ ms.date: 11/13/2020
7
7
8
8
# Strategies for migrating incrementally
9
9
10
-
The biggest challenge with migrating any large app is determining how to break the process into smaller tasks. There are several strategies that can be applied for this purpose, including breaking the app into horizontal layers such as UI, data access, business logic, or breaking up the app into separate, smaller apps. Another strategy is to upgrade some or all of the app to different framework versions on the way to a recent .NET Core release. One approach you could use, is to migrate [vertical slices](https://deviq.com/practices/vertical-slices) of the app, rather than attempting to migrate one horizontal layer at a time. Let's consider each of these different approaches.
10
+
The biggest challenge with migrating any large app is determining how to break the process into smaller tasks. There are several strategies that can be applied for this purpose, including breaking the app into horizontal layers such as UI, data access, business logic, or breaking up the app into separate, smaller apps. Another strategy is to upgrade some or all of the app to different framework versions on the way to a recent .NET Core release. One approach you could use is to migrate [vertical slices](https://deviq.com/practices/vertical-slices) of the app, rather than attempting to migrate one horizontal layer at a time. Let's consider each of these different approaches.
11
11
12
-
Consider the challenge of migrating a large ASP.NET 4.5 app. One approach is to migrate the entire app directly from .NET Framework 4.5 to .NET Core 3.1. However, this approach needs to account for every breaking change between the two frameworks and versions, which are substantial.
12
+
## Migrating slice by slice
13
+
14
+
One successful approach to migrating is to identify vertical slices of functionality and migrate them to the target platform one by one. The first step is to create a new ASP.NET Core 3.1 or 5 app. Next, identify the individual page or API endpoint that will be migrated first. Build out just the necessary functionality to support this one route in the ASP.NET Core app. Then use HTTP rewriting and/or a reverse proxy to start sending requests for these pages or endpoints to the new app rather than the ASP.NET app. This approach is well-suited to API projects, but can also work for many MVC apps.
15
+
16
+
When migrating slice by slice, the entire stack of the individual API endpoint or requested route is recreated in the new project or solution. The very first such slice typically requires the most effort, since it will typically need several projects to be created and decisions to be made about data access and solution organization. Once the first slice's functionality mirrors the existing app's, it can be deployed and the existing app can redirect to it or simply be removed. This approach is then repeated until the entire app has been ported to the new structure.
17
+
18
+
Some specific guidance on how to follow this strategy using IIS is covered in [Chapter 5, Deployment Scenarios](deployment-scenarios.md).
13
19
14
20
## Migrating layer by layer
15
21
22
+
Consider the challenge of migrating a large ASP.NET 4.5 app. One approach is to migrate the entire app directly from .NET Framework 4.5 to .NET Core 3.1. However, this approach needs to account for every breaking change between the two frameworks and versions, which are substantial. Performing this work on one project at a time provides a set of stepping stones so that the entire solution doesn't need to be moved at once.
23
+
16
24
One recent addition to the .NET ecosystem that helps with interoperability between different .NET frameworks is [.NET Standard](https://dotnet.microsoft.com/platform/dotnet-standard). .NET Standard allows libraries to build against the agreed upon set of common APIs, ensuring they can be used in any .NET app. .NET Standard 2.0 is notable because it covers most base class library functionality used by most .NET Framework and .NET Core apps. Unfortunately, the earliest version of .NET with support for .NET Standard 2.0 is .NET Framework 4.6.1, and there are a number of updates in .NET Framework 4.8 that make it a compelling choice for initial upgrades.
17
25
18
26
One approach to incrementally upgrade a .NET Framework 4.5 system layer-by-layer is to first update its class library dependencies to .NET Framework 4.8. Then, modify these libraries to be .NET Standard class libraries. Use multi-targeting and conditional compilation, if necessary. This step can be helpful in scenarios where app dependencies require .NET Framework and cannot easily be ported directly to use .NET Standard and .NET Core. Since .NET Framework libraries can be consumed by ASP.NET Core 2.1 apps, the next step is to migrate some or all of the web functionality of the app to ASP.NET Core 2.1 (as described in the [previous chapter](choose-net-core-version.md)). This is a "bottom up" approach, starting with low level class library dependencies and working up to the web app entry point.
@@ -25,12 +33,6 @@ Instead of a "bottom up" approach, another alternative is to start with the web
25
33
26
34
Instead of a "bottom up" approach, another alternative is to start with the web app (or even the entire solution) and use an automated tool to assist with the upgrade. The [.NET Upgrade Assistant tool](https://aka.ms/dotnet-upgrade-assistant) can be used to help upgrade .NET Framework apps to .NET Core / .NET 5. It automates many of the common tasks related to upgrading apps, such as modifying project file format, setting appropriate target frameworks, updating NuGet dependencies, and more.
27
35
28
-
## Migrating slice by slice
29
-
30
-
Another approach to the migration would be to identify vertical slices of functionality, and migrate them to the target platform one by one. The first step would be to create a new ASP.NET Core 3.1 or 5 app. Next, identify the individual page or API endpoint that will be migrated first. Build out just the necessary functionality to support this one route in the ASP.NET Core app. Then use HTTP rewriting and/or a reverse proxy to start sending requests for these pages or endpoints to the new app rather than the ASP.NET app.
31
-
32
-
Some specific guidance on how to follow this strategy using IIS is covered in [Chapter 5, Deployment Scenarios](deployment-scenarios.md).
33
-
34
36
## References
35
37
36
38
-[What is .NET Standard?](https://dotnet.microsoft.com/platform/dotnet-standard)
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/middleware-modules-handlers.md
+57Lines changed: 57 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,63 @@ ASP.NET Core defines a request pipeline in each app's `Configure` method. This r
21
21
22
22
Behavior in an ASP.NET MVC app that uses HTTP modules is probably best suited to [custom middleware](/aspnet/core/fundamentals/middleware/?preserve-view=true&view=aspnetcore-3.1). Custom HTTP handlers can be replaced with custom routes or endpoints that respond to the same path.
23
23
24
+
## Accessing HttpContext
25
+
26
+
Many .NET apps reference the current request's context through `HttpContext.Current`. This static access can be a common source of problems with testing and other code usage outside of individual requests. When building ASP.NET Core apps, access to the current HttpContext should be provided as a method parameter on middleware, as this sample demonstrates:
27
+
28
+
```csharp
29
+
publicclassMiddleware
30
+
{
31
+
privatereadonlyRequestDelegate_next;
32
+
33
+
publicMiddleware(RequestDelegatenext)
34
+
{
35
+
_next=next;
36
+
}
37
+
38
+
publicTaskInvoke(HttpContexthttpContext)
39
+
{
40
+
return_next(httpContext);
41
+
}
42
+
}
43
+
```
44
+
45
+
Similarly, ASP.NET Core filters pass a context argument to their methods, from which the current HttpContext can be accessed:
If you have components or services that require access to HttpContext, rather than using a static call like `HttpContext.Current` you should instead use constructor dependency injection and the [IHttpContextAccessor](https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.http.ihttpcontextaccessor) interface:
Copy file name to clipboardExpand all lines: docs/architecture/porting-existing-aspnet-apps/migrate-aspnet-core-2-1.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ ms.date: 11/13/2020
7
7
8
8
# Migrate to ASP.NET Core 2.1
9
9
10
-
ASP.NET Core 2.1 is an interesting release because it's the only currently supported .NET Core release to support both .NET Core and .NET Framework runtimes. As such, it may offer an easier upgrade path for some apps when compared to upgrading all parts of the app to .NET Core at once. As an LTS release, support for .NET Core 2.1 will continue through August 2021. Support for ASP.NET Core 2.1 running on .NET Framework will continue for as long as its underlying .NET Framework is supported.
10
+
ASP.NET Core 2.1 is an interesting release because it's the only currently supported ASP.NET Core release to support both .NET Core and .NET Framework runtimes. As such, it may offer an easier upgrade path for some apps when compared to upgrading all parts of the app to .NET Core at once. As an LTS release, support for .NET Core 2.1 will continue through August 2021. Support for ASP.NET Core 2.1 running on .NET Framework will continue for as long as its underlying .NET Framework is supported.
11
11
12
12
## Should apps run on .NET Framework with ASP.NET Core 2.1
0 commit comments