[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-microsoft-migrating-mvc-session-state":3,"mdc-8glxdb-key":35,"related-repo-microsoft-migrating-mvc-session-state":2383,"related-org-microsoft-migrating-mvc-session-state":2478},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":33,"mdContent":34},"migrating-mvc-session-state","migrate ASP.NET session state to Core","Migrates ASP.NET Framework session state, TempData, and application state to ASP.NET Core equivalents. Converts HttpSessionState to ISession with distributed cache backend, migrates TempData from session-based to cookie-based provider, and replaces HttpContext.Application and HttpRuntime.Cache with DI-based IMemoryCache or IDistributedCache. Use when upgrading MVC or WebAPI apps that use Session[], TempData[], HttpContext.Application[], HttpRuntime.Cache, or static state patterns. Also triggers for assessment signals UsesSession, UsesTempData, UsesApplicationState, UsesStaticState, and UsesInProcSession.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"microsoft","Microsoft","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmicrosoft.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Modernization","modernization","tag",{"name":17,"slug":18,"type":15},"ASP.NET Core","aspnet-core",{"name":20,"slug":21,"type":15},".NET","net",{"name":23,"slug":24,"type":15},"Migration","migration",7,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fupgrade-agent-plugins","2026-07-03T16:30:52.816251",null,1,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":28},[],"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fupgrade-agent-plugins\u002Ftree\u002FHEAD\u002Fplugins\u002Fupgrade-agent\u002Fextenders\u002Fupgrade-dotnet\u002Fupgrade\u002Fskills\u002Flazy\u002Fweb\u002Fmvc\u002Fmigrating-mvc-session-state","---\r\nname: migrating-mvc-session-state\r\ndescription: >\r\n  Migrates ASP.NET Framework session state, TempData, and application state to ASP.NET Core\r\n  equivalents. Converts HttpSessionState to ISession with distributed cache backend, migrates\r\n  TempData from session-based to cookie-based provider, and replaces HttpContext.Application and\r\n  HttpRuntime.Cache with DI-based IMemoryCache or IDistributedCache. Use when upgrading MVC or\r\n  WebAPI apps that use Session[], TempData[], HttpContext.Application[], HttpRuntime.Cache,\r\n  or static state patterns. Also triggers for assessment signals UsesSession, UsesTempData,\r\n  UsesApplicationState, UsesStaticState, and UsesInProcSession.\r\nmetadata:\r\n  traits: .NET|CSharp|VisualBasic|DotNetCore\r\n  discovery: lazy\r\n---\r\n\r\n# ASP.NET MVC Session and State Migration\r\n\r\n## Overview\r\n\r\nMigrate session state, TempData, and application-level state from ASP.NET Framework to ASP.NET Core. ASP.NET Core has no in-process session by default — session requires explicit opt-in via `AddSession()` plus a distributed cache provider. Getting this wrong causes silent data loss at scale or on app restart.\r\n\r\n> **Adapter overlay:** If the `aspnet-system-web-adapters` skill is loaded, its guidance takes precedence for `HttpSessionState` replacement during scaffold and migrate phases — the adapter provides a session shim that defers full migration. TempData and Application State are **not** covered by adapters; migrate them directly using this skill.\r\n\r\n> **Related skill:** `migrating-global-asax` covers `Session_Start`\u002F`Session_End` event migration to session middleware registration.\r\n\r\n## Workflow\r\n\r\nTrack progress across these steps:\r\n\r\n```\r\nMigration Progress:\r\n- [ ] Step 1: Audit state usage across project\r\n- [ ] Step 2: Register session services and middleware\r\n- [ ] Step 3: Migrate HttpSessionState to ISession\r\n- [ ] Step 4: Migrate TempData provider\r\n- [ ] Step 5: Replace Application state and HttpRuntime.Cache\r\n- [ ] Step 6: Replace static state with DI singletons\r\n- [ ] Step 7: Verify serialization and data round-trips\r\n```\r\n\r\n### Step 1: Audit State Usage\r\n\r\nSearch the codebase for all state-related patterns. Identify which migration paths apply:\r\n\r\n| Pattern to find | Migration path |\r\n|---|---|\r\n| `Session[` , `HttpContext.Session` | Session State (Step 3) |\r\n| `TempData[` , `ITempDataProvider` | TempData (Step 4) |\r\n| `HttpContext.Application[` , `HttpApplicationState` | Application State (Step 5) |\r\n| `HttpRuntime.Cache` , `HttpContext.Cache` | Application State (Step 5) |\r\n| `static` fields holding request\u002Fuser state | Static State (Step 6) |\r\n\r\nSkip steps that have no matching patterns. If the adapter overlay applies, defer Step 3 and proceed with Steps 4–6.\r\n\r\n### Step 2: Register Session Services and Middleware\r\n\r\nSkip this step if no `Session[` usage was found in Step 1 or if the adapter overlay handles session.\r\n\r\nAdd session services and a distributed cache in `Program.cs`:\r\n\r\n**Before (Framework — implicit, no registration needed):**\r\n```xml\r\n\u003C!-- web.config — session was on by default -->\r\n\u003CsessionState mode=\"InProc\" timeout=\"20\" \u002F>\r\n```\r\n\r\n**After (Core — explicit opt-in required):**\r\n```csharp\r\n\u002F\u002F Program.cs — service registration\r\nbuilder.Services.AddDistributedMemoryCache(); \u002F\u002F Dev only — replace for production\r\nbuilder.Services.AddSession(options =>\r\n{\r\n    options.IdleTimeout = TimeSpan.FromMinutes(20);\r\n    options.Cookie.HttpOnly = true;\r\n    options.Cookie.IsEssential = true;\r\n});\r\n\r\n\u002F\u002F Middleware pipeline — order matters: after routing, before endpoints\r\napp.UseSession();\r\n```\r\n\r\n⚠️ **Data loss risk:** `AddDistributedMemoryCache()` stores data in-process and loses everything on restart. For production, replace with Redis or SQL Server:\r\n\r\n```csharp\r\n\u002F\u002F Redis (recommended for multi-instance deployments)\r\nbuilder.Services.AddStackExchangeRedisCache(options =>\r\n{\r\n    options.Configuration = builder.Configuration.GetConnectionString(\"Redis\");\r\n});\r\n\r\n\u002F\u002F SQL Server (when Redis is unavailable)\r\nbuilder.Services.AddDistributedSqlServerCache(options =>\r\n{\r\n    options.ConnectionString = builder.Configuration.GetConnectionString(\"SessionDb\");\r\n    options.SchemaName = \"dbo\";\r\n    options.TableName = \"Sessions\";\r\n});\r\n```\r\n\r\n### Step 3: Migrate HttpSessionState to ISession\r\n\r\nASP.NET Core `ISession` has a fundamentally different API. Session values are byte arrays — there is no automatic object serialization.\r\n\r\n**Before (Framework):**\r\n```csharp\r\n\u002F\u002F Reading — returns object, cast required\r\nvar cart = (ShoppingCart)Session[\"Cart\"];\r\nvar name = Session[\"UserName\"] as string;\r\n\r\n\u002F\u002F Writing — any serializable object\r\nSession[\"Cart\"] = cart;\r\nSession[\"UserName\"] = \"Alice\";\r\n\r\n\u002F\u002F Removing\r\nSession.Remove(\"Cart\");\r\nSession.Abandon();\r\n```\r\n\r\n**After (Core):**\r\n```csharp\r\n\u002F\u002F Reading — use typed extension methods\r\nvar cart = HttpContext.Session.Get\u003CShoppingCart>(\"Cart\");\r\nvar name = HttpContext.Session.GetString(\"UserName\");\r\n\r\n\u002F\u002F Writing — must serialize explicitly\r\nHttpContext.Session.Set(\"Cart\", cart);\r\nHttpContext.Session.SetString(\"UserName\", \"Alice\");\r\n\r\n\u002F\u002F Removing\r\nHttpContext.Session.Remove(\"Cart\");\r\nHttpContext.Session.Clear();\r\n```\r\n\r\nThe built-in `ISession` only provides `GetString`\u002F`SetString` and `GetInt32`\u002F`SetInt32`. For complex objects, add a JSON extension helper:\r\n\r\n```csharp\r\npublic static class SessionExtensions\r\n{\r\n    public static void Set\u003CT>(this ISession session, string key, T value)\r\n    {\r\n        session.SetString(key, JsonSerializer.Serialize(value));\r\n    }\r\n\r\n    public static T? Get\u003CT>(this ISession session, string key)\r\n    {\r\n        var value = session.GetString(key);\r\n        return value is null ? default : JsonSerializer.Deserialize\u003CT>(value);\r\n    }\r\n}\r\n```\r\n\r\nPlace this in a shared location (e.g., `Extensions\u002FSessionExtensions.cs`). All session reads and writes for complex types must use these helpers — without them, `Get`\u002F`Set` of objects silently fails.\r\n\r\n**Key API differences:**\r\n\r\n| Framework | Core | Notes |\r\n|---|---|---|\r\n| `Session[\"key\"]` | `HttpContext.Session.GetString(\"key\")` | No indexer in Core |\r\n| `Session[\"key\"] = obj` | `HttpContext.Session.Set(\"key\", obj)` | Requires JSON helper |\r\n| `Session.Abandon()` | `HttpContext.Session.Clear()` | `Clear` removes data but keeps session ID |\r\n| `Session.SessionID` | `HttpContext.Session.Id` | Property name change |\r\n| `Session.Count` | `HttpContext.Session.Keys.Count()` | Must enumerate keys |\r\n\r\n### Step 4: Migrate TempData Provider\r\n\r\nTempData API surface is compatible between Framework and Core, but the backing store changed. Framework uses session-based TempData by default; Core uses cookie-based TempData.\r\n\r\n**Cookie TempData (Core default) — no code changes needed if data is small:**\r\n```csharp\r\n\u002F\u002F TempData usage stays the same\r\nTempData[\"Message\"] = \"Item saved successfully\";\r\nvar msg = TempData[\"Message\"] as string;\r\n```\r\n\r\n⚠️ **Silent truncation risk:** Cookie-based TempData is limited to ~4096 bytes total. Large objects stored in TempData will be silently truncated or fail. If TempData stored complex objects in Framework, switch to session-based TempData provider:\r\n\r\n```csharp\r\n\u002F\u002F Program.cs — switch to session-based TempData (requires AddSession)\r\nbuilder.Services.AddControllersWithViews()\r\n    .AddSessionStateTempDataProvider();\r\n```\r\n\r\n**TempData in WebAPI controllers:** TempData never existed in WebAPI. If Framework code used workarounds (e.g., storing values between redirects in a Web API context), replace with query string parameters, response headers, or a distributed cache lookup.\r\n\r\n### Step 5: Replace Application State and HttpRuntime.Cache\r\n\r\nASP.NET Core has no `HttpApplicationState` or `HttpRuntime.Cache`. Replace with dependency-injected services.\r\n\r\n#### Application State → DI Singleton\r\n\r\n**Before (Framework):**\r\n```csharp\r\n\u002F\u002F Writing — typically in Global.asax Application_Start\r\nHttpContext.Application[\"SiteSettings\"] = LoadSettings();\r\nHttpContext.Application.Lock();\r\nHttpContext.Application[\"VisitorCount\"] = (int)HttpContext.Application[\"VisitorCount\"] + 1;\r\nHttpContext.Application.UnLock();\r\n\r\n\u002F\u002F Reading — anywhere\r\nvar settings = HttpContext.Application[\"SiteSettings\"] as SiteSettings;\r\n```\r\n\r\n**After (Core):**\r\n```csharp\r\n\u002F\u002F Define a service to hold shared state\r\npublic class AppStateService\r\n{\r\n    private int _visitorCount;\r\n    public SiteSettings SiteSettings { get; set; } = new();\r\n    public int IncrementVisitors() => Interlocked.Increment(ref _visitorCount);\r\n}\r\n\r\n\u002F\u002F Register as singleton in Program.cs\r\nbuilder.Services.AddSingleton\u003CAppStateService>();\r\n\r\n\u002F\u002F Inject where needed\r\npublic class HomeController : Controller\r\n{\r\n    private readonly AppStateService _appState;\r\n    public HomeController(AppStateService appState) => _appState = appState;\r\n}\r\n```\r\n\r\nApplication state with `Lock()`\u002F`UnLock()` patterns needs thread-safe replacements — use `Interlocked`, `ConcurrentDictionary`, or `lock` in the singleton service. The `Lock()`\u002F`UnLock()` API does not exist in Core.\r\n\r\n#### HttpRuntime.Cache → IMemoryCache\r\n\r\n**Before (Framework):**\r\n```csharp\r\nHttpRuntime.Cache.Insert(\"Products\", products, null,\r\n    DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration);\r\nvar cached = HttpRuntime.Cache[\"Products\"] as List\u003CProduct>;\r\n```\r\n\r\n**After (Core):**\r\n```csharp\r\n\u002F\u002F Program.cs\r\nbuilder.Services.AddMemoryCache();\r\n\r\n\u002F\u002F In controller or service — inject IMemoryCache\r\npublic class ProductService\r\n{\r\n    private readonly IMemoryCache _cache;\r\n    public ProductService(IMemoryCache cache) => _cache = cache;\r\n\r\n    public List\u003CProduct> GetProducts()\r\n    {\r\n        return _cache.GetOrCreate(\"Products\", entry =>\r\n        {\r\n            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);\r\n            return LoadProductsFromDb();\r\n        })!;\r\n    }\r\n}\r\n```\r\n\r\nFor multi-instance deployments, use `IDistributedCache` instead of `IMemoryCache` to avoid cache inconsistencies across instances.\r\n\r\n### Step 6: Replace Static State with DI Singletons\r\n\r\nStatic fields holding per-application state are a common pattern in Framework apps. These work in single-instance deployments but break in multi-instance or container environments.\r\n\r\n**Before (Framework):**\r\n```csharp\r\npublic static class AppConfig\r\n{\r\n    public static string ConnectionString { get; set; }\r\n    public static Dictionary\u003Cstring, object> Settings = new();\r\n}\r\n```\r\n\r\n**After (Core):**\r\n```csharp\r\npublic class AppConfig\r\n{\r\n    public string ConnectionString { get; set; } = string.Empty;\r\n    public Dictionary\u003Cstring, object> Settings { get; } = new();\r\n}\r\n\r\n\u002F\u002F Program.cs\r\nbuilder.Services.AddSingleton\u003CAppConfig>();\r\n```\r\n\r\nConvert all static field access to constructor injection. If static access is needed in non-DI contexts (e.g., extension methods), expose the service through `IServiceProvider` at the call site rather than reverting to static state.\r\n\r\n### Step 7: Verify Serialization and Data Round-Trips\r\n\r\nAfter migrating, verify that data survives a full write-read cycle:\r\n\r\n1. **Session data** — Write a complex object to session, read it back, and confirm all properties match. Test after app restart to confirm the distributed cache retains data (in-memory cache will not).\r\n2. **TempData** — Store a value, perform a redirect, and verify the value is available on the destination page. Test with objects that approach the 4096-byte cookie limit if using cookie-based TempData.\r\n3. **Cache entries** — Verify expiration behavior matches the original `web.config` settings.\r\n\r\nBuild the project and run existing tests to confirm no regressions.\r\n\r\n## Troubleshooting\r\n\r\n| Symptom | Cause | Fix |\r\n|---|---|---|\r\n| `Session` is always null | Missing `app.UseSession()` or `AddSession()` | Add both to `Program.cs` |\r\n| Session data lost on restart | Using `AddDistributedMemoryCache()` in production | Switch to Redis or SQL Server cache |\r\n| TempData silently empty after redirect | Cookie exceeds 4096 bytes | Switch to `AddSessionStateTempDataProvider()` |\r\n| `HttpContext.Application` compile error | No equivalent in Core | Replace with DI singleton (Step 5) |\r\n| `HttpRuntime.Cache` compile error | No equivalent in Core | Replace with `IMemoryCache` (Step 5) |\r\n| Thread-safety issues with singleton state | Missing synchronization | Use `ConcurrentDictionary` or `Interlocked` |\r\n\r\n## Success Criteria\r\n\r\n- Session services registered with `AddSession()` and `UseSession()` in `Program.cs`\r\n- Distributed cache provider configured (not in-memory for production)\r\n- All `Session[\"key\"]` indexer access replaced with `ISession` extension methods\r\n- JSON serialization helper created for complex session objects\r\n- TempData provider chosen and configured based on data size requirements\r\n- `HttpContext.Application` replaced with DI singleton services\r\n- `HttpRuntime.Cache` replaced with `IMemoryCache` or `IDistributedCache`\r\n- Static state fields converted to singleton services with DI\r\n- No `System.Web` session or cache references remain\r\n- Project builds without errors\r\n",{"data":36,"body":40},{"name":4,"description":6,"metadata":37},{"traits":38,"discovery":39},".NET|CSharp|VisualBasic|DotNetCore","lazy",{"type":41,"children":42},"root",[43,52,59,74,112,149,155,160,172,179,184,327,332,338,350,363,371,399,407,513,532,640,646,659,667,760,768,860,902,1009,1037,1045,1208,1214,1219,1227,1258,1269,1300,1310,1316,1335,1342,1349,1419,1426,1567,1624,1630,1637,1668,1675,1821,1842,1848,1853,1860,1905,1912,1979,1992,1998,2003,2046,2051,2057,2255,2261,2377],{"type":44,"tag":45,"props":46,"children":48},"element","h1",{"id":47},"aspnet-mvc-session-and-state-migration",[49],{"type":50,"value":51},"text","ASP.NET MVC Session and State Migration",{"type":44,"tag":53,"props":54,"children":56},"h2",{"id":55},"overview",[57],{"type":50,"value":58},"Overview",{"type":44,"tag":60,"props":61,"children":62},"p",{},[63,65,72],{"type":50,"value":64},"Migrate session state, TempData, and application-level state from ASP.NET Framework to ASP.NET Core. ASP.NET Core has no in-process session by default — session requires explicit opt-in via ",{"type":44,"tag":66,"props":67,"children":69},"code",{"className":68},[],[70],{"type":50,"value":71},"AddSession()",{"type":50,"value":73}," plus a distributed cache provider. Getting this wrong causes silent data loss at scale or on app restart.",{"type":44,"tag":75,"props":76,"children":77},"blockquote",{},[78],{"type":44,"tag":60,"props":79,"children":80},{},[81,87,89,95,97,103,105,110],{"type":44,"tag":82,"props":83,"children":84},"strong",{},[85],{"type":50,"value":86},"Adapter overlay:",{"type":50,"value":88}," If the ",{"type":44,"tag":66,"props":90,"children":92},{"className":91},[],[93],{"type":50,"value":94},"aspnet-system-web-adapters",{"type":50,"value":96}," skill is loaded, its guidance takes precedence for ",{"type":44,"tag":66,"props":98,"children":100},{"className":99},[],[101],{"type":50,"value":102},"HttpSessionState",{"type":50,"value":104}," replacement during scaffold and migrate phases — the adapter provides a session shim that defers full migration. TempData and Application State are ",{"type":44,"tag":82,"props":106,"children":107},{},[108],{"type":50,"value":109},"not",{"type":50,"value":111}," covered by adapters; migrate them directly using this skill.",{"type":44,"tag":75,"props":113,"children":114},{},[115],{"type":44,"tag":60,"props":116,"children":117},{},[118,123,125,131,133,139,141,147],{"type":44,"tag":82,"props":119,"children":120},{},[121],{"type":50,"value":122},"Related skill:",{"type":50,"value":124}," ",{"type":44,"tag":66,"props":126,"children":128},{"className":127},[],[129],{"type":50,"value":130},"migrating-global-asax",{"type":50,"value":132}," covers ",{"type":44,"tag":66,"props":134,"children":136},{"className":135},[],[137],{"type":50,"value":138},"Session_Start",{"type":50,"value":140},"\u002F",{"type":44,"tag":66,"props":142,"children":144},{"className":143},[],[145],{"type":50,"value":146},"Session_End",{"type":50,"value":148}," event migration to session middleware registration.",{"type":44,"tag":53,"props":150,"children":152},{"id":151},"workflow",[153],{"type":50,"value":154},"Workflow",{"type":44,"tag":60,"props":156,"children":157},{},[158],{"type":50,"value":159},"Track progress across these steps:",{"type":44,"tag":161,"props":162,"children":166},"pre",{"className":163,"code":165,"language":50},[164],"language-text","Migration Progress:\n- [ ] Step 1: Audit state usage across project\n- [ ] Step 2: Register session services and middleware\n- [ ] Step 3: Migrate HttpSessionState to ISession\n- [ ] Step 4: Migrate TempData provider\n- [ ] Step 5: Replace Application state and HttpRuntime.Cache\n- [ ] Step 6: Replace static state with DI singletons\n- [ ] Step 7: Verify serialization and data round-trips\n",[167],{"type":44,"tag":66,"props":168,"children":170},{"__ignoreMap":169},"",[171],{"type":50,"value":165},{"type":44,"tag":173,"props":174,"children":176},"h3",{"id":175},"step-1-audit-state-usage",[177],{"type":50,"value":178},"Step 1: Audit State Usage",{"type":44,"tag":60,"props":180,"children":181},{},[182],{"type":50,"value":183},"Search the codebase for all state-related patterns. Identify which migration paths apply:",{"type":44,"tag":185,"props":186,"children":187},"table",{},[188,207],{"type":44,"tag":189,"props":190,"children":191},"thead",{},[192],{"type":44,"tag":193,"props":194,"children":195},"tr",{},[196,202],{"type":44,"tag":197,"props":198,"children":199},"th",{},[200],{"type":50,"value":201},"Pattern to find",{"type":44,"tag":197,"props":203,"children":204},{},[205],{"type":50,"value":206},"Migration path",{"type":44,"tag":208,"props":209,"children":210},"tbody",{},[211,237,261,285,308],{"type":44,"tag":193,"props":212,"children":213},{},[214,232],{"type":44,"tag":215,"props":216,"children":217},"td",{},[218,224,226],{"type":44,"tag":66,"props":219,"children":221},{"className":220},[],[222],{"type":50,"value":223},"Session[",{"type":50,"value":225}," , ",{"type":44,"tag":66,"props":227,"children":229},{"className":228},[],[230],{"type":50,"value":231},"HttpContext.Session",{"type":44,"tag":215,"props":233,"children":234},{},[235],{"type":50,"value":236},"Session State (Step 3)",{"type":44,"tag":193,"props":238,"children":239},{},[240,256],{"type":44,"tag":215,"props":241,"children":242},{},[243,249,250],{"type":44,"tag":66,"props":244,"children":246},{"className":245},[],[247],{"type":50,"value":248},"TempData[",{"type":50,"value":225},{"type":44,"tag":66,"props":251,"children":253},{"className":252},[],[254],{"type":50,"value":255},"ITempDataProvider",{"type":44,"tag":215,"props":257,"children":258},{},[259],{"type":50,"value":260},"TempData (Step 4)",{"type":44,"tag":193,"props":262,"children":263},{},[264,280],{"type":44,"tag":215,"props":265,"children":266},{},[267,273,274],{"type":44,"tag":66,"props":268,"children":270},{"className":269},[],[271],{"type":50,"value":272},"HttpContext.Application[",{"type":50,"value":225},{"type":44,"tag":66,"props":275,"children":277},{"className":276},[],[278],{"type":50,"value":279},"HttpApplicationState",{"type":44,"tag":215,"props":281,"children":282},{},[283],{"type":50,"value":284},"Application State (Step 5)",{"type":44,"tag":193,"props":286,"children":287},{},[288,304],{"type":44,"tag":215,"props":289,"children":290},{},[291,297,298],{"type":44,"tag":66,"props":292,"children":294},{"className":293},[],[295],{"type":50,"value":296},"HttpRuntime.Cache",{"type":50,"value":225},{"type":44,"tag":66,"props":299,"children":301},{"className":300},[],[302],{"type":50,"value":303},"HttpContext.Cache",{"type":44,"tag":215,"props":305,"children":306},{},[307],{"type":50,"value":284},{"type":44,"tag":193,"props":309,"children":310},{},[311,322],{"type":44,"tag":215,"props":312,"children":313},{},[314,320],{"type":44,"tag":66,"props":315,"children":317},{"className":316},[],[318],{"type":50,"value":319},"static",{"type":50,"value":321}," fields holding request\u002Fuser state",{"type":44,"tag":215,"props":323,"children":324},{},[325],{"type":50,"value":326},"Static State (Step 6)",{"type":44,"tag":60,"props":328,"children":329},{},[330],{"type":50,"value":331},"Skip steps that have no matching patterns. If the adapter overlay applies, defer Step 3 and proceed with Steps 4–6.",{"type":44,"tag":173,"props":333,"children":335},{"id":334},"step-2-register-session-services-and-middleware",[336],{"type":50,"value":337},"Step 2: Register Session Services and Middleware",{"type":44,"tag":60,"props":339,"children":340},{},[341,343,348],{"type":50,"value":342},"Skip this step if no ",{"type":44,"tag":66,"props":344,"children":346},{"className":345},[],[347],{"type":50,"value":223},{"type":50,"value":349}," usage was found in Step 1 or if the adapter overlay handles session.",{"type":44,"tag":60,"props":351,"children":352},{},[353,355,361],{"type":50,"value":354},"Add session services and a distributed cache in ",{"type":44,"tag":66,"props":356,"children":358},{"className":357},[],[359],{"type":50,"value":360},"Program.cs",{"type":50,"value":362},":",{"type":44,"tag":60,"props":364,"children":365},{},[366],{"type":44,"tag":82,"props":367,"children":368},{},[369],{"type":50,"value":370},"Before (Framework — implicit, no registration needed):",{"type":44,"tag":161,"props":372,"children":376},{"className":373,"code":374,"language":375,"meta":169,"style":169},"language-xml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- web.config — session was on by default -->\n\u003CsessionState mode=\"InProc\" timeout=\"20\" \u002F>\n","xml",[377],{"type":44,"tag":66,"props":378,"children":379},{"__ignoreMap":169},[380,390],{"type":44,"tag":381,"props":382,"children":384},"span",{"class":383,"line":29},"line",[385],{"type":44,"tag":381,"props":386,"children":387},{},[388],{"type":50,"value":389},"\u003C!-- web.config — session was on by default -->\n",{"type":44,"tag":381,"props":391,"children":393},{"class":383,"line":392},2,[394],{"type":44,"tag":381,"props":395,"children":396},{},[397],{"type":50,"value":398},"\u003CsessionState mode=\"InProc\" timeout=\"20\" \u002F>\n",{"type":44,"tag":60,"props":400,"children":401},{},[402],{"type":44,"tag":82,"props":403,"children":404},{},[405],{"type":50,"value":406},"After (Core — explicit opt-in required):",{"type":44,"tag":161,"props":408,"children":412},{"className":409,"code":410,"language":411,"meta":169,"style":169},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Program.cs — service registration\nbuilder.Services.AddDistributedMemoryCache(); \u002F\u002F Dev only — replace for production\nbuilder.Services.AddSession(options =>\n{\n    options.IdleTimeout = TimeSpan.FromMinutes(20);\n    options.Cookie.HttpOnly = true;\n    options.Cookie.IsEssential = true;\n});\n\n\u002F\u002F Middleware pipeline — order matters: after routing, before endpoints\napp.UseSession();\n","csharp",[413],{"type":44,"tag":66,"props":414,"children":415},{"__ignoreMap":169},[416,424,432,441,450,459,468,476,485,495,504],{"type":44,"tag":381,"props":417,"children":418},{"class":383,"line":29},[419],{"type":44,"tag":381,"props":420,"children":421},{},[422],{"type":50,"value":423},"\u002F\u002F Program.cs — service registration\n",{"type":44,"tag":381,"props":425,"children":426},{"class":383,"line":392},[427],{"type":44,"tag":381,"props":428,"children":429},{},[430],{"type":50,"value":431},"builder.Services.AddDistributedMemoryCache(); \u002F\u002F Dev only — replace for production\n",{"type":44,"tag":381,"props":433,"children":435},{"class":383,"line":434},3,[436],{"type":44,"tag":381,"props":437,"children":438},{},[439],{"type":50,"value":440},"builder.Services.AddSession(options =>\n",{"type":44,"tag":381,"props":442,"children":444},{"class":383,"line":443},4,[445],{"type":44,"tag":381,"props":446,"children":447},{},[448],{"type":50,"value":449},"{\n",{"type":44,"tag":381,"props":451,"children":453},{"class":383,"line":452},5,[454],{"type":44,"tag":381,"props":455,"children":456},{},[457],{"type":50,"value":458},"    options.IdleTimeout = TimeSpan.FromMinutes(20);\n",{"type":44,"tag":381,"props":460,"children":462},{"class":383,"line":461},6,[463],{"type":44,"tag":381,"props":464,"children":465},{},[466],{"type":50,"value":467},"    options.Cookie.HttpOnly = true;\n",{"type":44,"tag":381,"props":469,"children":470},{"class":383,"line":25},[471],{"type":44,"tag":381,"props":472,"children":473},{},[474],{"type":50,"value":475},"    options.Cookie.IsEssential = true;\n",{"type":44,"tag":381,"props":477,"children":479},{"class":383,"line":478},8,[480],{"type":44,"tag":381,"props":481,"children":482},{},[483],{"type":50,"value":484},"});\n",{"type":44,"tag":381,"props":486,"children":488},{"class":383,"line":487},9,[489],{"type":44,"tag":381,"props":490,"children":492},{"emptyLinePlaceholder":491},true,[493],{"type":50,"value":494},"\n",{"type":44,"tag":381,"props":496,"children":498},{"class":383,"line":497},10,[499],{"type":44,"tag":381,"props":500,"children":501},{},[502],{"type":50,"value":503},"\u002F\u002F Middleware pipeline — order matters: after routing, before endpoints\n",{"type":44,"tag":381,"props":505,"children":507},{"class":383,"line":506},11,[508],{"type":44,"tag":381,"props":509,"children":510},{},[511],{"type":50,"value":512},"app.UseSession();\n",{"type":44,"tag":60,"props":514,"children":515},{},[516,518,523,524,530],{"type":50,"value":517},"⚠️ ",{"type":44,"tag":82,"props":519,"children":520},{},[521],{"type":50,"value":522},"Data loss risk:",{"type":50,"value":124},{"type":44,"tag":66,"props":525,"children":527},{"className":526},[],[528],{"type":50,"value":529},"AddDistributedMemoryCache()",{"type":50,"value":531}," stores data in-process and loses everything on restart. For production, replace with Redis or SQL Server:",{"type":44,"tag":161,"props":533,"children":535},{"className":409,"code":534,"language":411,"meta":169,"style":169},"\u002F\u002F Redis (recommended for multi-instance deployments)\nbuilder.Services.AddStackExchangeRedisCache(options =>\n{\n    options.Configuration = builder.Configuration.GetConnectionString(\"Redis\");\n});\n\n\u002F\u002F SQL Server (when Redis is unavailable)\nbuilder.Services.AddDistributedSqlServerCache(options =>\n{\n    options.ConnectionString = builder.Configuration.GetConnectionString(\"SessionDb\");\n    options.SchemaName = \"dbo\";\n    options.TableName = \"Sessions\";\n});\n",[536],{"type":44,"tag":66,"props":537,"children":538},{"__ignoreMap":169},[539,547,555,562,570,577,584,592,600,607,615,623,632],{"type":44,"tag":381,"props":540,"children":541},{"class":383,"line":29},[542],{"type":44,"tag":381,"props":543,"children":544},{},[545],{"type":50,"value":546},"\u002F\u002F Redis (recommended for multi-instance deployments)\n",{"type":44,"tag":381,"props":548,"children":549},{"class":383,"line":392},[550],{"type":44,"tag":381,"props":551,"children":552},{},[553],{"type":50,"value":554},"builder.Services.AddStackExchangeRedisCache(options =>\n",{"type":44,"tag":381,"props":556,"children":557},{"class":383,"line":434},[558],{"type":44,"tag":381,"props":559,"children":560},{},[561],{"type":50,"value":449},{"type":44,"tag":381,"props":563,"children":564},{"class":383,"line":443},[565],{"type":44,"tag":381,"props":566,"children":567},{},[568],{"type":50,"value":569},"    options.Configuration = builder.Configuration.GetConnectionString(\"Redis\");\n",{"type":44,"tag":381,"props":571,"children":572},{"class":383,"line":452},[573],{"type":44,"tag":381,"props":574,"children":575},{},[576],{"type":50,"value":484},{"type":44,"tag":381,"props":578,"children":579},{"class":383,"line":461},[580],{"type":44,"tag":381,"props":581,"children":582},{"emptyLinePlaceholder":491},[583],{"type":50,"value":494},{"type":44,"tag":381,"props":585,"children":586},{"class":383,"line":25},[587],{"type":44,"tag":381,"props":588,"children":589},{},[590],{"type":50,"value":591},"\u002F\u002F SQL Server (when Redis is unavailable)\n",{"type":44,"tag":381,"props":593,"children":594},{"class":383,"line":478},[595],{"type":44,"tag":381,"props":596,"children":597},{},[598],{"type":50,"value":599},"builder.Services.AddDistributedSqlServerCache(options =>\n",{"type":44,"tag":381,"props":601,"children":602},{"class":383,"line":487},[603],{"type":44,"tag":381,"props":604,"children":605},{},[606],{"type":50,"value":449},{"type":44,"tag":381,"props":608,"children":609},{"class":383,"line":497},[610],{"type":44,"tag":381,"props":611,"children":612},{},[613],{"type":50,"value":614},"    options.ConnectionString = builder.Configuration.GetConnectionString(\"SessionDb\");\n",{"type":44,"tag":381,"props":616,"children":617},{"class":383,"line":506},[618],{"type":44,"tag":381,"props":619,"children":620},{},[621],{"type":50,"value":622},"    options.SchemaName = \"dbo\";\n",{"type":44,"tag":381,"props":624,"children":626},{"class":383,"line":625},12,[627],{"type":44,"tag":381,"props":628,"children":629},{},[630],{"type":50,"value":631},"    options.TableName = \"Sessions\";\n",{"type":44,"tag":381,"props":633,"children":635},{"class":383,"line":634},13,[636],{"type":44,"tag":381,"props":637,"children":638},{},[639],{"type":50,"value":484},{"type":44,"tag":173,"props":641,"children":643},{"id":642},"step-3-migrate-httpsessionstate-to-isession",[644],{"type":50,"value":645},"Step 3: Migrate HttpSessionState to ISession",{"type":44,"tag":60,"props":647,"children":648},{},[649,651,657],{"type":50,"value":650},"ASP.NET Core ",{"type":44,"tag":66,"props":652,"children":654},{"className":653},[],[655],{"type":50,"value":656},"ISession",{"type":50,"value":658}," has a fundamentally different API. Session values are byte arrays — there is no automatic object serialization.",{"type":44,"tag":60,"props":660,"children":661},{},[662],{"type":44,"tag":82,"props":663,"children":664},{},[665],{"type":50,"value":666},"Before (Framework):",{"type":44,"tag":161,"props":668,"children":670},{"className":409,"code":669,"language":411,"meta":169,"style":169},"\u002F\u002F Reading — returns object, cast required\nvar cart = (ShoppingCart)Session[\"Cart\"];\nvar name = Session[\"UserName\"] as string;\n\n\u002F\u002F Writing — any serializable object\nSession[\"Cart\"] = cart;\nSession[\"UserName\"] = \"Alice\";\n\n\u002F\u002F Removing\nSession.Remove(\"Cart\");\nSession.Abandon();\n",[671],{"type":44,"tag":66,"props":672,"children":673},{"__ignoreMap":169},[674,682,690,698,705,713,721,729,736,744,752],{"type":44,"tag":381,"props":675,"children":676},{"class":383,"line":29},[677],{"type":44,"tag":381,"props":678,"children":679},{},[680],{"type":50,"value":681},"\u002F\u002F Reading — returns object, cast required\n",{"type":44,"tag":381,"props":683,"children":684},{"class":383,"line":392},[685],{"type":44,"tag":381,"props":686,"children":687},{},[688],{"type":50,"value":689},"var cart = (ShoppingCart)Session[\"Cart\"];\n",{"type":44,"tag":381,"props":691,"children":692},{"class":383,"line":434},[693],{"type":44,"tag":381,"props":694,"children":695},{},[696],{"type":50,"value":697},"var name = Session[\"UserName\"] as string;\n",{"type":44,"tag":381,"props":699,"children":700},{"class":383,"line":443},[701],{"type":44,"tag":381,"props":702,"children":703},{"emptyLinePlaceholder":491},[704],{"type":50,"value":494},{"type":44,"tag":381,"props":706,"children":707},{"class":383,"line":452},[708],{"type":44,"tag":381,"props":709,"children":710},{},[711],{"type":50,"value":712},"\u002F\u002F Writing — any serializable object\n",{"type":44,"tag":381,"props":714,"children":715},{"class":383,"line":461},[716],{"type":44,"tag":381,"props":717,"children":718},{},[719],{"type":50,"value":720},"Session[\"Cart\"] = cart;\n",{"type":44,"tag":381,"props":722,"children":723},{"class":383,"line":25},[724],{"type":44,"tag":381,"props":725,"children":726},{},[727],{"type":50,"value":728},"Session[\"UserName\"] = \"Alice\";\n",{"type":44,"tag":381,"props":730,"children":731},{"class":383,"line":478},[732],{"type":44,"tag":381,"props":733,"children":734},{"emptyLinePlaceholder":491},[735],{"type":50,"value":494},{"type":44,"tag":381,"props":737,"children":738},{"class":383,"line":487},[739],{"type":44,"tag":381,"props":740,"children":741},{},[742],{"type":50,"value":743},"\u002F\u002F Removing\n",{"type":44,"tag":381,"props":745,"children":746},{"class":383,"line":497},[747],{"type":44,"tag":381,"props":748,"children":749},{},[750],{"type":50,"value":751},"Session.Remove(\"Cart\");\n",{"type":44,"tag":381,"props":753,"children":754},{"class":383,"line":506},[755],{"type":44,"tag":381,"props":756,"children":757},{},[758],{"type":50,"value":759},"Session.Abandon();\n",{"type":44,"tag":60,"props":761,"children":762},{},[763],{"type":44,"tag":82,"props":764,"children":765},{},[766],{"type":50,"value":767},"After (Core):",{"type":44,"tag":161,"props":769,"children":771},{"className":409,"code":770,"language":411,"meta":169,"style":169},"\u002F\u002F Reading — use typed extension methods\nvar cart = HttpContext.Session.Get\u003CShoppingCart>(\"Cart\");\nvar name = HttpContext.Session.GetString(\"UserName\");\n\n\u002F\u002F Writing — must serialize explicitly\nHttpContext.Session.Set(\"Cart\", cart);\nHttpContext.Session.SetString(\"UserName\", \"Alice\");\n\n\u002F\u002F Removing\nHttpContext.Session.Remove(\"Cart\");\nHttpContext.Session.Clear();\n",[772],{"type":44,"tag":66,"props":773,"children":774},{"__ignoreMap":169},[775,783,791,799,806,814,822,830,837,844,852],{"type":44,"tag":381,"props":776,"children":777},{"class":383,"line":29},[778],{"type":44,"tag":381,"props":779,"children":780},{},[781],{"type":50,"value":782},"\u002F\u002F Reading — use typed extension methods\n",{"type":44,"tag":381,"props":784,"children":785},{"class":383,"line":392},[786],{"type":44,"tag":381,"props":787,"children":788},{},[789],{"type":50,"value":790},"var cart = HttpContext.Session.Get\u003CShoppingCart>(\"Cart\");\n",{"type":44,"tag":381,"props":792,"children":793},{"class":383,"line":434},[794],{"type":44,"tag":381,"props":795,"children":796},{},[797],{"type":50,"value":798},"var name = HttpContext.Session.GetString(\"UserName\");\n",{"type":44,"tag":381,"props":800,"children":801},{"class":383,"line":443},[802],{"type":44,"tag":381,"props":803,"children":804},{"emptyLinePlaceholder":491},[805],{"type":50,"value":494},{"type":44,"tag":381,"props":807,"children":808},{"class":383,"line":452},[809],{"type":44,"tag":381,"props":810,"children":811},{},[812],{"type":50,"value":813},"\u002F\u002F Writing — must serialize explicitly\n",{"type":44,"tag":381,"props":815,"children":816},{"class":383,"line":461},[817],{"type":44,"tag":381,"props":818,"children":819},{},[820],{"type":50,"value":821},"HttpContext.Session.Set(\"Cart\", cart);\n",{"type":44,"tag":381,"props":823,"children":824},{"class":383,"line":25},[825],{"type":44,"tag":381,"props":826,"children":827},{},[828],{"type":50,"value":829},"HttpContext.Session.SetString(\"UserName\", \"Alice\");\n",{"type":44,"tag":381,"props":831,"children":832},{"class":383,"line":478},[833],{"type":44,"tag":381,"props":834,"children":835},{"emptyLinePlaceholder":491},[836],{"type":50,"value":494},{"type":44,"tag":381,"props":838,"children":839},{"class":383,"line":487},[840],{"type":44,"tag":381,"props":841,"children":842},{},[843],{"type":50,"value":743},{"type":44,"tag":381,"props":845,"children":846},{"class":383,"line":497},[847],{"type":44,"tag":381,"props":848,"children":849},{},[850],{"type":50,"value":851},"HttpContext.Session.Remove(\"Cart\");\n",{"type":44,"tag":381,"props":853,"children":854},{"class":383,"line":506},[855],{"type":44,"tag":381,"props":856,"children":857},{},[858],{"type":50,"value":859},"HttpContext.Session.Clear();\n",{"type":44,"tag":60,"props":861,"children":862},{},[863,865,870,872,878,879,885,887,893,894,900],{"type":50,"value":864},"The built-in ",{"type":44,"tag":66,"props":866,"children":868},{"className":867},[],[869],{"type":50,"value":656},{"type":50,"value":871}," only provides ",{"type":44,"tag":66,"props":873,"children":875},{"className":874},[],[876],{"type":50,"value":877},"GetString",{"type":50,"value":140},{"type":44,"tag":66,"props":880,"children":882},{"className":881},[],[883],{"type":50,"value":884},"SetString",{"type":50,"value":886}," and ",{"type":44,"tag":66,"props":888,"children":890},{"className":889},[],[891],{"type":50,"value":892},"GetInt32",{"type":50,"value":140},{"type":44,"tag":66,"props":895,"children":897},{"className":896},[],[898],{"type":50,"value":899},"SetInt32",{"type":50,"value":901},". For complex objects, add a JSON extension helper:",{"type":44,"tag":161,"props":903,"children":905},{"className":409,"code":904,"language":411,"meta":169,"style":169},"public static class SessionExtensions\n{\n    public static void Set\u003CT>(this ISession session, string key, T value)\n    {\n        session.SetString(key, JsonSerializer.Serialize(value));\n    }\n\n    public static T? Get\u003CT>(this ISession session, string key)\n    {\n        var value = session.GetString(key);\n        return value is null ? default : JsonSerializer.Deserialize\u003CT>(value);\n    }\n}\n",[906],{"type":44,"tag":66,"props":907,"children":908},{"__ignoreMap":169},[909,917,924,932,940,948,956,963,971,978,986,994,1001],{"type":44,"tag":381,"props":910,"children":911},{"class":383,"line":29},[912],{"type":44,"tag":381,"props":913,"children":914},{},[915],{"type":50,"value":916},"public static class SessionExtensions\n",{"type":44,"tag":381,"props":918,"children":919},{"class":383,"line":392},[920],{"type":44,"tag":381,"props":921,"children":922},{},[923],{"type":50,"value":449},{"type":44,"tag":381,"props":925,"children":926},{"class":383,"line":434},[927],{"type":44,"tag":381,"props":928,"children":929},{},[930],{"type":50,"value":931},"    public static void Set\u003CT>(this ISession session, string key, T value)\n",{"type":44,"tag":381,"props":933,"children":934},{"class":383,"line":443},[935],{"type":44,"tag":381,"props":936,"children":937},{},[938],{"type":50,"value":939},"    {\n",{"type":44,"tag":381,"props":941,"children":942},{"class":383,"line":452},[943],{"type":44,"tag":381,"props":944,"children":945},{},[946],{"type":50,"value":947},"        session.SetString(key, JsonSerializer.Serialize(value));\n",{"type":44,"tag":381,"props":949,"children":950},{"class":383,"line":461},[951],{"type":44,"tag":381,"props":952,"children":953},{},[954],{"type":50,"value":955},"    }\n",{"type":44,"tag":381,"props":957,"children":958},{"class":383,"line":25},[959],{"type":44,"tag":381,"props":960,"children":961},{"emptyLinePlaceholder":491},[962],{"type":50,"value":494},{"type":44,"tag":381,"props":964,"children":965},{"class":383,"line":478},[966],{"type":44,"tag":381,"props":967,"children":968},{},[969],{"type":50,"value":970},"    public static T? Get\u003CT>(this ISession session, string key)\n",{"type":44,"tag":381,"props":972,"children":973},{"class":383,"line":487},[974],{"type":44,"tag":381,"props":975,"children":976},{},[977],{"type":50,"value":939},{"type":44,"tag":381,"props":979,"children":980},{"class":383,"line":497},[981],{"type":44,"tag":381,"props":982,"children":983},{},[984],{"type":50,"value":985},"        var value = session.GetString(key);\n",{"type":44,"tag":381,"props":987,"children":988},{"class":383,"line":506},[989],{"type":44,"tag":381,"props":990,"children":991},{},[992],{"type":50,"value":993},"        return value is null ? default : JsonSerializer.Deserialize\u003CT>(value);\n",{"type":44,"tag":381,"props":995,"children":996},{"class":383,"line":625},[997],{"type":44,"tag":381,"props":998,"children":999},{},[1000],{"type":50,"value":955},{"type":44,"tag":381,"props":1002,"children":1003},{"class":383,"line":634},[1004],{"type":44,"tag":381,"props":1005,"children":1006},{},[1007],{"type":50,"value":1008},"}\n",{"type":44,"tag":60,"props":1010,"children":1011},{},[1012,1014,1020,1022,1028,1029,1035],{"type":50,"value":1013},"Place this in a shared location (e.g., ",{"type":44,"tag":66,"props":1015,"children":1017},{"className":1016},[],[1018],{"type":50,"value":1019},"Extensions\u002FSessionExtensions.cs",{"type":50,"value":1021},"). All session reads and writes for complex types must use these helpers — without them, ",{"type":44,"tag":66,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":50,"value":1027},"Get",{"type":50,"value":140},{"type":44,"tag":66,"props":1030,"children":1032},{"className":1031},[],[1033],{"type":50,"value":1034},"Set",{"type":50,"value":1036}," of objects silently fails.",{"type":44,"tag":60,"props":1038,"children":1039},{},[1040],{"type":44,"tag":82,"props":1041,"children":1042},{},[1043],{"type":50,"value":1044},"Key API differences:",{"type":44,"tag":185,"props":1046,"children":1047},{},[1048,1069],{"type":44,"tag":189,"props":1049,"children":1050},{},[1051],{"type":44,"tag":193,"props":1052,"children":1053},{},[1054,1059,1064],{"type":44,"tag":197,"props":1055,"children":1056},{},[1057],{"type":50,"value":1058},"Framework",{"type":44,"tag":197,"props":1060,"children":1061},{},[1062],{"type":50,"value":1063},"Core",{"type":44,"tag":197,"props":1065,"children":1066},{},[1067],{"type":50,"value":1068},"Notes",{"type":44,"tag":208,"props":1070,"children":1071},{},[1072,1098,1124,1156,1182],{"type":44,"tag":193,"props":1073,"children":1074},{},[1075,1084,1093],{"type":44,"tag":215,"props":1076,"children":1077},{},[1078],{"type":44,"tag":66,"props":1079,"children":1081},{"className":1080},[],[1082],{"type":50,"value":1083},"Session[\"key\"]",{"type":44,"tag":215,"props":1085,"children":1086},{},[1087],{"type":44,"tag":66,"props":1088,"children":1090},{"className":1089},[],[1091],{"type":50,"value":1092},"HttpContext.Session.GetString(\"key\")",{"type":44,"tag":215,"props":1094,"children":1095},{},[1096],{"type":50,"value":1097},"No indexer in Core",{"type":44,"tag":193,"props":1099,"children":1100},{},[1101,1110,1119],{"type":44,"tag":215,"props":1102,"children":1103},{},[1104],{"type":44,"tag":66,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":50,"value":1109},"Session[\"key\"] = obj",{"type":44,"tag":215,"props":1111,"children":1112},{},[1113],{"type":44,"tag":66,"props":1114,"children":1116},{"className":1115},[],[1117],{"type":50,"value":1118},"HttpContext.Session.Set(\"key\", obj)",{"type":44,"tag":215,"props":1120,"children":1121},{},[1122],{"type":50,"value":1123},"Requires JSON helper",{"type":44,"tag":193,"props":1125,"children":1126},{},[1127,1136,1145],{"type":44,"tag":215,"props":1128,"children":1129},{},[1130],{"type":44,"tag":66,"props":1131,"children":1133},{"className":1132},[],[1134],{"type":50,"value":1135},"Session.Abandon()",{"type":44,"tag":215,"props":1137,"children":1138},{},[1139],{"type":44,"tag":66,"props":1140,"children":1142},{"className":1141},[],[1143],{"type":50,"value":1144},"HttpContext.Session.Clear()",{"type":44,"tag":215,"props":1146,"children":1147},{},[1148,1154],{"type":44,"tag":66,"props":1149,"children":1151},{"className":1150},[],[1152],{"type":50,"value":1153},"Clear",{"type":50,"value":1155}," removes data but keeps session ID",{"type":44,"tag":193,"props":1157,"children":1158},{},[1159,1168,1177],{"type":44,"tag":215,"props":1160,"children":1161},{},[1162],{"type":44,"tag":66,"props":1163,"children":1165},{"className":1164},[],[1166],{"type":50,"value":1167},"Session.SessionID",{"type":44,"tag":215,"props":1169,"children":1170},{},[1171],{"type":44,"tag":66,"props":1172,"children":1174},{"className":1173},[],[1175],{"type":50,"value":1176},"HttpContext.Session.Id",{"type":44,"tag":215,"props":1178,"children":1179},{},[1180],{"type":50,"value":1181},"Property name change",{"type":44,"tag":193,"props":1183,"children":1184},{},[1185,1194,1203],{"type":44,"tag":215,"props":1186,"children":1187},{},[1188],{"type":44,"tag":66,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":50,"value":1193},"Session.Count",{"type":44,"tag":215,"props":1195,"children":1196},{},[1197],{"type":44,"tag":66,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":50,"value":1202},"HttpContext.Session.Keys.Count()",{"type":44,"tag":215,"props":1204,"children":1205},{},[1206],{"type":50,"value":1207},"Must enumerate keys",{"type":44,"tag":173,"props":1209,"children":1211},{"id":1210},"step-4-migrate-tempdata-provider",[1212],{"type":50,"value":1213},"Step 4: Migrate TempData Provider",{"type":44,"tag":60,"props":1215,"children":1216},{},[1217],{"type":50,"value":1218},"TempData API surface is compatible between Framework and Core, but the backing store changed. Framework uses session-based TempData by default; Core uses cookie-based TempData.",{"type":44,"tag":60,"props":1220,"children":1221},{},[1222],{"type":44,"tag":82,"props":1223,"children":1224},{},[1225],{"type":50,"value":1226},"Cookie TempData (Core default) — no code changes needed if data is small:",{"type":44,"tag":161,"props":1228,"children":1230},{"className":409,"code":1229,"language":411,"meta":169,"style":169},"\u002F\u002F TempData usage stays the same\nTempData[\"Message\"] = \"Item saved successfully\";\nvar msg = TempData[\"Message\"] as string;\n",[1231],{"type":44,"tag":66,"props":1232,"children":1233},{"__ignoreMap":169},[1234,1242,1250],{"type":44,"tag":381,"props":1235,"children":1236},{"class":383,"line":29},[1237],{"type":44,"tag":381,"props":1238,"children":1239},{},[1240],{"type":50,"value":1241},"\u002F\u002F TempData usage stays the same\n",{"type":44,"tag":381,"props":1243,"children":1244},{"class":383,"line":392},[1245],{"type":44,"tag":381,"props":1246,"children":1247},{},[1248],{"type":50,"value":1249},"TempData[\"Message\"] = \"Item saved successfully\";\n",{"type":44,"tag":381,"props":1251,"children":1252},{"class":383,"line":434},[1253],{"type":44,"tag":381,"props":1254,"children":1255},{},[1256],{"type":50,"value":1257},"var msg = TempData[\"Message\"] as string;\n",{"type":44,"tag":60,"props":1259,"children":1260},{},[1261,1262,1267],{"type":50,"value":517},{"type":44,"tag":82,"props":1263,"children":1264},{},[1265],{"type":50,"value":1266},"Silent truncation risk:",{"type":50,"value":1268}," Cookie-based TempData is limited to ~4096 bytes total. Large objects stored in TempData will be silently truncated or fail. If TempData stored complex objects in Framework, switch to session-based TempData provider:",{"type":44,"tag":161,"props":1270,"children":1272},{"className":409,"code":1271,"language":411,"meta":169,"style":169},"\u002F\u002F Program.cs — switch to session-based TempData (requires AddSession)\nbuilder.Services.AddControllersWithViews()\n    .AddSessionStateTempDataProvider();\n",[1273],{"type":44,"tag":66,"props":1274,"children":1275},{"__ignoreMap":169},[1276,1284,1292],{"type":44,"tag":381,"props":1277,"children":1278},{"class":383,"line":29},[1279],{"type":44,"tag":381,"props":1280,"children":1281},{},[1282],{"type":50,"value":1283},"\u002F\u002F Program.cs — switch to session-based TempData (requires AddSession)\n",{"type":44,"tag":381,"props":1285,"children":1286},{"class":383,"line":392},[1287],{"type":44,"tag":381,"props":1288,"children":1289},{},[1290],{"type":50,"value":1291},"builder.Services.AddControllersWithViews()\n",{"type":44,"tag":381,"props":1293,"children":1294},{"class":383,"line":434},[1295],{"type":44,"tag":381,"props":1296,"children":1297},{},[1298],{"type":50,"value":1299},"    .AddSessionStateTempDataProvider();\n",{"type":44,"tag":60,"props":1301,"children":1302},{},[1303,1308],{"type":44,"tag":82,"props":1304,"children":1305},{},[1306],{"type":50,"value":1307},"TempData in WebAPI controllers:",{"type":50,"value":1309}," TempData never existed in WebAPI. If Framework code used workarounds (e.g., storing values between redirects in a Web API context), replace with query string parameters, response headers, or a distributed cache lookup.",{"type":44,"tag":173,"props":1311,"children":1313},{"id":1312},"step-5-replace-application-state-and-httpruntimecache",[1314],{"type":50,"value":1315},"Step 5: Replace Application State and HttpRuntime.Cache",{"type":44,"tag":60,"props":1317,"children":1318},{},[1319,1321,1326,1328,1333],{"type":50,"value":1320},"ASP.NET Core has no ",{"type":44,"tag":66,"props":1322,"children":1324},{"className":1323},[],[1325],{"type":50,"value":279},{"type":50,"value":1327}," or ",{"type":44,"tag":66,"props":1329,"children":1331},{"className":1330},[],[1332],{"type":50,"value":296},{"type":50,"value":1334},". Replace with dependency-injected services.",{"type":44,"tag":1336,"props":1337,"children":1339},"h4",{"id":1338},"application-state-di-singleton",[1340],{"type":50,"value":1341},"Application State → DI Singleton",{"type":44,"tag":60,"props":1343,"children":1344},{},[1345],{"type":44,"tag":82,"props":1346,"children":1347},{},[1348],{"type":50,"value":666},{"type":44,"tag":161,"props":1350,"children":1352},{"className":409,"code":1351,"language":411,"meta":169,"style":169},"\u002F\u002F Writing — typically in Global.asax Application_Start\nHttpContext.Application[\"SiteSettings\"] = LoadSettings();\nHttpContext.Application.Lock();\nHttpContext.Application[\"VisitorCount\"] = (int)HttpContext.Application[\"VisitorCount\"] + 1;\nHttpContext.Application.UnLock();\n\n\u002F\u002F Reading — anywhere\nvar settings = HttpContext.Application[\"SiteSettings\"] as SiteSettings;\n",[1353],{"type":44,"tag":66,"props":1354,"children":1355},{"__ignoreMap":169},[1356,1364,1372,1380,1388,1396,1403,1411],{"type":44,"tag":381,"props":1357,"children":1358},{"class":383,"line":29},[1359],{"type":44,"tag":381,"props":1360,"children":1361},{},[1362],{"type":50,"value":1363},"\u002F\u002F Writing — typically in Global.asax Application_Start\n",{"type":44,"tag":381,"props":1365,"children":1366},{"class":383,"line":392},[1367],{"type":44,"tag":381,"props":1368,"children":1369},{},[1370],{"type":50,"value":1371},"HttpContext.Application[\"SiteSettings\"] = LoadSettings();\n",{"type":44,"tag":381,"props":1373,"children":1374},{"class":383,"line":434},[1375],{"type":44,"tag":381,"props":1376,"children":1377},{},[1378],{"type":50,"value":1379},"HttpContext.Application.Lock();\n",{"type":44,"tag":381,"props":1381,"children":1382},{"class":383,"line":443},[1383],{"type":44,"tag":381,"props":1384,"children":1385},{},[1386],{"type":50,"value":1387},"HttpContext.Application[\"VisitorCount\"] = (int)HttpContext.Application[\"VisitorCount\"] + 1;\n",{"type":44,"tag":381,"props":1389,"children":1390},{"class":383,"line":452},[1391],{"type":44,"tag":381,"props":1392,"children":1393},{},[1394],{"type":50,"value":1395},"HttpContext.Application.UnLock();\n",{"type":44,"tag":381,"props":1397,"children":1398},{"class":383,"line":461},[1399],{"type":44,"tag":381,"props":1400,"children":1401},{"emptyLinePlaceholder":491},[1402],{"type":50,"value":494},{"type":44,"tag":381,"props":1404,"children":1405},{"class":383,"line":25},[1406],{"type":44,"tag":381,"props":1407,"children":1408},{},[1409],{"type":50,"value":1410},"\u002F\u002F Reading — anywhere\n",{"type":44,"tag":381,"props":1412,"children":1413},{"class":383,"line":478},[1414],{"type":44,"tag":381,"props":1415,"children":1416},{},[1417],{"type":50,"value":1418},"var settings = HttpContext.Application[\"SiteSettings\"] as SiteSettings;\n",{"type":44,"tag":60,"props":1420,"children":1421},{},[1422],{"type":44,"tag":82,"props":1423,"children":1424},{},[1425],{"type":50,"value":767},{"type":44,"tag":161,"props":1427,"children":1429},{"className":409,"code":1428,"language":411,"meta":169,"style":169},"\u002F\u002F Define a service to hold shared state\npublic class AppStateService\n{\n    private int _visitorCount;\n    public SiteSettings SiteSettings { get; set; } = new();\n    public int IncrementVisitors() => Interlocked.Increment(ref _visitorCount);\n}\n\n\u002F\u002F Register as singleton in Program.cs\nbuilder.Services.AddSingleton\u003CAppStateService>();\n\n\u002F\u002F Inject where needed\npublic class HomeController : Controller\n{\n    private readonly AppStateService _appState;\n    public HomeController(AppStateService appState) => _appState = appState;\n}\n",[1430],{"type":44,"tag":66,"props":1431,"children":1432},{"__ignoreMap":169},[1433,1441,1449,1456,1464,1472,1480,1487,1494,1502,1510,1517,1525,1533,1541,1550,1559],{"type":44,"tag":381,"props":1434,"children":1435},{"class":383,"line":29},[1436],{"type":44,"tag":381,"props":1437,"children":1438},{},[1439],{"type":50,"value":1440},"\u002F\u002F Define a service to hold shared state\n",{"type":44,"tag":381,"props":1442,"children":1443},{"class":383,"line":392},[1444],{"type":44,"tag":381,"props":1445,"children":1446},{},[1447],{"type":50,"value":1448},"public class AppStateService\n",{"type":44,"tag":381,"props":1450,"children":1451},{"class":383,"line":434},[1452],{"type":44,"tag":381,"props":1453,"children":1454},{},[1455],{"type":50,"value":449},{"type":44,"tag":381,"props":1457,"children":1458},{"class":383,"line":443},[1459],{"type":44,"tag":381,"props":1460,"children":1461},{},[1462],{"type":50,"value":1463},"    private int _visitorCount;\n",{"type":44,"tag":381,"props":1465,"children":1466},{"class":383,"line":452},[1467],{"type":44,"tag":381,"props":1468,"children":1469},{},[1470],{"type":50,"value":1471},"    public SiteSettings SiteSettings { get; set; } = new();\n",{"type":44,"tag":381,"props":1473,"children":1474},{"class":383,"line":461},[1475],{"type":44,"tag":381,"props":1476,"children":1477},{},[1478],{"type":50,"value":1479},"    public int IncrementVisitors() => Interlocked.Increment(ref _visitorCount);\n",{"type":44,"tag":381,"props":1481,"children":1482},{"class":383,"line":25},[1483],{"type":44,"tag":381,"props":1484,"children":1485},{},[1486],{"type":50,"value":1008},{"type":44,"tag":381,"props":1488,"children":1489},{"class":383,"line":478},[1490],{"type":44,"tag":381,"props":1491,"children":1492},{"emptyLinePlaceholder":491},[1493],{"type":50,"value":494},{"type":44,"tag":381,"props":1495,"children":1496},{"class":383,"line":487},[1497],{"type":44,"tag":381,"props":1498,"children":1499},{},[1500],{"type":50,"value":1501},"\u002F\u002F Register as singleton in Program.cs\n",{"type":44,"tag":381,"props":1503,"children":1504},{"class":383,"line":497},[1505],{"type":44,"tag":381,"props":1506,"children":1507},{},[1508],{"type":50,"value":1509},"builder.Services.AddSingleton\u003CAppStateService>();\n",{"type":44,"tag":381,"props":1511,"children":1512},{"class":383,"line":506},[1513],{"type":44,"tag":381,"props":1514,"children":1515},{"emptyLinePlaceholder":491},[1516],{"type":50,"value":494},{"type":44,"tag":381,"props":1518,"children":1519},{"class":383,"line":625},[1520],{"type":44,"tag":381,"props":1521,"children":1522},{},[1523],{"type":50,"value":1524},"\u002F\u002F Inject where needed\n",{"type":44,"tag":381,"props":1526,"children":1527},{"class":383,"line":634},[1528],{"type":44,"tag":381,"props":1529,"children":1530},{},[1531],{"type":50,"value":1532},"public class HomeController : Controller\n",{"type":44,"tag":381,"props":1534,"children":1536},{"class":383,"line":1535},14,[1537],{"type":44,"tag":381,"props":1538,"children":1539},{},[1540],{"type":50,"value":449},{"type":44,"tag":381,"props":1542,"children":1544},{"class":383,"line":1543},15,[1545],{"type":44,"tag":381,"props":1546,"children":1547},{},[1548],{"type":50,"value":1549},"    private readonly AppStateService _appState;\n",{"type":44,"tag":381,"props":1551,"children":1553},{"class":383,"line":1552},16,[1554],{"type":44,"tag":381,"props":1555,"children":1556},{},[1557],{"type":50,"value":1558},"    public HomeController(AppStateService appState) => _appState = appState;\n",{"type":44,"tag":381,"props":1560,"children":1562},{"class":383,"line":1561},17,[1563],{"type":44,"tag":381,"props":1564,"children":1565},{},[1566],{"type":50,"value":1008},{"type":44,"tag":60,"props":1568,"children":1569},{},[1570,1572,1578,1579,1585,1587,1593,1595,1601,1603,1609,1611,1616,1617,1622],{"type":50,"value":1571},"Application state with ",{"type":44,"tag":66,"props":1573,"children":1575},{"className":1574},[],[1576],{"type":50,"value":1577},"Lock()",{"type":50,"value":140},{"type":44,"tag":66,"props":1580,"children":1582},{"className":1581},[],[1583],{"type":50,"value":1584},"UnLock()",{"type":50,"value":1586}," patterns needs thread-safe replacements — use ",{"type":44,"tag":66,"props":1588,"children":1590},{"className":1589},[],[1591],{"type":50,"value":1592},"Interlocked",{"type":50,"value":1594},", ",{"type":44,"tag":66,"props":1596,"children":1598},{"className":1597},[],[1599],{"type":50,"value":1600},"ConcurrentDictionary",{"type":50,"value":1602},", or ",{"type":44,"tag":66,"props":1604,"children":1606},{"className":1605},[],[1607],{"type":50,"value":1608},"lock",{"type":50,"value":1610}," in the singleton service. The ",{"type":44,"tag":66,"props":1612,"children":1614},{"className":1613},[],[1615],{"type":50,"value":1577},{"type":50,"value":140},{"type":44,"tag":66,"props":1618,"children":1620},{"className":1619},[],[1621],{"type":50,"value":1584},{"type":50,"value":1623}," API does not exist in Core.",{"type":44,"tag":1336,"props":1625,"children":1627},{"id":1626},"httpruntimecache-imemorycache",[1628],{"type":50,"value":1629},"HttpRuntime.Cache → IMemoryCache",{"type":44,"tag":60,"props":1631,"children":1632},{},[1633],{"type":44,"tag":82,"props":1634,"children":1635},{},[1636],{"type":50,"value":666},{"type":44,"tag":161,"props":1638,"children":1640},{"className":409,"code":1639,"language":411,"meta":169,"style":169},"HttpRuntime.Cache.Insert(\"Products\", products, null,\n    DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration);\nvar cached = HttpRuntime.Cache[\"Products\"] as List\u003CProduct>;\n",[1641],{"type":44,"tag":66,"props":1642,"children":1643},{"__ignoreMap":169},[1644,1652,1660],{"type":44,"tag":381,"props":1645,"children":1646},{"class":383,"line":29},[1647],{"type":44,"tag":381,"props":1648,"children":1649},{},[1650],{"type":50,"value":1651},"HttpRuntime.Cache.Insert(\"Products\", products, null,\n",{"type":44,"tag":381,"props":1653,"children":1654},{"class":383,"line":392},[1655],{"type":44,"tag":381,"props":1656,"children":1657},{},[1658],{"type":50,"value":1659},"    DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration);\n",{"type":44,"tag":381,"props":1661,"children":1662},{"class":383,"line":434},[1663],{"type":44,"tag":381,"props":1664,"children":1665},{},[1666],{"type":50,"value":1667},"var cached = HttpRuntime.Cache[\"Products\"] as List\u003CProduct>;\n",{"type":44,"tag":60,"props":1669,"children":1670},{},[1671],{"type":44,"tag":82,"props":1672,"children":1673},{},[1674],{"type":50,"value":767},{"type":44,"tag":161,"props":1676,"children":1678},{"className":409,"code":1677,"language":411,"meta":169,"style":169},"\u002F\u002F Program.cs\nbuilder.Services.AddMemoryCache();\n\n\u002F\u002F In controller or service — inject IMemoryCache\npublic class ProductService\n{\n    private readonly IMemoryCache _cache;\n    public ProductService(IMemoryCache cache) => _cache = cache;\n\n    public List\u003CProduct> GetProducts()\n    {\n        return _cache.GetOrCreate(\"Products\", entry =>\n        {\n            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);\n            return LoadProductsFromDb();\n        })!;\n    }\n}\n",[1679],{"type":44,"tag":66,"props":1680,"children":1681},{"__ignoreMap":169},[1682,1690,1698,1705,1713,1721,1728,1736,1744,1751,1759,1766,1774,1782,1790,1798,1806,1813],{"type":44,"tag":381,"props":1683,"children":1684},{"class":383,"line":29},[1685],{"type":44,"tag":381,"props":1686,"children":1687},{},[1688],{"type":50,"value":1689},"\u002F\u002F Program.cs\n",{"type":44,"tag":381,"props":1691,"children":1692},{"class":383,"line":392},[1693],{"type":44,"tag":381,"props":1694,"children":1695},{},[1696],{"type":50,"value":1697},"builder.Services.AddMemoryCache();\n",{"type":44,"tag":381,"props":1699,"children":1700},{"class":383,"line":434},[1701],{"type":44,"tag":381,"props":1702,"children":1703},{"emptyLinePlaceholder":491},[1704],{"type":50,"value":494},{"type":44,"tag":381,"props":1706,"children":1707},{"class":383,"line":443},[1708],{"type":44,"tag":381,"props":1709,"children":1710},{},[1711],{"type":50,"value":1712},"\u002F\u002F In controller or service — inject IMemoryCache\n",{"type":44,"tag":381,"props":1714,"children":1715},{"class":383,"line":452},[1716],{"type":44,"tag":381,"props":1717,"children":1718},{},[1719],{"type":50,"value":1720},"public class ProductService\n",{"type":44,"tag":381,"props":1722,"children":1723},{"class":383,"line":461},[1724],{"type":44,"tag":381,"props":1725,"children":1726},{},[1727],{"type":50,"value":449},{"type":44,"tag":381,"props":1729,"children":1730},{"class":383,"line":25},[1731],{"type":44,"tag":381,"props":1732,"children":1733},{},[1734],{"type":50,"value":1735},"    private readonly IMemoryCache _cache;\n",{"type":44,"tag":381,"props":1737,"children":1738},{"class":383,"line":478},[1739],{"type":44,"tag":381,"props":1740,"children":1741},{},[1742],{"type":50,"value":1743},"    public ProductService(IMemoryCache cache) => _cache = cache;\n",{"type":44,"tag":381,"props":1745,"children":1746},{"class":383,"line":487},[1747],{"type":44,"tag":381,"props":1748,"children":1749},{"emptyLinePlaceholder":491},[1750],{"type":50,"value":494},{"type":44,"tag":381,"props":1752,"children":1753},{"class":383,"line":497},[1754],{"type":44,"tag":381,"props":1755,"children":1756},{},[1757],{"type":50,"value":1758},"    public List\u003CProduct> GetProducts()\n",{"type":44,"tag":381,"props":1760,"children":1761},{"class":383,"line":506},[1762],{"type":44,"tag":381,"props":1763,"children":1764},{},[1765],{"type":50,"value":939},{"type":44,"tag":381,"props":1767,"children":1768},{"class":383,"line":625},[1769],{"type":44,"tag":381,"props":1770,"children":1771},{},[1772],{"type":50,"value":1773},"        return _cache.GetOrCreate(\"Products\", entry =>\n",{"type":44,"tag":381,"props":1775,"children":1776},{"class":383,"line":634},[1777],{"type":44,"tag":381,"props":1778,"children":1779},{},[1780],{"type":50,"value":1781},"        {\n",{"type":44,"tag":381,"props":1783,"children":1784},{"class":383,"line":1535},[1785],{"type":44,"tag":381,"props":1786,"children":1787},{},[1788],{"type":50,"value":1789},"            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);\n",{"type":44,"tag":381,"props":1791,"children":1792},{"class":383,"line":1543},[1793],{"type":44,"tag":381,"props":1794,"children":1795},{},[1796],{"type":50,"value":1797},"            return LoadProductsFromDb();\n",{"type":44,"tag":381,"props":1799,"children":1800},{"class":383,"line":1552},[1801],{"type":44,"tag":381,"props":1802,"children":1803},{},[1804],{"type":50,"value":1805},"        })!;\n",{"type":44,"tag":381,"props":1807,"children":1808},{"class":383,"line":1561},[1809],{"type":44,"tag":381,"props":1810,"children":1811},{},[1812],{"type":50,"value":955},{"type":44,"tag":381,"props":1814,"children":1816},{"class":383,"line":1815},18,[1817],{"type":44,"tag":381,"props":1818,"children":1819},{},[1820],{"type":50,"value":1008},{"type":44,"tag":60,"props":1822,"children":1823},{},[1824,1826,1832,1834,1840],{"type":50,"value":1825},"For multi-instance deployments, use ",{"type":44,"tag":66,"props":1827,"children":1829},{"className":1828},[],[1830],{"type":50,"value":1831},"IDistributedCache",{"type":50,"value":1833}," instead of ",{"type":44,"tag":66,"props":1835,"children":1837},{"className":1836},[],[1838],{"type":50,"value":1839},"IMemoryCache",{"type":50,"value":1841}," to avoid cache inconsistencies across instances.",{"type":44,"tag":173,"props":1843,"children":1845},{"id":1844},"step-6-replace-static-state-with-di-singletons",[1846],{"type":50,"value":1847},"Step 6: Replace Static State with DI Singletons",{"type":44,"tag":60,"props":1849,"children":1850},{},[1851],{"type":50,"value":1852},"Static fields holding per-application state are a common pattern in Framework apps. These work in single-instance deployments but break in multi-instance or container environments.",{"type":44,"tag":60,"props":1854,"children":1855},{},[1856],{"type":44,"tag":82,"props":1857,"children":1858},{},[1859],{"type":50,"value":666},{"type":44,"tag":161,"props":1861,"children":1863},{"className":409,"code":1862,"language":411,"meta":169,"style":169},"public static class AppConfig\n{\n    public static string ConnectionString { get; set; }\n    public static Dictionary\u003Cstring, object> Settings = new();\n}\n",[1864],{"type":44,"tag":66,"props":1865,"children":1866},{"__ignoreMap":169},[1867,1875,1882,1890,1898],{"type":44,"tag":381,"props":1868,"children":1869},{"class":383,"line":29},[1870],{"type":44,"tag":381,"props":1871,"children":1872},{},[1873],{"type":50,"value":1874},"public static class AppConfig\n",{"type":44,"tag":381,"props":1876,"children":1877},{"class":383,"line":392},[1878],{"type":44,"tag":381,"props":1879,"children":1880},{},[1881],{"type":50,"value":449},{"type":44,"tag":381,"props":1883,"children":1884},{"class":383,"line":434},[1885],{"type":44,"tag":381,"props":1886,"children":1887},{},[1888],{"type":50,"value":1889},"    public static string ConnectionString { get; set; }\n",{"type":44,"tag":381,"props":1891,"children":1892},{"class":383,"line":443},[1893],{"type":44,"tag":381,"props":1894,"children":1895},{},[1896],{"type":50,"value":1897},"    public static Dictionary\u003Cstring, object> Settings = new();\n",{"type":44,"tag":381,"props":1899,"children":1900},{"class":383,"line":452},[1901],{"type":44,"tag":381,"props":1902,"children":1903},{},[1904],{"type":50,"value":1008},{"type":44,"tag":60,"props":1906,"children":1907},{},[1908],{"type":44,"tag":82,"props":1909,"children":1910},{},[1911],{"type":50,"value":767},{"type":44,"tag":161,"props":1913,"children":1915},{"className":409,"code":1914,"language":411,"meta":169,"style":169},"public class AppConfig\n{\n    public string ConnectionString { get; set; } = string.Empty;\n    public Dictionary\u003Cstring, object> Settings { get; } = new();\n}\n\n\u002F\u002F Program.cs\nbuilder.Services.AddSingleton\u003CAppConfig>();\n",[1916],{"type":44,"tag":66,"props":1917,"children":1918},{"__ignoreMap":169},[1919,1927,1934,1942,1950,1957,1964,1971],{"type":44,"tag":381,"props":1920,"children":1921},{"class":383,"line":29},[1922],{"type":44,"tag":381,"props":1923,"children":1924},{},[1925],{"type":50,"value":1926},"public class AppConfig\n",{"type":44,"tag":381,"props":1928,"children":1929},{"class":383,"line":392},[1930],{"type":44,"tag":381,"props":1931,"children":1932},{},[1933],{"type":50,"value":449},{"type":44,"tag":381,"props":1935,"children":1936},{"class":383,"line":434},[1937],{"type":44,"tag":381,"props":1938,"children":1939},{},[1940],{"type":50,"value":1941},"    public string ConnectionString { get; set; } = string.Empty;\n",{"type":44,"tag":381,"props":1943,"children":1944},{"class":383,"line":443},[1945],{"type":44,"tag":381,"props":1946,"children":1947},{},[1948],{"type":50,"value":1949},"    public Dictionary\u003Cstring, object> Settings { get; } = new();\n",{"type":44,"tag":381,"props":1951,"children":1952},{"class":383,"line":452},[1953],{"type":44,"tag":381,"props":1954,"children":1955},{},[1956],{"type":50,"value":1008},{"type":44,"tag":381,"props":1958,"children":1959},{"class":383,"line":461},[1960],{"type":44,"tag":381,"props":1961,"children":1962},{"emptyLinePlaceholder":491},[1963],{"type":50,"value":494},{"type":44,"tag":381,"props":1965,"children":1966},{"class":383,"line":25},[1967],{"type":44,"tag":381,"props":1968,"children":1969},{},[1970],{"type":50,"value":1689},{"type":44,"tag":381,"props":1972,"children":1973},{"class":383,"line":478},[1974],{"type":44,"tag":381,"props":1975,"children":1976},{},[1977],{"type":50,"value":1978},"builder.Services.AddSingleton\u003CAppConfig>();\n",{"type":44,"tag":60,"props":1980,"children":1981},{},[1982,1984,1990],{"type":50,"value":1983},"Convert all static field access to constructor injection. If static access is needed in non-DI contexts (e.g., extension methods), expose the service through ",{"type":44,"tag":66,"props":1985,"children":1987},{"className":1986},[],[1988],{"type":50,"value":1989},"IServiceProvider",{"type":50,"value":1991}," at the call site rather than reverting to static state.",{"type":44,"tag":173,"props":1993,"children":1995},{"id":1994},"step-7-verify-serialization-and-data-round-trips",[1996],{"type":50,"value":1997},"Step 7: Verify Serialization and Data Round-Trips",{"type":44,"tag":60,"props":1999,"children":2000},{},[2001],{"type":50,"value":2002},"After migrating, verify that data survives a full write-read cycle:",{"type":44,"tag":2004,"props":2005,"children":2006},"ol",{},[2007,2018,2028],{"type":44,"tag":2008,"props":2009,"children":2010},"li",{},[2011,2016],{"type":44,"tag":82,"props":2012,"children":2013},{},[2014],{"type":50,"value":2015},"Session data",{"type":50,"value":2017}," — Write a complex object to session, read it back, and confirm all properties match. Test after app restart to confirm the distributed cache retains data (in-memory cache will not).",{"type":44,"tag":2008,"props":2019,"children":2020},{},[2021,2026],{"type":44,"tag":82,"props":2022,"children":2023},{},[2024],{"type":50,"value":2025},"TempData",{"type":50,"value":2027}," — Store a value, perform a redirect, and verify the value is available on the destination page. Test with objects that approach the 4096-byte cookie limit if using cookie-based TempData.",{"type":44,"tag":2008,"props":2029,"children":2030},{},[2031,2036,2038,2044],{"type":44,"tag":82,"props":2032,"children":2033},{},[2034],{"type":50,"value":2035},"Cache entries",{"type":50,"value":2037}," — Verify expiration behavior matches the original ",{"type":44,"tag":66,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":50,"value":2043},"web.config",{"type":50,"value":2045}," settings.",{"type":44,"tag":60,"props":2047,"children":2048},{},[2049],{"type":50,"value":2050},"Build the project and run existing tests to confirm no regressions.",{"type":44,"tag":53,"props":2052,"children":2054},{"id":2053},"troubleshooting",[2055],{"type":50,"value":2056},"Troubleshooting",{"type":44,"tag":185,"props":2058,"children":2059},{},[2060,2081],{"type":44,"tag":189,"props":2061,"children":2062},{},[2063],{"type":44,"tag":193,"props":2064,"children":2065},{},[2066,2071,2076],{"type":44,"tag":197,"props":2067,"children":2068},{},[2069],{"type":50,"value":2070},"Symptom",{"type":44,"tag":197,"props":2072,"children":2073},{},[2074],{"type":50,"value":2075},"Cause",{"type":44,"tag":197,"props":2077,"children":2078},{},[2079],{"type":50,"value":2080},"Fix",{"type":44,"tag":208,"props":2082,"children":2083},{},[2084,2125,2150,2174,2198,2226],{"type":44,"tag":193,"props":2085,"children":2086},{},[2087,2098,2115],{"type":44,"tag":215,"props":2088,"children":2089},{},[2090,2096],{"type":44,"tag":66,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":50,"value":2095},"Session",{"type":50,"value":2097}," is always null",{"type":44,"tag":215,"props":2099,"children":2100},{},[2101,2103,2109,2110],{"type":50,"value":2102},"Missing ",{"type":44,"tag":66,"props":2104,"children":2106},{"className":2105},[],[2107],{"type":50,"value":2108},"app.UseSession()",{"type":50,"value":1327},{"type":44,"tag":66,"props":2111,"children":2113},{"className":2112},[],[2114],{"type":50,"value":71},{"type":44,"tag":215,"props":2116,"children":2117},{},[2118,2120],{"type":50,"value":2119},"Add both to ",{"type":44,"tag":66,"props":2121,"children":2123},{"className":2122},[],[2124],{"type":50,"value":360},{"type":44,"tag":193,"props":2126,"children":2127},{},[2128,2133,2145],{"type":44,"tag":215,"props":2129,"children":2130},{},[2131],{"type":50,"value":2132},"Session data lost on restart",{"type":44,"tag":215,"props":2134,"children":2135},{},[2136,2138,2143],{"type":50,"value":2137},"Using ",{"type":44,"tag":66,"props":2139,"children":2141},{"className":2140},[],[2142],{"type":50,"value":529},{"type":50,"value":2144}," in production",{"type":44,"tag":215,"props":2146,"children":2147},{},[2148],{"type":50,"value":2149},"Switch to Redis or SQL Server cache",{"type":44,"tag":193,"props":2151,"children":2152},{},[2153,2158,2163],{"type":44,"tag":215,"props":2154,"children":2155},{},[2156],{"type":50,"value":2157},"TempData silently empty after redirect",{"type":44,"tag":215,"props":2159,"children":2160},{},[2161],{"type":50,"value":2162},"Cookie exceeds 4096 bytes",{"type":44,"tag":215,"props":2164,"children":2165},{},[2166,2168],{"type":50,"value":2167},"Switch to ",{"type":44,"tag":66,"props":2169,"children":2171},{"className":2170},[],[2172],{"type":50,"value":2173},"AddSessionStateTempDataProvider()",{"type":44,"tag":193,"props":2175,"children":2176},{},[2177,2188,2193],{"type":44,"tag":215,"props":2178,"children":2179},{},[2180,2186],{"type":44,"tag":66,"props":2181,"children":2183},{"className":2182},[],[2184],{"type":50,"value":2185},"HttpContext.Application",{"type":50,"value":2187}," compile error",{"type":44,"tag":215,"props":2189,"children":2190},{},[2191],{"type":50,"value":2192},"No equivalent in Core",{"type":44,"tag":215,"props":2194,"children":2195},{},[2196],{"type":50,"value":2197},"Replace with DI singleton (Step 5)",{"type":44,"tag":193,"props":2199,"children":2200},{},[2201,2210,2214],{"type":44,"tag":215,"props":2202,"children":2203},{},[2204,2209],{"type":44,"tag":66,"props":2205,"children":2207},{"className":2206},[],[2208],{"type":50,"value":296},{"type":50,"value":2187},{"type":44,"tag":215,"props":2211,"children":2212},{},[2213],{"type":50,"value":2192},{"type":44,"tag":215,"props":2215,"children":2216},{},[2217,2219,2224],{"type":50,"value":2218},"Replace with ",{"type":44,"tag":66,"props":2220,"children":2222},{"className":2221},[],[2223],{"type":50,"value":1839},{"type":50,"value":2225}," (Step 5)",{"type":44,"tag":193,"props":2227,"children":2228},{},[2229,2234,2239],{"type":44,"tag":215,"props":2230,"children":2231},{},[2232],{"type":50,"value":2233},"Thread-safety issues with singleton state",{"type":44,"tag":215,"props":2235,"children":2236},{},[2237],{"type":50,"value":2238},"Missing synchronization",{"type":44,"tag":215,"props":2240,"children":2241},{},[2242,2244,2249,2250],{"type":50,"value":2243},"Use ",{"type":44,"tag":66,"props":2245,"children":2247},{"className":2246},[],[2248],{"type":50,"value":1600},{"type":50,"value":1327},{"type":44,"tag":66,"props":2251,"children":2253},{"className":2252},[],[2254],{"type":50,"value":1592},{"type":44,"tag":53,"props":2256,"children":2258},{"id":2257},"success-criteria",[2259],{"type":50,"value":2260},"Success Criteria",{"type":44,"tag":2262,"props":2263,"children":2264},"ul",{},[2265,2289,2294,2313,2318,2323,2333,2354,2359,2372],{"type":44,"tag":2008,"props":2266,"children":2267},{},[2268,2270,2275,2276,2282,2284],{"type":50,"value":2269},"Session services registered with ",{"type":44,"tag":66,"props":2271,"children":2273},{"className":2272},[],[2274],{"type":50,"value":71},{"type":50,"value":886},{"type":44,"tag":66,"props":2277,"children":2279},{"className":2278},[],[2280],{"type":50,"value":2281},"UseSession()",{"type":50,"value":2283}," in ",{"type":44,"tag":66,"props":2285,"children":2287},{"className":2286},[],[2288],{"type":50,"value":360},{"type":44,"tag":2008,"props":2290,"children":2291},{},[2292],{"type":50,"value":2293},"Distributed cache provider configured (not in-memory for production)",{"type":44,"tag":2008,"props":2295,"children":2296},{},[2297,2299,2304,2306,2311],{"type":50,"value":2298},"All ",{"type":44,"tag":66,"props":2300,"children":2302},{"className":2301},[],[2303],{"type":50,"value":1083},{"type":50,"value":2305}," indexer access replaced with ",{"type":44,"tag":66,"props":2307,"children":2309},{"className":2308},[],[2310],{"type":50,"value":656},{"type":50,"value":2312}," extension methods",{"type":44,"tag":2008,"props":2314,"children":2315},{},[2316],{"type":50,"value":2317},"JSON serialization helper created for complex session objects",{"type":44,"tag":2008,"props":2319,"children":2320},{},[2321],{"type":50,"value":2322},"TempData provider chosen and configured based on data size requirements",{"type":44,"tag":2008,"props":2324,"children":2325},{},[2326,2331],{"type":44,"tag":66,"props":2327,"children":2329},{"className":2328},[],[2330],{"type":50,"value":2185},{"type":50,"value":2332}," replaced with DI singleton services",{"type":44,"tag":2008,"props":2334,"children":2335},{},[2336,2341,2343,2348,2349],{"type":44,"tag":66,"props":2337,"children":2339},{"className":2338},[],[2340],{"type":50,"value":296},{"type":50,"value":2342}," replaced with ",{"type":44,"tag":66,"props":2344,"children":2346},{"className":2345},[],[2347],{"type":50,"value":1839},{"type":50,"value":1327},{"type":44,"tag":66,"props":2350,"children":2352},{"className":2351},[],[2353],{"type":50,"value":1831},{"type":44,"tag":2008,"props":2355,"children":2356},{},[2357],{"type":50,"value":2358},"Static state fields converted to singleton services with DI",{"type":44,"tag":2008,"props":2360,"children":2361},{},[2362,2364,2370],{"type":50,"value":2363},"No ",{"type":44,"tag":66,"props":2365,"children":2367},{"className":2366},[],[2368],{"type":50,"value":2369},"System.Web",{"type":50,"value":2371}," session or cache references remain",{"type":44,"tag":2008,"props":2373,"children":2374},{},[2375],{"type":50,"value":2376},"Project builds without errors",{"type":44,"tag":2378,"props":2379,"children":2380},"style",{},[2381],{"type":50,"value":2382},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2384,"total":2477},[2385,2395,2409,2426,2436,2450,2467],{"slug":2386,"name":2386,"fn":2387,"description":2388,"org":2389,"tags":2390,"stars":25,"repoUrl":26,"updatedAt":2394},"converting-to-cpm","migrate .NET projects to Central Package Management","Converts .NET projects and solutions to NuGet Central Package Management (CPM) with Directory.Packages.props. Use when the user wants to centralize, convert, align, or sync NuGet package versions across multiple projects, resolve version conflicts or mismatches, or get versions consistent across a solution or repository. Also triggers when packages are out of sync or drifting across projects.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2391,2392,2393],{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"name":23,"slug":24,"type":15},"2026-07-18T05:14:13.971821",{"slug":2396,"name":2396,"fn":2397,"description":2398,"org":2399,"tags":2400,"stars":25,"repoUrl":26,"updatedAt":2408},"creating-winforms-custom-controls","create custom WinForms controls","Creates custom controls and UserControls for modern WinForms (.NET 6+). Use when deriving from Control, UserControl, Button, TextBox, or other base controls, implementing custom rendering with OnPaint overrides, creating composite controls with child control composition, adding custom properties with [Browsable], [Category], or [DefaultValue] attributes for Designer support, implementing INotifyPropertyChanged for control properties, handling Layout\u002FLayoutEngine for custom sizing, creating scrollable controls with AutoScrollMinSize, implementing dark mode theming, or building List\u002FGrid\u002FTree-like controls. Also triggers for \"custom UserControl\", \"derive from Control\", \"owner-drawn control\", \"Designer properties\", \"[Browsable] attribute\", \"custom WinForms control\", \"LayoutEngine\", \"AutoScroll control\", and \"themed control\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2401,2402,2405],{"name":20,"slug":21,"type":15},{"name":2403,"slug":2404,"type":15},"Windows","windows",{"name":2406,"slug":2407,"type":15},"WinUI","winui","2026-07-03T16:31:30.1325",{"slug":2410,"name":2410,"fn":2411,"description":2412,"org":2413,"tags":2414,"stars":25,"repoUrl":26,"updatedAt":2425},"managing-winforms-high-dpi-layout","design high-DPI responsive WinForms layouts","Implements WinForms high-DPI fluent layouts using TableLayoutPanel, FlowLayoutPanel, and DPI-aware design patterns. Use when creating responsive form layouts that must scale across different DPI settings, implementing Per Monitor V2 (PerMonitorV2) DPI awareness, working with TableLayoutPanel.RowStyles\u002FColumnStyles, using FlowLayoutPanel for dynamic layouts, replacing fixed pixel positioning with container-based layout, troubleshooting DPI scaling issues, or structuring nested layout containers. Also triggers for \"TableLayoutPanel\", \"FlowLayoutPanel\", \"high DPI WinForms\", \"PerMonitorV2\", \"DPI aware layout\", \"responsive WinForms\", \"scale UI\", \"AutoScaleMode\", and \"DPI scaling\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2415,2418,2421,2424],{"name":2416,"slug":2417,"type":15},"Design","design",{"name":2419,"slug":2420,"type":15},"Desktop","desktop",{"name":2422,"slug":2423,"type":15},"UI Components","ui-components",{"name":2403,"slug":2404,"type":15},"2026-07-18T05:14:12.982806",{"slug":2427,"name":2427,"fn":2428,"description":2429,"org":2430,"tags":2431,"stars":25,"repoUrl":26,"updatedAt":2435},"managing-winforms-mvvm","implement MVVM pattern in WinForms","Implements MVVM pattern in WinForms applications (.NET 8+) with ViewModels, Commands, and DataContext. Use when user explicitly requests MVVM implementation, setting up ViewModel with INotifyPropertyChanged or ObservableObject, implementing ICommand or RelayCommand, wiring Form.DataContext, binding controls to ViewModel properties, creating Commands for button clicks, or separating business logic from UI code. Also triggers for \"WinForms MVVM\", \"ViewModel in WinForms\", \"INotifyPropertyChanged\", \"DataContext binding\", \"Command pattern WinForms\", \"ObservableObject\", \"RelayCommand\", and \"testable WinForms\". Also use when fixing existing MVVM code or when guided by winforms-feature-adoption scenario. DO NOT USE FOR: automatic application during version upgrades (opt-in only).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2432,2433,2434],{"name":20,"slug":21,"type":15},{"name":2403,"slug":2404,"type":15},{"name":2406,"slug":2407,"type":15},"2026-07-18T05:14:11.951511",{"slug":2437,"name":2437,"fn":2438,"description":2439,"org":2440,"tags":2441,"stars":25,"repoUrl":26,"updatedAt":2449},"migrating-aspnet-framework-to-core","migrate ASP.NET Framework to Core","Orchestrates migration of ASP.NET Framework (System.Web) MVC and WebAPI projects to ASP.NET Core. Covers only old .NET Framework web projects — not applicable to ASP.NET Core or modern .NET web projects (those are already on the target stack). Defines the ordered phase sequence (project file, host, config, DI, controllers, middleware, auth, views, cleanup), satellite skill dispatch, and migration unit breakdown for both in-place and side-by-side modes. Use when executing a task that upgrades a project with System.Web dependencies, HttpModules, HttpHandlers, MVC controllers, WebAPI controllers, or Global.asax. Also triggers for \"migrate ASP.NET to Core\", \"upgrade MVC project\", \"convert WebAPI to ASP.NET Core\". Not applicable to class libraries unless they directly reference System.Web.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2442,2443,2445,2448],{"name":20,"slug":21,"type":15},{"name":17,"slug":2444,"type":15},"asp-net-core",{"name":2446,"slug":2447,"type":15},"Backend","backend",{"name":23,"slug":24,"type":15},"2026-07-03T16:30:55.581898",{"slug":2451,"name":2451,"fn":2452,"description":2453,"org":2454,"tags":2455,"stars":25,"repoUrl":26,"updatedAt":2466},"migrating-documentdb-to-cosmos","migrate DocumentDB to Cosmos DB","Migrates from the deprecated Microsoft.Azure.DocumentDB SDK (V2) to the modern Microsoft.Azure.Cosmos SDK (V3) for Azure Cosmos DB. Use ONLY when Microsoft.Azure.DocumentDB has been flagged as deprecated or obsolete and must be replaced — not for version-bump scenarios where the V2 SDK is still supported.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2456,2459,2462,2465],{"name":2457,"slug":2458,"type":15},"Azure","azure",{"name":2460,"slug":2461,"type":15},"Cosmos DB","cosmos-db",{"name":2463,"slug":2464,"type":15},"Database","database",{"name":23,"slug":24,"type":15},"2026-07-03T16:31:21.932144",{"slug":130,"name":130,"fn":2468,"description":2469,"org":2470,"tags":2471,"stars":25,"repoUrl":26,"updatedAt":2476},"migrate Global.asax to ASP.NET Core middleware","Migrates Global.asax application lifecycle events to ASP.NET Core middleware, startup configuration, and Program.cs. Use when upgrading ASP.NET Framework apps containing Global.asax or Global.asax.cs files. Triggers for \"migrate Global.asax\", \"convert application events\", \"move Application_Start to Program.cs\", \"replace Global.asax with middleware\", and ASP.NET-to-Core migration involving request lifecycle, error handling, or session management.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2472,2473,2474,2475],{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-07T06:54:34.226435",19,{"items":2479,"total":2666},[2480,2502,2519,2540,2555,2572,2583,2596,2611,2626,2641,2654],{"slug":2481,"name":2481,"fn":2482,"description":2483,"org":2484,"tags":2485,"stars":2499,"repoUrl":2500,"updatedAt":2501},"rushstack-best-practices","manage Rush monorepos with best practices","Provides best practices and guidance for working with Rush monorepos. Use when the user is working in a Rush-based repository, asks about Rush commands (install, update, build, rebuild), needs help with project selection, dependency management, build caching, subspace configuration, or troubleshooting Rush-specific issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2486,2489,2492,2493,2496],{"name":2487,"slug":2488,"type":15},"Engineering","engineering",{"name":2490,"slug":2491,"type":15},"Local Development","local-development",{"name":9,"slug":8,"type":15},{"name":2494,"slug":2495,"type":15},"Project Management","project-management",{"name":2497,"slug":2498,"type":15},"Rush","rush",6484,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frushstack","2026-04-06T18:34:44.965032",{"slug":2503,"name":2503,"fn":2504,"description":2505,"org":2506,"tags":2507,"stars":2516,"repoUrl":2517,"updatedAt":2518},"azure-ai-agents-persistent-dotnet","build AI agents with Azure .NET SDK","Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: \"PersistentAgentsClient\", \"persistent agents\", \"agent threads\", \"agent runs\", \"streaming agents\", \"function calling agents .NET\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2508,2509,2512,2513],{"name":20,"slug":21,"type":15},{"name":2510,"slug":2511,"type":15},"Agents","agents",{"name":2457,"slug":2458,"type":15},{"name":2514,"slug":2515,"type":15},"LLM","llm",2804,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills","2026-07-03T16:32:10.297433",{"slug":2520,"name":2520,"fn":2521,"description":2522,"org":2523,"tags":2524,"stars":2516,"repoUrl":2517,"updatedAt":2539},"azure-ai-anomalydetector-java","build anomaly detection applications with Java","Build anomaly detection applications with Azure AI Anomaly Detector SDK for Java. Use when implementing univariate\u002Fmultivariate anomaly detection, time-series analysis, or AI-powered monitoring.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2525,2528,2529,2532,2535,2536],{"name":2526,"slug":2527,"type":15},"Analytics","analytics",{"name":2457,"slug":2458,"type":15},{"name":2530,"slug":2531,"type":15},"Data Analysis","data-analysis",{"name":2533,"slug":2534,"type":15},"Java","java",{"name":9,"slug":8,"type":15},{"name":2537,"slug":2538,"type":15},"Monitoring","monitoring","2026-05-13T06:14:16.261754",{"slug":2541,"name":2541,"fn":2542,"description":2543,"org":2544,"tags":2545,"stars":2516,"repoUrl":2517,"updatedAt":2554},"azure-ai-contentsafety-java","build content moderation applications with Azure AI","Build content moderation applications with Azure AI Content Safety SDK for Java. Use when implementing text\u002Fimage analysis, blocklist management, or harm detection for hate, violence, sexual content, and self-harm.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2546,2549,2550,2551],{"name":2547,"slug":2548,"type":15},"AI Infrastructure","ai-infrastructure",{"name":2457,"slug":2458,"type":15},{"name":2533,"slug":2534,"type":15},{"name":2552,"slug":2553,"type":15},"Security","security","2026-07-07T06:53:31.293235",{"slug":2556,"name":2556,"fn":2557,"description":2558,"org":2559,"tags":2560,"stars":2516,"repoUrl":2517,"updatedAt":2571},"azure-ai-contentsafety-py","detect harmful content with Azure AI Content Safety","Azure AI Content Safety SDK for Python. Use for detecting harmful content in text and images with multi-severity classification.\nTriggers: \"azure-ai-contentsafety\", \"ContentSafetyClient\", \"content moderation\", \"harmful content\", \"text analysis\", \"image analysis\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2561,2562,2565,2566,2567,2570],{"name":2457,"slug":2458,"type":15},{"name":2563,"slug":2564,"type":15},"Compliance","compliance",{"name":2514,"slug":2515,"type":15},{"name":9,"slug":8,"type":15},{"name":2568,"slug":2569,"type":15},"Python","python",{"name":2552,"slug":2553,"type":15},"2026-07-18T05:14:23.017504",{"slug":2573,"name":2573,"fn":2574,"description":2575,"org":2576,"tags":2577,"stars":2516,"repoUrl":2517,"updatedAt":2582},"azure-ai-language-conversations-py","implement conversational language understanding with Python","Implement Conversational Language Understanding (CLU) using the azure-ai-language-conversations Python SDK. Use when working with ConversationAnalysisClient to analyze conversation intent and entities, building NLP features, or integrating language understanding into applications.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2578,2579,2580,2581],{"name":2526,"slug":2527,"type":15},{"name":2457,"slug":2458,"type":15},{"name":2514,"slug":2515,"type":15},{"name":2568,"slug":2569,"type":15},"2026-07-31T05:54:29.068751",{"slug":2584,"name":2584,"fn":2585,"description":2586,"org":2587,"tags":2588,"stars":2516,"repoUrl":2517,"updatedAt":2595},"azure-ai-translation-text-py","translate text using Azure AI services","Azure AI Text Translation SDK for real-time text translation, transliteration, language detection, and dictionary lookup. Use for translating text content in applications.\nTriggers: \"text translation\", \"translator\", \"translate text\", \"transliterate\", \"TextTranslationClient\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2589,2592,2593,2594],{"name":2590,"slug":2591,"type":15},"API Development","api-development",{"name":2457,"slug":2458,"type":15},{"name":9,"slug":8,"type":15},{"name":2568,"slug":2569,"type":15},"2026-07-18T05:14:16.988376",{"slug":2597,"name":2597,"fn":2598,"description":2599,"org":2600,"tags":2601,"stars":2516,"repoUrl":2517,"updatedAt":2610},"azure-ai-vision-imageanalysis-py","analyze images with Azure AI Vision","Azure AI Vision Image Analysis SDK for captions, tags, objects, OCR, people detection, and smart cropping. Use for computer vision and image understanding tasks.\nTriggers: \"image analysis\", \"computer vision\", \"OCR\", \"object detection\", \"ImageAnalysisClient\", \"image caption\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2602,2603,2606,2609],{"name":2457,"slug":2458,"type":15},{"name":2604,"slug":2605,"type":15},"Computer Vision","computer-vision",{"name":2607,"slug":2608,"type":15},"Images","images",{"name":2568,"slug":2569,"type":15},"2026-07-18T05:14:18.007737",{"slug":2612,"name":2612,"fn":2613,"description":2614,"org":2615,"tags":2616,"stars":2516,"repoUrl":2517,"updatedAt":2625},"azure-appconfiguration-java","manage configuration with Azure App Configuration","Azure App Configuration SDK for Java. Centralized application configuration management with key-value settings, feature flags, and snapshots.\nTriggers: \"ConfigurationClient java\", \"app configuration java\", \"feature flag java\", \"configuration setting java\", \"azure config java\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2617,2618,2621,2624],{"name":2457,"slug":2458,"type":15},{"name":2619,"slug":2620,"type":15},"Configuration","configuration",{"name":2622,"slug":2623,"type":15},"Feature Flags","feature-flags",{"name":2533,"slug":2534,"type":15},"2026-07-03T16:32:01.278468",{"slug":2627,"name":2627,"fn":2628,"description":2629,"org":2630,"tags":2631,"stars":2516,"repoUrl":2517,"updatedAt":2640},"azure-cosmos-rust","build applications with Azure Cosmos DB","Azure Cosmos DB library for Rust (NoSQL API). Document CRUD, containers, and globally distributed data.\nTriggers: \"cosmos db rust\", \"CosmosClient rust\", \"document crud rust\", \"NoSQL rust\", \"partition key rust\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2632,2633,2634,2637],{"name":2460,"slug":2461,"type":15},{"name":2463,"slug":2464,"type":15},{"name":2635,"slug":2636,"type":15},"NoSQL","nosql",{"name":2638,"slug":2639,"type":15},"Rust","rust","2026-07-31T05:54:27.021432",{"slug":2642,"name":2642,"fn":2628,"description":2643,"org":2644,"tags":2645,"stars":2516,"repoUrl":2517,"updatedAt":2653},"azure-cosmos-ts","Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2646,2647,2648,2649,2650],{"name":2460,"slug":2461,"type":15},{"name":2463,"slug":2464,"type":15},{"name":9,"slug":8,"type":15},{"name":2635,"slug":2636,"type":15},{"name":2651,"slug":2652,"type":15},"TypeScript","typescript","2026-07-03T16:31:19.368382",{"slug":2655,"name":2655,"fn":2656,"description":2657,"org":2658,"tags":2659,"stars":2516,"repoUrl":2517,"updatedAt":2665},"azure-data-tables-java","build table storage applications with Java","Build table storage applications with Azure Tables SDK for Java. Use when working with Azure Table Storage or Cosmos DB Table API for NoSQL key-value data, schemaless storage, or structured data at scale.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2660,2661,2662,2663,2664],{"name":2457,"slug":2458,"type":15},{"name":2460,"slug":2461,"type":15},{"name":2463,"slug":2464,"type":15},{"name":2533,"slug":2534,"type":15},{"name":2635,"slug":2636,"type":15},"2026-05-13T06:14:17.582229",267]