更新:これの最後にあるコードを実行して、私が抱えているエラーを再作成して確認し、うまくいけばそれを解決することができます!
UPDATE2:問題はxmlns = ""の削除ではありません...最初のxml文字列から削除できるため、問題は、[XmlType(TypeName = "Systems")]が何らかの理由で追加されることにあります。
UPDATE3:問題はここにあることがわかりました。既存のXmlTypeAttributeにあるものに基づいて、TypeNameを設定する必要があります(クラスにすでに存在する場合)。
xmlAttributes.XmlType = new XmlTypeAttribute
{
Namespace = ""
};
次のXMLをWebサービスから文字列として取得します
<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;
//}
}
}
}