2010-06-22 25 views
14

Sınıflarımın serileştirilmesini işleyen bir çift uzantı yöntemim var ve bu, zaman alıcı bir işlem olabileceğinden, her sınıfa bir kere oluşturuluyor ve bu yöntemle dağıtılıyor.xmlns OLUŞTURULMASI Serileştirme

public static XmlSerializer GetSerializerFor(Type typeOfT) 
{ 
    if (!serializers.ContainsKey(typeOfT)) 
    { 
     var xmlAttributes = new XmlAttributes(); 
     var xmlAttributeOverrides = new XmlAttributeOverrides(); 

     System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT)); 

     xmlAttributes.Xmlns = false; 
     xmlAttributeOverrides.Add(typeOfT, xmlAttributes); 

     var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides); 
     serializers.Add(typeOfT, newSerializer); 
    } 

    return serializers[typeOfT]; 
} 

Bu uzantı yöntemi .Serialize() otomatik olarak oluşturulmuş olan sınıfları seri hale

public static XElement Serialize(this object source) 
{ 
    try 
    { 
     var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType()); 
     var xdoc = new XDocument(); 
     using (var writer = xdoc.CreateWriter()) 
     { 
      serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") })); 
     } 

     return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing"); 
    } 
    catch (Exception x) 
    { 
     return new XElement("Error", x.ToString()); 
    } 
} 

yazık ki, bunlara uygulanan özelliği XmlTypeAttribute(Namespace="http://tempuri.org/") sahip adlandırılır.

Bu, otomatik oluşturulmamış muadillerinin başarısız olması için seri hale getirmeye neden olur.

Tamamen ad uygulamak görmezden ve değil seri hale gerekiyor, ama ne kodunun ilk bloğunda yazdım çıkarmak için görünmüyor, hala bu

<Note> 
    <ID xmlns="http://tempuri.org/">12</ID> 
    <Author xmlns="http://tempuri.org/"> 
    <ID>1234</ID> 
    <Type>Associate</Type> 
    <IsAvailable>false</IsAvailable> 
    </Author> 
    <Created xmlns="http://tempuri.org/">2010-06-22T09:38:01.5024351-05:00</Created> 
    <Text xmlns="http://tempuri.org/">This is an update</Text> 
</Note> 
gibi xml ile bitirmek

Aynı yerine, xmlns="http://tempuri.org/" özniteliği.

Lütfen yardım edin, teşekkürler, bu beni deli ediyor!

DÜZENLEME:

Sorunu biliyorum, sadece bunu düzeltmek için değil nasıl.

Sınıfım, yalnızca basit türlerle doludur.

Diğer sınıf türleriyle özellikleri içerir. Ayrıca XmlTypeAttribute(Namespace = "http://tempuri.org/") özniteliği ile otomatik olarak oluşturulur. Yani, gerçekleşen şey, serileştirme gerçekleştiğinde ve sınıfımın özelliklerini serileştirdiği zaman, onlar özel serileştirme sürecimden geçmeyecek ve böylece, özniteliğin uygulandığı ve geçersiz kılınamayacağıdır.

Şimdi sadece bu kasnağın nasıl atlanacağını bulmalıyım. Nasıl bir düşünce var?

DÜZENLEME 2:

aşağıdaki eserlerini xmlns OLMADAN seri hale getirmek için ... ama

public static XmlSerializer GetSerializerFor(Type typeOfT) 
{ 
    if (!serializers.ContainsKey(typeOfT)) 
    { 
     var xmlAttributes = new XmlAttributes(); 
     var xmlAttributeOverrides = new XmlAttributeOverrides(); 

     System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT)); 

     xmlAttributes.XmlType = new XmlTypeAttribute 
     { 
      Namespace = "" 
     }; 

     xmlAttributes.Xmlns = false; 

     var types = new List<Type> {typeOfT, typeOfT.BaseType}; 

     foreach (var property in typeOfT.GetProperties()) 
     { 
      types.Add(property.PropertyType); 
     } 

     types.RemoveAll(t => t.ToString().StartsWith("System.")); 

     foreach (var type in types) 
     { 
      xmlAttributeOverrides.Add(type, xmlAttributes); 
     } 

     var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides); 
     //var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides, extraTypes.ToArray(), new XmlRootAttribute(), string.Empty); 
     //var newSerializer = new XmlSerializer(typeOfT, string.Empty); 

     serializers.Add(typeOfT, newSerializer); 
    } 

    return serializers[typeOfT]; 
} 

