ОБНОВЛЕНИЕ: Вы можете запустить код в конце этого, чтобы воссоздать и увидеть ошибку, которую я имею, и, надеюсь, решить ее!
ОБНОВЛЕНИЕ2: Проблема не в удалении xmlns = ""... как вы можете удалить его из начальной строки XML.Проблема в том, что [XmlType (TypeName = "Systems")] каким-то образом вызывает его добавление ...
ОБНОВЛЕНИЕ3: Оказывается, проблема здесь, мне нужно установить TypeName на основе того, чтов существующем XmlTypeAttribute, если он уже существует в классе ....
xmlAttributes.XmlType = new XmlTypeAttribute
{
Namespace = ""
};
Я получаю следующий XML в виде строки из веб-службы
<Systems xmlns="">
<System id="1">
<sys_name>ALL</sys_name>
</System>
<System id="2">
<sys_name>asdfasdf</sys_name>
</System>
<System id="3">
<sys_name>fasdfasf</sys_name>
</System>
<System id="4">
<sys_name>asdfasdfasdf</sys_name>
</System>
</Systems>
Затем я выполняю это,преобразовать его в объект
result = XElement.Parse(xmlResult.OuterXml).Deserialize<AwayRequestSystems>();
Странно, хотя, в методе Deserialize, в то время как RemoveAllNamespaces работает и возвращает XML без пространства имен
Я получаю ошибку<Systems xmlns=''> was not expected.
в подвохе при выполнении return (T) serializer.Deserialize(reader);
!
Почему это происходит?Xmlns Ушел !!!
ИСПОЛНИМЫЙ КОД!(Просто поместите его в тестовый проект)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml.Serialization;
namespace DeserializationTest
{
[TestClass]
public class UnitTest1
{
public TestContext TestContext { get; set; }
[TestMethod]
public void RemoveXmlnsFromSystems()
{
var xml = XElement.Parse(@"<Systems xmlns="""">
<System id=""1"">
<sys_name>ALL</sys_name>
</System>
<System id=""2"">
<sys_name>ePO</sys_name>
</System>
<System id=""3"">
<sys_name>iEFT</sys_name>
</System>
<System id=""4"">
<sys_name>Away Requests</sys_name>
</System>
<System id=""5"">
<sys_name>RP3</sys_name>
</System>
</Systems>");
var systems = xml.Deserialize<AwayRequestSystems>();
Assert.IsInstanceOfType(systems, typeof(AwayRequestSystems));
var xmlnsFree = xml.RemoveAllNamespaces();
var str = xmlnsFree.ToString();
Debug.WriteLine(str);
Assert.AreNotEqual("Error", xmlnsFree.Name.ToString(), "Serialization Error");
Assert.IsFalse(str.Contains("xmlns"), "Xmlns still exists");
}
}
[XmlType(TypeName = "Systems")]
public class AwayRequestSystems : List<AwayRequestSystem> { }
[XmlType(TypeName = "System")]
public class AwayRequestSystem
{
[XmlAttribute("id")]
public int ID { get; set; }
[XmlElement("sys_name")]
public string Name { get; set; }
}
public static class XmlSerializerFactory
{
private static Dictionary<Type, XmlSerializer> _serializers = new Dictionary<Type, XmlSerializer>();
public static void ResetCache()
{
_serializers = new Dictionary<Type, XmlSerializer>();
}
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!_serializers.ContainsKey(typeOfT))
{
var xmlAttributes = new XmlAttributes();
var xmlAttributeOverrides = new XmlAttributeOverrides();
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)
{
if (xmlAttributeOverrides[type] == null)
xmlAttributeOverrides.Add(type, xmlAttributes);
}
var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
//var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides, types.ToArray(), new XmlRootAttribute(), string.Empty);
//var newSerializer = new XmlSerializer(typeOfT, string.Empty);
_serializers.Add(typeOfT, newSerializer);
}
return _serializers[typeOfT];
}
}
public static class XElementExtensions
{
public static XElement RemoveAllNamespaces(this XElement source)
{
if (source.HasAttributes)
source.Attributes().Where(a => a.Name.LocalName.Equals("xmlns")).Remove();
return source.HasElements
? new XElement(source.Name.LocalName,
source.Attributes()/*.Where(a => !a.Name.LocalName.Equals("xmlns"))*/,
source.Elements().Select(el => RemoveAllNamespaces(el))
)
: new XElement(source.Name.LocalName)
{
Value = source.Value
};
}
}
public static class SerializationExtensions
{
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("", "") }));
}
var result = (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
return result.RemoveAllNamespaces();
}
catch (Exception x)
{
return new XElement("Error", x.ToString());
}
}
public static T Deserialize<T>(this XElement source) where T : class
{
//try
//{
var serializer = XmlSerializerFactory.GetSerializerFor(typeof(T));
var cleanxml = source.RemoveAllNamespaces();
var reader = cleanxml.CreateReader();
return (T)serializer.Deserialize(reader);
//}
//catch (Exception x)
//{
// return null;
//}
}
}
}