Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArgumentNullException when Deserializing Inherit Class with empty Migration #414

Closed
imperiobadgo opened this issue Jul 15, 2020 · 10 comments
Assignees
Labels
bug (cc: fix) Something isn't working

Comments

@imperiobadgo
Copy link

I've found an Issue in my Project with deserializing via a Migration. I've created the following Example to reproduce the behaviour:

using ExtendedXmlSerializer;
using ExtendedXmlSerializer.Configuration;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;

namespace Test
{
 class IssueExample
  {
    static void Main(string[] args)
    {
      var serializer = new ConfigurationContainer().Type<Base>().AddMigration(new EmptyMigration()).Create();
      var container = new Container { Content = new AnotherNameSpace.Inherit() };
      var xml = serializer.Serialize(container);
      var loaded = serializer.Deserialize<Container>(xml); //Throws System.ArgumentNullException
    }
  }

  public class Container
  {
    public Base Content { get; set; }
  }

  public class Base { }

  namespace AnotherNameSpace
  {
    public class Inherit : Base { }
  }

  public class EmptyMigration : IEnumerable<Action<XElement>>
  {
    public IEnumerator<Action<XElement>> GetEnumerator()
    {
      yield return x => { }; //Do nothing
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

  }
}

The Key-Elements are the inherit class inside the container object and the empty migration which changes something. If you remove the namespace "AnotherNameSpace", another exception appears. The whole thing has something to do with namespaces. In the following the stacktrace:

System.ArgumentNullException
  HResult=0x80004003
  Message=Value cannot be null.
Parametername: key
  Source=mscorlib
  StackTrace:
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at ExtendedXmlSerializer.Core.Sources.CacheBase`2.Get(TKey key) in ExtendedXmlSerializer\Core\Sources\CacheBase.cs:line 34
   at ExtendedXmlSerializer.ContentModel.Identification.IdentityStore.Get(String name, String identifier) in ExtendedXmlSerializer\ContentModel\Identification\IdentityStore.cs:line 10
   at ExtendedXmlSerializer.ExtensionModel.Xml.IdentityMapper.Get(String name, String identifier) in ExtendedXmlSerializer\ExtensionModel\Xml\IdentityMapper.cs:line 17
   at ExtendedXmlSerializer.ContentModel.Reflection.TypePartReflector.Create(TypeParts parameter) in ExtendedXmlSerializer\ContentModel\Reflection\TypePartReflector.cs:line 24
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at ExtendedXmlSerializer.Core.Sources.CacheBase`2.Get(TKey key) in ExtendedXmlSerializer\Core\Sources\CacheBase.cs:line 34
   at ExtendedXmlSerializer.ContentModel.Reflection.TypeParser.Create(String parameter) in ExtendedXmlSerializer\ContentModel\Reflection\TypeParser.cs:line 22
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at ExtendedXmlSerializer.Core.Sources.CacheBase`2.Get(TKey key) in ExtendedXmlSerializer\Core\Sources\CacheBase.cs:line 34
   at ExtendedXmlSerializer.ContentModel.Reflection.ReflectionParser.Create(String parameter) in ExtendedXmlSerializer\ContentModel\Reflection\ReflectionParser.cs:line 41
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at ExtendedXmlSerializer.Core.Sources.CacheBase`2.Get(TKey key) in ExtendedXmlSerializer\Core\Sources\CacheBase.cs:line 34
   at ExtendedXmlSerializer.ExtensionModel.Xml.FormatReaderContext.Get(String parameter) in ExtendedXmlSerializer\ExtensionModel\Xml\FormatReaderContext.cs:line 19
   at ExtendedXmlSerializer.ExtensionModel.Xml.XmlReader.Get(String parameter) in ExtendedXmlSerializer\ExtensionModel\Xml\XmlReader.cs:line 28
   at ExtendedXmlSerializer.ContentModel.Format.ParsedContent`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Format\ParsedContent.cs:line 16
   at ExtendedXmlSerializer.ContentModel.Format.ContextualReader`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Format\ContextualReader.cs:line 17
   at ExtendedXmlSerializer.ContentModel.DecoratedReader`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\DecoratedReader.cs:line 26
   at ExtendedXmlSerializer.ContentModel.Reflection.TypedParsingReader.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Reflection\TypedParsingReader.cs:line 15
   at ExtendedXmlSerializer.ContentModel.TrackingReader`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\TrackingReader.cs:line 13
   at ExtendedXmlSerializer.ContentModel.Members.Extensions.GetIfAssigned[T](IReader`1 this, IFormatReader reader) in ExtendedXmlSerializer\ContentModel\Members\Extensions.cs:line 12
   at ExtendedXmlSerializer.ContentModel.Serializer`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Serializer.cs:line 22
   at ExtendedXmlSerializer.ContentModel.Properties.Property`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Properties\Property.cs:line 17
   at ExtendedXmlSerializer.ContentModel.Reflection.Classification.FromAttributes(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Reflection\Classification.cs:line 37
   at ExtendedXmlSerializer.ContentModel.Reflection.Classification.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Reflection\Classification.cs:line 31
   at ExtendedXmlSerializer.ContentModel.Reflection.Activation.RuntimeActivator.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Reflection\Activation.cs:line 61
   at ExtendedXmlSerializer.ExtensionModel.Xml.XmlInnerContentActivator.Get(IFormatReader parameter) in ExtendedXmlSerializer\ExtensionModel\Xml\XmlInnerContentActivator.cs:line 20
   at ExtendedXmlSerializer.ContentModel.Content.InnerContentReader.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Content\InnerContentReader.cs:line 21
   at ExtendedXmlSerializer.ContentModel.Members.Extensions.GetIfAssigned[T](IReader`1 this, IFormatReader reader) in ExtendedXmlSerializer\ContentModel\Members\Extensions.cs:line 12
   at ExtendedXmlSerializer.ContentModel.Serializer`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Serializer.cs:line 22
   at ExtendedXmlSerializer.ExtensionModel.Xml.MigrationsExtension.Contents.Serializer.Get(IFormatReader parameter) in ExtendedXmlSerializer\ExtensionModel\Xml\MigrationsExtension.cs:line 149
   at ExtendedXmlSerializer.ContentModel.Members.Extensions.GetIfAssigned[T](IReader`1 this, IFormatReader reader) in ExtendedXmlSerializer\ContentModel\Members\Extensions.cs:line 12
   at ExtendedXmlSerializer.ContentModel.Serializer`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Serializer.cs:line 22
   at ExtendedXmlSerializer.ContentModel.Members.MemberSerializer.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Members\MemberSerializer.cs:line 22
   at ExtendedXmlSerializer.ContentModel.Members.MemberHandler.Handle(IInnerContent contents, IMemberSerializer member) in ExtendedXmlSerializer\ContentModel\Members\MemberHandler.cs:line 13
   at ExtendedXmlSerializer.ContentModel.Content.InnerContentServices.Handle(IInnerContent contents, IMemberSerializer member) in ExtendedXmlSerializer\ContentModel\Content\InnerContentServices.cs:line 41
   at ExtendedXmlSerializer.ContentModel.Members.MemberInnerContentHandler.IsSatisfiedBy(IInnerContent parameter) in ExtendedXmlSerializer\ContentModel\Members\MemberInnerContentHandler.cs:line 29
   at ExtendedXmlSerializer.ContentModel.Content.InnerContentReader.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Content\InnerContentReader.cs:line 26
   at ExtendedXmlSerializer.ContentModel.Members.Extensions.GetIfAssigned[T](IReader`1 this, IFormatReader reader) in ExtendedXmlSerializer\ContentModel\Members\Extensions.cs:line 12
   at ExtendedXmlSerializer.ContentModel.Serializer`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\Serializer.cs:line 22
   at ExtendedXmlSerializer.ContentModel.SerializerAdapter`1.Get(IFormatReader parameter) in ExtendedXmlSerializer\ContentModel\SerializerAdapter.cs:line 41
   at ExtendedXmlSerializer.ExtensionModel.Xml.Read.Get(XmlReader parameter) in ExtendedXmlSerializer\ExtensionModel\Xml\Read.cs:line 26
   at ExtendedXmlSerializer.ExtensionModel.Xml.Serializer.Deserialize(XmlReader reader) in ExtendedXmlSerializer\ExtensionModel\Xml\Serializer.cs:line 21
   at ExtendedXmlSerializer.ExtensionModel.Xml.ExtendedXmlSerializer.Deserialize(XmlReader reader) in ExtendedXmlSerializer\ExtensionModel\Xml\ExtendedXmlSerializer.cs:line 18
   at ExtendedXmlSerializer.ExtensionMethodsForSerialization.Deserialize[T](IExtendedXmlSerializer this, XmlReaderSettings settings, Stream stream) in ExtendedXmlSerializer\ExtensionMethodsForSerialization.cs:line 145
   at ExtendedXmlSerializer.ExtensionMethodsForSerialization.Deserialize[T](IExtendedXmlSerializer this, XmlReaderSettings settings, String data) in ExtendedXmlSerializer\ExtensionMethodsForSerialization.cs:line 121
   at ExtendedXmlSerializer.ExtensionMethodsForSerialization.Deserialize[T](IExtendedXmlSerializer this, String data) in ExtendedXmlSerializer\ExtensionMethodsForSerialization.cs:line 109
   at Test.IssueExample.Main(String[] args) in IssueExample.cs:line 17

  This exception was originally thrown at this call stack:
    [External Code]
    ExtendedXmlSerializer.Core.Sources.CacheBase<TKey, TValue>.Get(TKey) in CacheBase.cs
    ExtendedXmlSerializer.ContentModel.Identification.IdentityStore.Get(string, string) in IdentityStore.cs
    ExtendedXmlSerializer.ExtensionModel.Xml.IdentityMapper.Get(string, string) in IdentityMapper.cs
    ExtendedXmlSerializer.ContentModel.Reflection.TypePartReflector.Create(ExtendedXmlSerializer.ContentModel.Conversion.TypeParts) in TypePartReflector.cs
    [External Code]
    ExtendedXmlSerializer.Core.Sources.CacheBase<TKey, TValue>.Get(TKey) in CacheBase.cs
    ExtendedXmlSerializer.ContentModel.Reflection.TypeParser.Create(string) in TypeParser.cs
    [External Code]
    ExtendedXmlSerializer.Core.Sources.CacheBase<TKey, TValue>.Get(TKey) in CacheBase.cs
    ...
    [Call Stack Truncated]