Edit3 Bunlar birbirine Henüz emin değilse, seri kaldırma ucunda bir sorunum veya değilim : How to remove all namespaces from XML with C#?

public static XElement RemoveAllNamespaces(this XElement source) 
{ 
    return !source.HasElements 
       ? new XElement(source.Name.LocalName) 
        { 
         Value = source.Value 
        } 
       : new XElement(source.Name.LocalName, source.Elements().Select(el => RemoveAllNamespaces(el))); 
} 
+1

son çözüm seçildi gerekirdi 'aslında işe yaramadı önce hala sınıfına XmlTypeAttribute değeri kullanıyordum, buydu o – redtetrahedron

cevap

3

sorun gelen çözüm kullanarak sona erdi - tıpkı boş bir dize geçer XML seri hale varsayılan ad: - Peki ya da sizi XmlAttributeOverrides atlayıp Bahsettiğim yapıcı kullanabilir veya gerçekten XmlAttributeOverrides ve varsayılan ad tanımlamak gerekirse Maalesef

XmlSerializer newSerializer = 
    new XmlSerializer(typeOfT, ""); 

, kolay yapıcı aşırı yük var tüm olası parametreleri (XmlAttributeOverrides ve varsayılan XML ad alanları dahil - ve daha fazlası) tanımlayan birini kullanmanız gerekir.

+0

RemoveAllAttributes'. Ve sadece aşağıdakileri denedim ve çalışmadı 'var newSerializer = yeni XmlSerializer (typeOfT, xmlAttributeOverrides, yeni Type [] {}, yeni XmlRootAttribute()," "); – CaffGeek

+0

string.Empty >>>" " :) – annakata

+0

@annakata, ayrıca string.mpty ile değiştirmeyi denedim. – CaffGeek

44

Bir çalışma çözümü, kayıt için !

var ns = new XmlSerializerNamespaces(); 
ns.Add("", ""); 
var serializer = new XmlSerializer(yourType); 
serializer.Serialize(xmlTextWriter, someObject, ns); 
+0

Kesinlikle daha iyi bir çözüm. ÇALIŞIYOR bir cazibe gibi! – user460762

+10

Kayıt için, bu xsi ve xsd'yi kaldıracaktır, ancak yeni bir 'xmlns: önek = ' EKLEME ve 'XmlTypeAttribute' ifadenizde belirtilen ad aralıklarına sahipseniz, tüm etiketlerinize önek ekleyin. sınıflar. – redtetrahedron

+0

Bu gerçekten benim için mükemmel çalıştı, pek çok farklı şeyi denedikten sonra işini yan etkilerden yapmadı. Çok teşekkür ederim. – JoeFox

1
public static byte[] SerializeByteByType(object objectToSerialize, Type type) 
    { 
     XmlWriterSettings xmlSetting = new XmlWriterSettings() 
     { 
      NewLineOnAttributes = false, 
      OmitXmlDeclaration = true, 
      Indent = false, 
      NewLineHandling = NewLineHandling.None, 
      Encoding = Encoding.UTF8, 
      NamespaceHandling = NamespaceHandling.OmitDuplicates 
     }; 

     using (MemoryStream stm = new MemoryStream()) 
     { 
      using (XmlWriter writer = XmlWriter.Create(stm, xmlSetting)) 
      { 
       var xmlAttributes = new XmlAttributes(); 
       var xmlAttributeOverrides = new XmlAttributeOverrides(); 

       xmlAttributes.Xmlns = false; 
       xmlAttributes.XmlType = new XmlTypeAttribute() { Namespace = "" }; 
       xmlAttributeOverrides.Add(type, xmlAttributes); 

       XmlSerializer serializer = new XmlSerializer(type, xmlAttributeOverrides); 
       //Use the following to serialize without namespaces 
       XmlSerializerNamespaces xmlSrzNamespace = new XmlSerializerNamespaces(); 
       xmlSrzNamespace.Add("", ""); 

       serializer.Serialize(writer, objectToSerialize, xmlSrzNamespace); 
       stm.Flush(); 
       stm.Position = 0; 
      } 

      return stm.ToArray(); 
     } 
    }   
+0

Bunun yerine "xmlAttributeOverrides.Add (type, xmlAttributes);" olmalıdır: "var types = type.Assembly.GetTypes(). Burada (t => string.Equals (t.Namespace, currentType.Namespace, StringComparison.Ordinal)); var xmlAttributeOverrides = new XmlAttributeOverrides(); \t \t \t foreach (türlerde var t) \t xmlAttributeOverrides.Add (t, xmlAttributes); " – Mentor