使用.NET时,我遇到了一个非常奇怪的问题XmlSerializer.
采用以下示例类:
public class Order
{
public PaymentCollection Payments { get; set; }
//everything else is serializable (including other collections of non-abstract types)
}
public class PaymentCollection : Collection<Payment>
{
}
public abstract class Payment
{
//abstract methods
}
public class BankPayment : Payment
{
//method implementations
}
Run Code Online (Sandbox Code Playgroud)
AFAIK,有三种不同的方法可以解决InvalidOperationException由序列化程序不知道派生类型引起的问题Payment.
1.添加XmlInclude到Payment类定义:
这是不可能的,因为所有类都包含在我无法控制的外部引用中.
2.在创建XmlSerializer实例期间传递派生类型的类型
不行.
3.定义XmlAttributeOverrides目标属性以覆盖属性的默认序列化(如本SO帖子中所述)
也不起作用(XmlAttributeOverrides初始化如下).
Type bankPayment = typeof(BankPayment);
XmlAttributes attributes = …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种使用C#的方法,我可以将类序列化为XML并添加命名空间,但是定义该命名空间将使用的前缀.
最终我正在尝试生成以下XML:
<myNamespace:Node xmlns:myNamespace="...">
<childNode>something in here</childNode>
</myNamespace:Node>
Run Code Online (Sandbox Code Playgroud)
我知道有两个DataContractSerializer和XmlSerializer我可以添加一个命名空间,但他们似乎在内部生成一个前缀,与我不能够控制的东西.我能用这些序列化器控制它(我可以使用其中任何一个)吗?
如果我无法控制名称空间的生成,我需要编写自己的XML序列化程序,如果是这样,那么编写它的最佳选择是什么?
我使用XmlSerializer在一行代码上得到一个BindingFailure:
XmlSerializer s = new XmlSerializer(typeof(CustomXMLSerializeObject));
Run Code Online (Sandbox Code Playgroud)
具有显示名称CustomXMLSerializeObject.XmlSerializers'的程序集无法加载到ID为1的AppDomain的"LoadFrom"绑定上下文中.失败的原因是:System.IO.FileNotFoundException:无法加载文件或程序集XMLSerializeObject.XmlSerializers,Version = 1.4.0.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一.该系统找不到指定的文件.
错误很长,继续解释预绑定状态信息以及它试图找到文件的位置.
我试图去序列化的自定义对象相对简单 - 只是一堆私有整数和具有公共访问器的字符串.我有一个私有变量,它是另一个自定义的可序列化类,但它只有私有字符串,其中包含公共访问器.
尴尬的部分?这只在我反序列化时发生.当我序列化对象时,那行代码运行正常.它工作正常,对象被反序列化并完美填充.不要注意任何性能损失或加载时间过长.
这个警告究竟是什么(不是错误或异常,之后程序运行良好)?为什么会这样?如何在不简单禁用警告的情况下阻止它?
只是好奇为什么词典不受支持XmlSerializer?
你可以通过使用DataContractSerializer和写入对象来轻松地绕过它XmlTextWriter,但是如果XmlSerializer考虑到它真的是一个KeyValuePairs数组,那么字典的特征是什么使它难以处理.
实际上,你可以传递一个IDictionary<TKey, TItem>期望的方法IEnumerable<KeyValuePairs<TKey, ITem>>.
是否可以将未知XML反序列化为对象,如下所示?
var xml = @"<Students><Student><Name>Arul</Name><Mark>90</Mark></Student></Students>";
var serializer = new XmlSerializer(typeof(DynamicObject));
dynamic students = serializer.Deserialize(new XmlTextReader(new StringReader(xml)));
Run Code Online (Sandbox Code Playgroud) 我有一个调用记录器,用于记录所有方法调用以及与使用XmlSerializer的方法相关的参数.它适用于大多数调用,但它会为具有IEnumerable类型参数的所有方法抛出异常.
例如,void MethodWithPlace( Place value )将序列化,但void MethodWithPlace( IEnumerable<Place> value )不会.
例外是
System.NotSupportedException:无法序列化接口System.Collections.Generic.IEnumerable`1 [[Place,Test,Version = 0.0.0.0,Culture = neutral]].
我应该怎么做才能使用这些方法IEnumerable作为其参数之一?
我正在尝试将对象写入Xml字符串并获取该字符串并将其保存到数据库中.但首先我需要得到字符串......
private static readonly Encoding LocalEncoding = Encoding.UTF8;
public static string SaveToString<T> (T settings)
{
Stream stream = null;
TextWriter writer = null;
string settingsString = null;
try
{
stream = new MemoryStream();
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(stream, LocalEncoding);
serializer.Serialize(writer, settings);
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
settingsString = LocalEncoding.GetString(buffer);
}
catch(Exception ex)
{
// If the action cancels we don't want to throw, just return null.
}
finally
{
if (stream != null) …Run Code Online (Sandbox Code Playgroud) 我上课了 PersonList
[XmlRoot("Persons")]
PersonList : List<Human>
Run Code Online (Sandbox Code Playgroud)
当我将其序列化为XML时,默认情况下会生成如下内容:
<Persons>
<Human>...</Human>
<Human>...</Human>
</Persons>
Run Code Online (Sandbox Code Playgroud)
我的问题是需要以改变元素做什么Human,以Person输出?所以输出将是:
<Persons>
<Person>...</Person>
<Person>...</Person>
</Persons>
Run Code Online (Sandbox Code Playgroud)
并且,如何将上述XML反序列化为PersonList类对象?
Per Nick的建议,这是我的测试代码:
[XmlRoot("Persons")]
public class Persons : List<Human>
{
}
[XmlRoot("Person")]
public class Human
{
public Human()
{
}
public Human(string name)
{
Name = name;
}
[XmlElement("Name")]
public string Name { get; set; }
}
void TestXmlSerialize()
{
Persons personList = new Persons();
personList.Add(new Human("John"));
personList.Add(new Human("Peter"));
try
{
using (StringWriter writer = new StringWriter())
{ …Run Code Online (Sandbox Code Playgroud) 我有一个具有许多Nullable <T>属性的类,我想将其作为属性序列化为XML.这显然是禁忌,因为它们被认为是"复杂类型".所以,我实现了*Specified模式,我在其中创建了一个add*Value和*Specified属性,如下所示:
[XmlIgnore]
public int? Age
{
get { return this.age; }
set { this.age = value; }
}
[XmlAttribute("Age")]
public int AgeValue
{
get { return this.age.Value; }
set { this.age = value; }
}
[XmlIgnore]
public bool AgeValueSpecified
{
get { return this.age.HasValue; }
}
哪个工作正常 - 如果'Age'属性有值,则将其序列化为属性.如果它没有值,则不会序列化.
问题在于,正如我所提到的,我的班级中有很多Nullable-s,这种模式只是让事情变得混乱和无法管理.
我希望有一种方法可以使Nullable更友好的XmlSerializer.或者,如果失败了,那就是创建Nullable替换的方法.
有没有人有任何想法我怎么能这样做?
谢谢.
我采取了IIS的内存转储,并在分析时发现了"无法加载文件或程序集MyAssemblyName.XmlSerializers"的错误.在我的代码中,我使用XmlSerializer类将xml文件中的xml内容序列化和反序列化为自定义对象.当项目构建时,它只创建MyAssembly.dll和MyAssembly.pdb文件,但不创建MyAssembly.XmlSerializers.dll.有谁知道如何启用我的项目来创建xmlserializers.dll文件?
注意:在项目构建选项卡中,"生成序列化程序集"设置为"自动".
谢谢.
c# ×10
xmlserializer ×10
.net ×3
xml ×3
attributes ×1
dictionary ×1
dll ×1
dynamic ×1
memorystream ×1
nullable ×1