@issue-label-bot issue-label-bot bot added the bug (cc: fix) Something isn't working label Jul 15, 2020
@issue-label-bot
Copy link

Issue-Label Bot is automatically applying the label bug to this issue, with a confidence of 0.85. Please mark this comment with 👍 or 👎 to give our bot feedback!

Links: app homepage, dashboard and code for this bot.

@Mike-E-angelo Mike-E-angelo self-assigned this Jul 15, 2020
@Mike-E-angelo
Copy link
Member

Thank you for reporting this @imperiobadgo. I am a little slammed today but should be able to look into this for you tomorrow. I will update you with any findings then. 👍

@Mike-E-angelo
Copy link
Member

Mike-E-angelo commented Jul 16, 2020

Alright @imperiobadgo I have managed to successfully reproduce this issue on my end. Note that this appears to occur when applying a migration to a base type. I was able to reproduce this with having both types in the same namespace.

I am looking into this now but from the outset it looks like an ugly one so I am not sure if I will be able to fix it with time constraints per #383.

In the meantime, it does appear if you configure the type directly that it does work as expected. I know that's a bit of a pain (if you have a lot of inherited types to configure) but it should serve as a workaround until this is fixed.

var serializer = new ConfigurationContainer().Type<AnotherNameSpace.Inherit>().AddMigration(new EmptyMigration()).Create();
var container = new Container { Content = new AnotherNameSpace.Inherit() };

