Web服务器闲置后CMS对象返回页面时丢失问题技术求助
This is a tricky scenario with clear patterns—let’s dig into the root causes and actionable fixes based on your problem details:
Core Observations to Anchor Our Investigation
Your issue happens only after 20-30 minutes of server idle, triggers OnModelCreating right before failure, and resolves only after app pool recycling. Crucially:
- Repository layer confirms the object exists before returning
- Other EF-powered pages work fine
- The null appears only when crossing assembly boundaries (CMS module → main website)
Key Troubleshooting Directions
1. Cross-Assembly Type Mismatch (Most Likely Culprit)
When IIS idles, it may unload unused assemblies. When the CMS module is reloaded, the CLR might load it into a different assembly context—making what looks like the same ICMSPageVersion type actually incompatible between the main website and CMS module.
How to Verify:
- Add logs in both the repository layer (CMS module) and page layer (main website) to print the full assembly-qualified type name of the returned object:
// In repository/domain logic layer Debug.Log($"Returning type: {dcPv.GetType().AssemblyQualifiedName}"); // In page layer Debug.Log($"Received type: {PageVersion?.GetType().AssemblyQualifiedName ?? "NULL"}"); - If the names don’t match (even if the type name is identical), you have an assembly loading mismatch.
Fixes:
- Move the
ICMSPageVersioninterface (and all shared DTOs/implementations) into a separate shared class library that both the main website and CMS module reference directly. Avoid referencing the CMS module’s DLL directly from the main website if possible. - Disable IIS assembly unloading for testing: Adjust the app pool’s "Load User Profile" setting to
True, or enable "Always Running" to prevent idle unloading.
2. EF Context Lifecycle & State Corruption
Your repository modifies ProxyCreationEnabled on the EF context, but if the context is a singleton or has an overly long lifecycle, idle time can leave it in an invalid state (e.g., stale database connections, cached metadata).
How to Verify:
- Check if your EF context is registered as
Scoped(per-request) in your dependency injection container. If it’sSingletonorTransientwith reuse, that’s a red flag. - Add logs to track context instance IDs:
If the same instance is used across idle periods, it’s likely corrupted.Debug.Log($"Using context instance: {_ctx.GetHashCode()}");
Fixes:
- Enforce per-request EF context lifecycle (Scoped in ASP.NET Core, or request-bound in older ASP.NET).
- After fetching data in the repository, detach the entity from the context to avoid future state issues:
_ctx.Entry(pv).State = EntityState.Detached; - Wrap the proxy setting change in a
try/finallyblock to ensure it’s always restored, even if an exception occurs.
3. Silent Type Conversion Exceptions
It’s possible the object is being returned, but a failed type conversion (between CMS module’s implementation and main website’s interface) is being swallowed, leaving you with null.
How to Verify:
- Wrap the page layer’s assignment in a
try/catchblock to catch hidden cast exceptions:try { PageVersion = _pageVersionCache.GetPageVersionById(pageVersionId); } catch (Exception ex) { Debug.Log($"Type conversion failed: {ex.Message}"); }
Fixes:
- Ensure all implementations of
ICMSPageVersionare accessible to the main website. If using dynamic proxies (e.g., fromCreateDcControlledInstance()), generate them in the shared class library instead of the CMS module. - Avoid implicit casting; use explicit casting with error handling, or return concrete DTOs instead of interfaces across assembly boundaries.
4. Cache & GC Interaction (Less Likely, But Worth Checking)
Even though you noted the issue existed before caching, idle GC might be cleaning up objects with weak references, and re-fetching them triggers the cross-assembly issue.
Fixes:
- If using memory cache, avoid weak reference policies for CMS page objects.
- Add a deep copy step when returning objects across assemblies (e.g., serialize to JSON and deserialize back) to break any assembly-bound references:
// Example in domain logic layer var json = JsonSerializer.Serialize(dcPv); return JsonSerializer.Deserialize<ICMSPageVersion>(json);
Quick Validation Steps
- Force Idle: Set your app pool’s idle timeout to 5 minutes, wait, then test the CMS request to reproduce the issue quickly.
- Bypass Cross-Assembly Calls: Temporarily move the CMS repository logic into the main website to see if the null issue disappears. If it does, the problem is definitely assembly-related.
- Disable Proxy Creation Entirely: Test with
ProxyCreationEnabled = falsepermanently in your EF context configuration to rule out proxy-related type issues.
内容的提问来源于stack exchange,提问作者Thierry Verhaegen

