{"record":{"id":"8259d84cc6400adf","repo":"dotnet/wpf","slug":"sr-format-sr-customcontentstatemustbeserializable-type","errorCode":null,"errorMessage":"SR.Format(SR.CustomContentStateMustBeSerializable, type)","messagePattern":"SR\\.Format\\(SR\\.CustomContentStateMustBeSerializable, type\\)","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs","lineNumber":3231,"sourceCode":"\n            // _customContentStateToSave can be preset by AddBackEntry() or FireNavigating().\n            // If not, try the IProvideCustomContentState callback.\n            CustomContentState ccs = _customContentStateToSave;\n            if (ccs == null)\n            {\n                IProvideCustomContentState pccs = _bp as IProvideCustomContentState;\n                if (pccs != null)\n                {\n                    ccs = pccs.GetContentState();\n                }\n            }\n            if (ccs != null)\n            {\n                // Make sure the object is serializable\n                Type type = ccs.GetType();\n                if (!type.IsSerializable)\n                {\n                    throw new SystemException(SR.Format(SR.CustomContentStateMustBeSerializable, type));\n                }\n                journalEntry.CustomContentState = ccs;\n            }\n            // Info: CustomContentState for the current page in child frames is saved in\n            // DataStreams.SaveState(). (This requires the IProvideCustomContentState to be implemented.)\n\n            // Root Viewer journaling\n            if (_rootViewerStateToSave != null) // state saved in advance?\n            {\n                journalEntry.RootViewerState = _rootViewerStateToSave;\n                _rootViewerStateToSave = null;\n            }\n            else\n            {\n                journalEntry.RootViewerState = GetRootViewerState(journalReason);\n            }\n\n            // Set the friendly Name of this JournalEntry, it will be used to display","sourceCodeStart":3213,"sourceCodeEnd":3249,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs#L3213-L3249","documentation":"When saving a journal entry that carries a CustomContentState, the service verifies the state object's type is serializable. Non-serializable CustomContentState objects cannot survive journal serialization (e.g. saving to disk for Remember navigation), so a SystemException is thrown naming the offending type.","triggerScenarios":"Calling NavigationService.AddBackEntry / creating journal entries with a CustomContentState subclass not marked [Serializable] (and not implementing ISerializable), especially with NavigationMode.Remember navigation.","commonSituations":"Custom view-state class missing [Serializable] attribute; CustomContentState added in IProvideCustomContentState implementations; journal persistence paths that require serialization.","solutions":["Mark the CustomContentState class [Serializable] and implement ISerializable correctly.","Ensure all fields of the CustomContentState are serializable types.","Store non-serializable data by reference/key and rebuild it in Reapply().","Test journal save/load early in development of custom state."],"exampleFix":"// before\nclass MyState : CustomContentState { public MyControl C; }\n// after\n[Serializable]\nclass MyState : CustomContentState {\n    public string ControlId; // serializable data instead of live control\n    public override void Reapply(object navigationContent, NavigationMode mode) { ... }\n}","handlingStrategy":"validation","validationCode":"bool stateIsSerializable(CustomContentState ccs) => ccs == null || ccs.GetType().IsSerializable;","typeGuard":"bool IsSerializableState<T>(T state) where T : CustomContentState => state.GetType().IsSerializable;","tryCatchPattern":"try { navService.AddBackEntry(myState); }\ncatch (SystemException ex) when (ex.Message.Contains(\"serializable\"))\n{ /* log type and fix [Serializable] */ }","preventionTips":["Always mark CustomContentState subclasses [Serializable].","Keep state fields to serializable primitives.","Add a unit test that round-trips state via a BinaryFormatter/MemoryStream.","Store live controls by identifier, rebuild in Reapply."],"tags":["wpf","navigation","serialization","journal"],"backgroundTag":"schema-validation-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}