To persist objects and restore them on next startup, XML serialization has done the job pretty well for me to date. But I'm currently having trouble with the ScriptingOptions class in the Microsoft.SqlServer.Management.Smo namespace.
Serializing the object produces the XML fragment shown below. But when I try to deserialize it, XmlSerializer throws an exception:
There is an error in XML document (n,n)
The inner exception is an InvalidOperationException:
Instance is read-only
The stack trace (included further below) identifies that it's trying to set the EncoderFallback property. This is further confirmed by the fact that deserialization succeeds if I edit the XML to remove the following element:
<Encoding xsi:type="UnicodeEncoding">
<EncoderFallback xsi:type="EncoderReplacementFallback" />
<DecoderFallback xsi:type="DecoderReplacementFallback" />
</Encoding>
So I want to exclude this Encoding
element, during either serialization or deserialization of the object.
I've searched for answers but all the custom serialization/deserialization approaches I found seem to assume access to the class source code, to add XMLIgnore or to implement ISerializable etc.
I suppose I could write a preprocessor that would parse the XML and chop out the offending element prior to deserialization, but surely there must be a more "proper" way than that?
The serialized object:
<ScriptingOptions>
<FileName />
<Encoding xsi:type="UnicodeEncoding">
<EncoderFallback xsi:type="EncoderReplacementFallback" />
<DecoderFallback xsi:type="DecoderReplacementFallback" />
</Encoding>
<DriWithNoCheck>false</DriWithNoCheck>
<IncludeFullTextCatalogRootPath>false</IncludeFullTextCatalogRootPath>
<BatchSize>1</BatchSize>
<ScriptDrops>false</ScriptDrops>
<TargetServerVersion>Version120</TargetServerVersion>
<TargetDatabaseEngineType>Standalone</TargetDatabaseEngineType>
<AnsiFile>false</AnsiFile>
<AppendToFile>false</AppendToFile>
<ToFileOnly>false</ToFileOnly>
<SchemaQualify>true</SchemaQualify>
<IncludeHeaders>false</IncludeHeaders>
<IncludeIfNotExists>true</IncludeIfNotExists>
<WithDependencies>false</WithDependencies>
<DriPrimaryKey>false</DriPrimaryKey>
<DriForeignKeys>false</DriForeignKeys>
<DriUniqueKeys>false</DriUniqueKeys>
<DriClustered>false</DriClustered>
<DriNonClustered>false</DriNonClustered>
<DriChecks>false</DriChecks>
<DriDefaults>false</DriDefaults>
<Triggers>false</Triggers>
<Statistics>false</Statistics>
<ClusteredIndexes>false</ClusteredIndexes>
<NonClusteredIndexes>false</NonClusteredIndexes>
<NoAssemblies>false</NoAssemblies>
<PrimaryObject>true</PrimaryObject>
<Default>true</Default>
<XmlIndexes>false</XmlIndexes>
<FullTextCatalogs>false</FullTextCatalogs>
<FullTextIndexes>false</FullTextIndexes>
<FullTextStopLists>false</FullTextStopLists>
<Indexes>false</Indexes>
<DriIndexes>false</DriIndexes>
<DriAllKeys>false</DriAllKeys>
<DriAllConstraints>false</DriAllConstraints>
<DriAll>false</DriAll>
<Bindings>false</Bindings>
<NoFileGroup>false</NoFileGroup>
<NoFileStream>false</NoFileStream>
<NoFileStreamColumn>false</NoFileStreamColumn>
<NoCollation>false</NoCollation>
<ContinueScriptingOnError>false</ContinueScriptingOnError>
<IncludeDatabaseRoleMemberships>false</IncludeDatabaseRoleMemberships>
<Permissions>false</Permissions>
<AllowSystemObjects>true</AllowSystemObjects>
<NoIdentities>false</NoIdentities>
<ConvertUserDefinedDataTypesToBaseType>false</ConvertUserDefinedDataTypesToBaseType>
<TimestampToBinary>false</TimestampToBinary>
<AnsiPadding>false</AnsiPadding>
<ExtendedProperties>false</ExtendedProperties>
<DdlHeaderOnly>false</DdlHeaderOnly>
<DdlBodyOnly>false</DdlBodyOnly>
<NoViewColumns>false</NoViewColumns>
<SchemaQualifyForeignKeysReferences>false</SchemaQualifyForeignKeysReferences>
<AgentAlertJob>false</AgentAlertJob>
<AgentJobId>true</AgentJobId>
<AgentNotify>false</AgentNotify>
<LoginSid>false</LoginSid>
<NoCommandTerminator>false</NoCommandTerminator>
<NoIndexPartitioningSchemes>false</NoIndexPartitioningSchemes>
<NoTablePartitioningSchemes>false</NoTablePartitioningSchemes>
<IncludeDatabaseContext>false</IncludeDatabaseContext>
<NoXmlNamespaces>false</NoXmlNamespaces>
<DriIncludeSystemNames>false</DriIncludeSystemNames>
<OptimizerData>false</OptimizerData>
<NoExecuteAs>false</NoExecuteAs>
<EnforceScriptingOptions>false</EnforceScriptingOptions>
<NoMailProfileAccounts>false</NoMailProfileAccounts>
<NoMailProfilePrincipals>false</NoMailProfilePrincipals>
<NoVardecimal>true</NoVardecimal>
<ChangeTracking>false</ChangeTracking>
<ScriptDataCompression>true</ScriptDataCompression>
<ScriptSchema>true</ScriptSchema>
<ScriptData>false</ScriptData>
<ScriptBatchTerminator>false</ScriptBatchTerminator>
<ScriptOwner>false</ScriptOwner>
</ScriptingOptions>
The stack trace on attempting to deserialize the above XML:
StackTrace " at System.Text.Encoding.set_EncoderFallback(EncoderFallback value)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read13_UnicodeEncoding(Boolean isNullable, Boolean checkType)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read7_Encoding(Boolean isNullable, Boolean checkType)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read10_ScriptingOptions(Boolean isNullable, Boolean checkType)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read14_TableScriptingOptions(Boolean isNullable, Boolean checkType)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read15_UserSettings(Boolean isNullable, Boolean checkType)\r\n
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUserSettings.Read16_UserSettings()" string