mercredi 2 décembre 2015

Use CustomReflectionContext with XmlSerializer

Is it possible to use CustomReflectionContext with XmlSerializer? I have no idea why anyone would want to do this; the purpose of this question is simply to explore possible usage scenarios of the CustomReflectionContext.

To get this sample to compile, add a reference to System.Reflection.Context.

public class MyReflectionContext : CustomReflectionContext
{

}

[Serializable]
public class Foo
{

}

static class Program
{
    private static void Main(string[] args)
    {
        var ctx = new MyReflectionContext();
        var foo = new Foo();
        var unmappedType = foo.GetType();
        var mappedType = ctx.MapType(unmappedType.GetTypeInfo()).AsType();
        var serializer = new XmlSerializer(mappedType);
    }
}

The last line causes an InvalidCastException:

Unable to cast object of type 'System.Reflection.Context.Custom.CustomModule' to type 'System.Reflection.RuntimeModule'.

at System.Reflection.Emit.ModuleBuilder.GetTypeTokenWorkerNoLock(Type type, Boolean getGenericDefinition)
at System.Reflection.Emit.ModuleBuilder.GetTypeTokenInternal(Type type, Boolean getGenericDefinition)
at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, Type cls)
at System.Xml.Serialization.CodeGenerator.Castclass(Type target)
at System.Xml.Serialization.CodeGenerator.InternalConvert(Type source, Type target, Boolean isAddress)
at System.Xml.Serialization.SourceInfo.InternalLoad(Type elementType, Boolean asAddress)
at System.Xml.Serialization.SourceInfo.Load(Type elementType)
at System.Xml.Serialization.XmlSerializationWriterILGen.WriteElement(SourceInfo source, ElementAccessor element, String arrayName, Boolean writeAccessor)
at System.Xml.Serialization.XmlSerializationWriterILGen.WriteElements(SourceInfo source, String enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, String arrayName, Boolean writeAccessors, Boolean isNullable)
at System.Xml.Serialization.XmlSerializationWriterILGen.WriteMember(SourceInfo source, String choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, Boolean writeAccessors)
at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateTypeElement(XmlTypeMapping xmlTypeMapping)
at System.Xml.Serialization.XmlSerializationWriterILGen.GenerateElement(XmlMapping xmlMapping)
at System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at Sandbox.Program.Main(String[] args)

If you add a property to Foo:

[Serializable]
public class Foo
{
    public string X { get; set; }
}

The exception changes to:

There was an error reflecting type 'Sandbox.Foo'.:

To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. System.String does not implement Add(System.Object).

How do I resolve this?





Aucun commentaire:

Enregistrer un commentaire