Skip to main content

Outline

At a glance:
  • Deprecation occurs due to framework evolution, improved design, standardization, and security enhancements.
  • Unaddressed deprecated code causes build failures, runtime errors, performance issues, and increased technical debt.
  • Modern replacements include appsettings.json, DI, middleware, and ASP.NET Core patterns.

Introduction

This module focuses on a critical task during the migration from Optimizely CMS 11 to CMS 12: identifying and systematically removing deprecated APIs and outdated coding patterns. The transition to ASP.NET Core requires careful updates to prevent runtime errors, performance degradation, and security vulnerabilities.

Why Deprecation Occurs and Why it Matters

Reasons for deprecation

  • Framework evolution: ASP.NET Core introduces dependency injection, middleware, and other paradigms that replace older patterns.
  • Improved design and performance: New APIs are cleaner, faster, and more secure than their predecessors.
  • Standardization: Aligns the platform with .NET standards and community best practices.
  • Security enhancements: Replace older APIs with more secure alternatives that address known vulnerabilities.

Impact of unaddressed deprecations

Important: Leaving deprecated code unaddressed is not a "fix it later" decision - it compounds over time and makes each subsequent upgrade harder than the last.

  • Build failures: Breaking changes prevent compilation entirely.
  • Runtime errors: Deprecated code may fail silently or throw at runtime in ways that are hard to trace.
  • Performance degradation: Older patterns are not optimized for ASP.NET Core's execution model.
  • Increased technical debt: Harder to maintain, test, and upgrade solutions over time.
  • Security risks: Known vulnerabilities in deprecated APIs may persist unpatched.

Common Deprecated APIs and Patterns (CMS 11 to CMS 12)

The following accordion covers the most commonly encountered deprecated patterns and their CMS 12 replacements.

Deprecated patterns by category

Select a category to expand the deprecated pattern and its modern replacement.

1. Configuration management - web.config
  • Deprecated: Using web.config sections for application settings and connection strings.
  • Replacement: appsettings.json, environment variables, and IConfiguration.
  • Action: Move connection strings to the ConnectionStrings section in appsettings.json and inject IConfiguration where settings are consumed.
2. Dependency injection - ServiceLocator.Current
  • Deprecated: ServiceLocator.Current.GetInstance<T>() for resolving services.
  • Replacement: ASP.NET Core DI container with constructor injection.
C#
// Deprecated (CMS 11) // var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); // Modern (CMS 12) public class MyService { private readonly IContentLoader _contentLoader; public MyService(IContentLoader contentLoader) // Injected via DI { _contentLoader = contentLoader; } // ... use _contentLoader }
3. HTTP context - System.Web.HttpContext.Current
  • Deprecated: Static access to HttpContext.Current.
  • Replacement: Inject IHttpContextAccessor or use HttpContext directly in controllers.
C#
// Deprecated (CMS 11) // var currentUrl = HttpContext.Current.Request.Url; // Modern (CMS 12) - via IHttpContextAccessor public class MyHttpContextService { private readonly IHttpContextAccessor _httpContextAccessor; public MyHttpContextService(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public Uri GetCurrentUrl() { return _httpContextAccessor.HttpContext?.Request.GetUri(); } }
4. Routing and URL management
  • Legacy routing: Use Endpoint Routing (MapContent(), MapControllerRoute()) instead of the old RouteCollection pattern.
  • URL rewriting: Use ASP.NET Core URL Rewriting Middleware instead of web.config rewrite rules.
5. Optimizely-specific APIs
  • IInitializableModule: Methods now receive InitializationEngine, IServiceCollection, or IApplicationBuilder for ASP.NET Core startup.
  • Content loading and saving: Some IContentLoader and IContentRepository method signatures have changed - verify against current documentation.
  • Event handling: Updated to match the ASP.NET Core event model.
  • UI components: Legacy controls from System.Web.UI may need full reimplementation using Razor or equivalent.

Tools and Techniques for Identification

A combination of automated tooling and manual review is the most reliable approach to surfacing deprecated usage across a codebase.

  • Compiler warnings: Observe all warnings after upgrading packages - deprecated API usage typically surfaces here first.
  • Static analysis: Roslyn analyzers, ReSharper/Rider, and the .NET Upgrade Assistant can identify problematic patterns automatically.
  • Manual review: Search for deprecated namespaces (for example, System.Web), consult official migration guides, and review community forums for known CMS 11 to CMS 12 patterns.

Pro tip: Run the .NET Upgrade Assistant early in the migration planning phase, before touching any code. It produces a structured report of breaking changes and deprecated usage that can directly inform your migration backlog and effort estimates.

Strategies for Removal and Replacement

  • Prioritize by impact: Fix breaking changes that prevent compilation first, then address less critical deprecated code in order of risk.
  • Find modern equivalents: Use official Optimizely and Microsoft docs, extension methods, or middleware replacements as the authoritative source for replacements.
  • Incremental refactoring: Refactor feature by feature with tests in place at each step to catch regressions before they accumulate.

Note: "Incremental refactoring" means commit, test, and verify at each step - not "refactor everything then test at the end." The latter strategy removes the safety net and makes root-cause analysis after failures much harder.

Conclusion

Identifying and removing deprecated APIs is essential for a successful migration to Optimizely CMS 12 and Commerce 14. This process reduces technical debt, improves performance, and aligns the solution with modern .NET practices.

The investment is front-loaded but pays dividends across the full lifetime of the solution - each deprecated pattern removed is one fewer obstacle to future upgrades, security patches, and performance improvements.