2010-03-22 23 views
12

serileştirirken XmlSerializer istisna atar Dinamik olarak yüklenmiş (ve derlenmiş bir sınıf) serileştirmek için System.Xml.Serialization.XmlSerializer kullanmaya çalışıyorum. Söz konusu sınıfı ana meclise kurarsam, her şey beklendiği gibi çalışır. Ancak, sınıfı dinamik olarak yüklenmiş bir derlemeden derler ve yüklersek, XmlSerializer bir istisna atar.Dinamik olarak yüklenen tip

Neyi yanlış yapıyorum?

Ben sorunu yeniden oluşturmak için aşağıdaki .NET 3.5 C# uygulaması oluşturduk:

------------------------------------- 
Serializing StaticallyBuiltClass... 
------------------------------------- 
<?xml version="1.0" encoding="IBM437"?> 
<StaticallyBuiltClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Values /> 
</StaticallyBuiltClass> 
------------------------------------- 
Serializing DynamicallyBuiltClass... 
------------------------------------- 
Exception caught while serializing DynamicallyBuiltClass 
There was an error generating the XML document. 
Inner: The type initializer for 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterDynamicallyBuiltClass' threw an exception. 
Inner: Object reference not set to an instance of an object. 
Inner: null 

Stack trace: 
    at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) 
    at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces) 
    at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o) 
    at Program.Serialize(Type type, Object o) in c:\dev\SerTest\SerTest\Program.cs:line 100 

Edit: şu çıktıyı üretir

using System; 
using System.Collections.Generic; 
using System.Xml.Serialization; 
using System.Text; 
using System.Reflection; 
using System.CodeDom.Compiler; 
using Microsoft.CSharp; 

public class StaticallyBuiltClass 
{ 
    public class Item 
    { 
     public string Name { get; set; } 
     public int Value { get; set; } 
    } 
    private List<Item> values = new List<Item>(); 
    public List<Item> Values { get { return values; } set { values = value; } } 
} 

static class Program 
{ 
    static void Main() 
    { 
     RunStaticTest(); 
     RunDynamicTest(); 
    } 

    static void RunStaticTest() 
    { 
     Console.WriteLine("-------------------------------------"); 
     Console.WriteLine(" Serializing StaticallyBuiltClass..."); 
     Console.WriteLine("-------------------------------------"); 
     var stat = new StaticallyBuiltClass(); 

     Serialize(stat.GetType(), stat); 

     Console.WriteLine(); 
    } 

    static void RunDynamicTest() 
    { 
     Console.WriteLine("-------------------------------------"); 
     Console.WriteLine(" Serializing DynamicallyBuiltClass..."); 
     Console.WriteLine("-------------------------------------"); 
     CSharpCodeProvider csProvider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v3.5" } }); 

     CompilerParameters csParams = new System.CodeDom.Compiler.CompilerParameters(); 
     csParams.GenerateInMemory = true; 
     csParams.GenerateExecutable = false; 
     csParams.ReferencedAssemblies.Add("System.dll"); 
     csParams.CompilerOptions = "/target:library"; 

     StringBuilder classDef = new StringBuilder(); 
     classDef.AppendLine("using System;"); 
     classDef.AppendLine("using System.Collections.Generic;"); 
     classDef.AppendLine(""); 
     classDef.AppendLine("public class DynamicallyBuiltClass"); 
     classDef.AppendLine("{"); 
     classDef.AppendLine(" public class Item"); 
     classDef.AppendLine(" {"); 
     classDef.AppendLine("  public string Name { get; set; }"); 
     classDef.AppendLine("  public int Value { get; set; }"); 
     classDef.AppendLine(" }"); 
     classDef.AppendLine(" private List<Item> values = new List<Item>();"); 
     classDef.AppendLine(" public List<Item> Values { get { return values; } set { values = value; } }"); 
     classDef.AppendLine("}"); 

     CompilerResults res = csProvider.CompileAssemblyFromSource(csParams, new string[] { classDef.ToString() }); 

     foreach (var line in res.Output) 
     { 
      Console.WriteLine(line); 
     } 

     Assembly asm = res.CompiledAssembly; 
     if (asm != null) 
     { 
      Type t = asm.GetType("DynamicallyBuiltClass"); 
      object o = t.InvokeMember("", BindingFlags.CreateInstance, null, null, null); 
      Serialize(t, o); 
     } 

     Console.WriteLine(); 
    } 

    static void Serialize(Type type, object o) 
    { 
     var serializer = new XmlSerializer(type); 
     try 
     { 
      serializer.Serialize(Console.Out, o); 
     } 
     catch(Exception ex) 
     { 
      Console.WriteLine("Exception caught while serializing " + type.ToString()); 
      Exception e = ex; 
      while (e != null) 
      { 
       Console.WriteLine(e.Message); 
       e = e.InnerException; 
       Console.Write("Inner: "); 
      } 
      Console.WriteLine("null"); 
      Console.WriteLine(); 
      Console.WriteLine("Stack trace:"); 
      Console.WriteLine(ex.StackTrace); 
     } 
    } 
} 

kaldırıldı bazı yabancı başvurulan derlemeler

+2

+1 sorunu çoğaltır. –

cevap

7

'u false olarak değiştirin ve işe yarayacaktır. Bunun XML serileştirme işleminin bir sınırlaması olup olmadığını bilmiyorum, ancak derlemeyi diskte geçici bir konuma oluşturmak sizin için bir sorun değilse, sorununuzu çözecektir.

+0

Gerçekten, bu çalıştı. Cevabını kabul etmedim, çünkü bilmek istediğim gibi _why_. – anorm

+0

@Dr. Sbaitso, ben de nedenini merak ediyorum. Resmi bir açıklama elde etmek için connect.microsoft.com adresinden bir sorun gönderebilirsiniz. –

+3

Kullanıcı [cronos] (http://stackoverflow.com/users/711977/cronos) aşağıdakileri gönderdi, ancak silindi: "CompilerParameters.GenerateInMemory = false" çalışmasının nedeni, derlemenin diskte kalıcı olması gerektiğidir . Bunun nedeni, C# derleyicisinin, dinamik olarak oluşturulmuş XML serileştirme türlerini derlemek için kullandıklarıdır. Derleyici, ayrı bir (alt) işlemde çalışır ve bellekte bir birleştirmeye başvuruda bulunamaz. –

1

RE: Değişim CompilerParameters.GenerateInMemory false

Kendini nasıl yapılır? Kod sağlamak için

İlgili konular