Please let me know if the above workaround gets you unblocked in the meantime.

@Mike-E-angelo
Copy link
Member

Mike-E-angelo commented Jul 16, 2020

FWIW we are most definitely in "viewing code you wrote ~four years ago and WTF WERE YOU THINKING" territory now.

😂😂😂

😭😭😭

@Mike-E-angelo
Copy link
Member

Good news @imperiobadgo... I have a possible fix for you. Please try the build out here:

#415 (comment)

And let me know if that treats you any better. 🤞

@imperiobadgo
Copy link
Author

Thank you so much for taking care of this problem. This serializer helps me to cover all kinds of special scenarios very elegantly, which otherwise would be very complicated to solve. And I am very grateful for your hard work.

I've already found another workaround: If I serialize the "inherit" object inside a list with only one entry, it works just fine.

@imperiobadgo
Copy link
Author

Good news @imperiobadgo... I have a possible fix for you. Please try the build out here:

#415 (comment)

And let me know if that treats you any better. 🤞

Thank you very much, it throws no exception anymore. I am still testing if old saves can be migrated and loaded.

@Mike-E-angelo
Copy link
Member

Woohoo! Glad to hear. Please let me know if you encounter any further issues. I will slate the fix release for next Tuesday and update here when available on Nuget. Please use the preview builds until then. 👍

@imperiobadgo
Copy link
Author

imperiobadgo commented Jul 16, 2020

It works just perfect. Older save can still be migrated and desirialized!

@Mike-E-angelo
Copy link
Member

Mike-E-angelo commented Jul 21, 2020

Alright! v3.2.3 is now available on NuGet:

https://www.nuget.org/packages/ExtendedXmlSerializer/

Thank you for improving the quality of ExtendedXmlSerializer. Please let us know if you have any further issues and we will look into them for you. 👍 Closing for now.

An extensible Xml Serializer for .NET that builds on the functionality of the classic XmlSerializer with a powerful and robust extension model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug (cc: fix) Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants