liuhaipeng905 / servicestack

Automatically exported from code.google.com/p/servicestack
0 stars 1 forks source link

TypeSerializer.SerializeToString[T](T value) throws System.ArgumentException "An item with the same key has already been added." #13

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Using the latest TypeSerializer in my own application a got an exception during 
serialization.

Following test object:

[Serializable]
public abstract class CorrelativeDataBase
{
    protected CorrelativeDataBase()
    {
        CorrelationIdentifier = GetNextId();
    }

    public Guid CorrelationIdentifier { get; set; }

    protected static Guid GetNextId()
    {
        return Guid.NewGuid();
    }
}

[Serializable]
public sealed class TestObject : CorrelativeDataBase
{
    public Type SomeType { get; set; }
    public string SomeString { get; set; }
    public IEnumerable<Type> SomeTypeList { get; set; }
    public IEnumerable<Type> SomeTypeList2 { get; set; }
    public IEnumerable<object> SomeObjectList { get; set; }
}

Due a interface limitation i dont know the type of the object to serialize, so 
my test call was:

var obj = new TestObject()
{
    SomeType = typeof(string),
    SomeString = "Test",
    SomeObjectList = new object[0];
}

var result = TypeSerializer.SerializeToString<object>(obj);

Following Exception was the result:

System.TypeInitializationException was unhandled
  Message="The type initializer for 'ServiceStack.Text.Jsv.JsvWriter`1' threw an exception."
  Source="ServiceStack.Text"
  TypeName="ServiceStack.Text.Jsv.JsvWriter`1"
  StackTrace:
       at ServiceStack.Text.Jsv.JsvWriter`1.WriteFn()
       at ServiceStack.Text.Jsv.JsvWriter.GetWriteFn(Type type) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 39
       at ServiceStack.Text.Jsv.JsvWriter.WriteLateBoundObject(TextWriter writer, Object value) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 49
       at ServiceStack.Text.Jsv.JsvWriter`1.WriteObject(TextWriter writer, Object value) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 224
       at ServiceStack.Text.TypeSerializer.SerializeToString[T](T value) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\TypeSerializer.cs:line 100
       at Serialization.ServiceStackTypeSerializer.Serialize(Object obj)
       at .....
  InnerException: System.TypeInitializationException
       Message="The type initializer for 'ServiceStack.Text.Jsv.WriteType`1' threw an exception."
       Source="ServiceStack.Text"
       TypeName="ServiceStack.Text.Jsv.WriteType`1"
       StackTrace:
            at ServiceStack.Text.Jsv.WriteType`1.get_Write() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 32
            at ServiceStack.Text.Jsv.JsvWriter`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 205
            at ServiceStack.Text.Jsv.JsvWriter`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 106
       InnerException: System.TypeInitializationException
            Message="The type initializer for 'ServiceStack.Text.Jsv.JsvWriter`1' threw an exception."
            Source="ServiceStack.Text"
            TypeName="ServiceStack.Text.Jsv.JsvWriter`1"
            StackTrace:
                 at ServiceStack.Text.Jsv.JsvWriter`1.WriteFn()
                 at ServiceStack.Text.Jsv.JsvWriter.GetWriteFn(Type type) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 39
                 at ServiceStack.Text.Jsv.WriteType`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 51
                 at ServiceStack.Text.Jsv.WriteType`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 27
            InnerException: System.TypeInitializationException
                 Message="The type initializer for 'ServiceStack.Text.Jsv.WriteType`1' threw an exception."
                 Source="ServiceStack.Text"
                 TypeName="ServiceStack.Text.Jsv.WriteType`1"
                 StackTrace:
                      at ServiceStack.Text.Jsv.WriteType`1.get_Write() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 32
                      at ServiceStack.Text.Jsv.JsvWriter`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 205
                      at ServiceStack.Text.Jsv.JsvWriter`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 106
                 InnerException: System.TypeInitializationException
                      Message="The type initializer for 'ServiceStack.Text.Jsv.JsvWriter`1' threw an exception."
                      Source="ServiceStack.Text"
                      TypeName="ServiceStack.Text.Jsv.JsvWriter`1"
                      StackTrace:
                           at ServiceStack.Text.Jsv.JsvWriter`1.WriteFn()
                           at ServiceStack.Text.Jsv.JsvWriter.GetWriteFn(Type type) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 39
                           at ServiceStack.Text.Jsv.WriteType`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 51
                           at ServiceStack.Text.Jsv.WriteType`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 27
                      InnerException: System.TypeInitializationException
                           Message="The type initializer for 'ServiceStack.Text.Jsv.WriteType`1' threw an exception."
                           Source="ServiceStack.Text"
                           TypeName="ServiceStack.Text.Jsv.WriteType`1"
                           StackTrace:
                                at ServiceStack.Text.Jsv.WriteType`1.get_Write() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 32
                                at ServiceStack.Text.Jsv.JsvWriter`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 205
                                at ServiceStack.Text.Jsv.JsvWriter`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 106
                           InnerException: System.ArgumentException
                                Message="An item with the same key has already been added."
                                Source="mscorlib"
                                StackTrace:
                                     at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
                                     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
                                     at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
                                     at ServiceStack.Text.Jsv.JsvWriter.GetWriteFn(Type type) in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\JsvWriter.Generic.cs:line 40
                                     at ServiceStack.Text.Jsv.WriteType`1.GetWriteFn() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 51
                                     at ServiceStack.Text.Jsv.WriteType`1..cctor() in C:\Projects\servicestack\Common\ServiceStack.Text\ServiceStack.Text\Jsv\WriteType.cs:line 27
                                InnerException: 

Original issue reported on code.google.com by daniel.n...@gmail.com on 16 Jun 2010 at 9:27

GoogleCodeExporter commented 9 years ago
It looks like the TypeSerializer is unable to serialize a System.Type:

typeof (string).SerializeAndFormat();

throws the same exception.

Original comment by daniel.n...@gmail.com on 16 Jun 2010 at 9:38

GoogleCodeExporter commented 9 years ago
Hi,

Yeah it didn't support serializing 'Type' properties because I had to 
specifically provide support for it. 
I've quickly just added support for it and should now work in v1.32 of 
ServiceStack or later. 
You can download the latest version from: 
http://servicestack.googlecode.com/files/ServiceStack.Text.zip

I've added your example as a test you can see here, so it should hopefully work 
for you as well:
http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Te
xt/ServiceStack.Text.Tests/ReportedIssues.cs

Just a couple of things, you don't need to mark your classes as [Serializable] 
and as you might've guessed, 'SerializeAndFormat' uses TypeSerializer 
underneath so will exhibit the same behaviour.

Thanks for your feedback. Let me know if the latest version works for you so I 
can close this issue.

Cheers,
Demis

Original comment by demis.be...@gmail.com on 17 Jun 2010 at 1:38

GoogleCodeExporter commented 9 years ago
Hello,

the new Assembly fixes the Type problem, but throws again the duplicate key 
exception on other objects ;)
I'll investigate today and post a new test case.

@System.Type serialization:
It would be more non-ambiguous if you use type.FullName instead of Type.Name 
during serialization.

Thanks for your very fast response.

Original comment by daniel.n...@gmail.com on 17 Jun 2010 at 5:46

GoogleCodeExporter commented 9 years ago
hmmmm, I am using 'Type.FullName', and I'm no longer getting that Exception. 
Can you make sure that you're using the latest binary.

Otherwise can you provide some sample code where its failing?

Original comment by demis.be...@gmail.com on 17 Jun 2010 at 8:19

GoogleCodeExporter commented 9 years ago
Sorry, i meant: type.AssemblyQualifiedName

Original comment by daniel.n...@gmail.com on 17 Jun 2010 at 9:23

GoogleCodeExporter commented 9 years ago
Hi,

Try the latest build, it has most of your tests passing (with caveats)
http://servicestack.googlecode.com/files/ServiceStack.Text.zip

I have incorporated your tests into the test suite and have left comments where 
I've needed to do work arounds or document limitations
http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Te
xt/ServiceStack.Text.Tests/DynamicModels/ComplexObjectGraphTest.cs

The important part to remember is since I don't serialize any Type information 
with the payload, I will require the Type information to de-serialize it 
correctly. e.g. If you serialize an 'object' Property and de-serialize it back 
again with an 'object' type it will leave it as the serialized 'string' since 
thats a valid object. Now if you store the Type information with the payload 
then you have a chance to reconstruct it with the serialized string value.

Check out the last test and it will show you what's possible with Dynamic and 
strict types 
Can_Serialize_DynamicType_and_Deserialize_into_StrictType()

Let us know if you have any questions?

Cheers,
Demis

Original comment by demis.be...@gmail.com on 18 Jun 2010 at 2:25

GoogleCodeExporter commented 9 years ago

Original comment by demis.be...@gmail.com on 21 Jun 2010 at 9:04