在进行我认为我要分享的C#XML序列化时,我遇到了一些问题:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void …Run Code Online (Sandbox Code Playgroud) 使用.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) 我正在使用字典来保存一些参数,我发现不可能序列化任何实现IDictionary的东西(无法序列化IDictionary).
作为一种解决方法,我想将字典转换为字符串以进行序列化,然后在需要时转换回字典.
因为我正在努力改进我的LINQ,这似乎是一个很好的地方,但我不知道如何开始.
这是我在没有LINQ的情况下实现的方法:
/// <summary>
/// Get / Set the extended properties of the FTPS processor
/// </summary>
/// <remarks>Can't serialize the Dictionary object so convert to a string (http://msdn.microsoft.com/en-us/library/ms950721.aspx)</remarks>
public Dictionary<string, string> FtpsExtendedProperties
{
get
{
Dictionary<string, string> dict = new Dictionary<string, string>();
// Get the Key value pairs from the string
string[] kvpArray = m_FtpsExtendedProperties.Split('|');
foreach (string kvp in kvpArray)
{
// Seperate the key and value to build the dictionary
string[] pair = kvp.Split(','); …Run Code Online (Sandbox Code Playgroud) 我的C#有点生疏,我以前从未用它编写XML.如果我尝试编写除元素之外的任何内容,我就无法将XML写入文件.这是我的测试代码:
var guiPath = txtGuiPath.Text;
MessageBox.Show("Dumping File: " + guiPath);
try
{
var writer = new XmlTextWriter("client_settings.xml", null);
writer.WriteStartDocument();
writer.WriteComment("Config generated on 01/01/01");
writer.WriteStartElement("Config");
writer.WriteStartElement("GuiPath");
writer.WriteString(guiPath);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
MessageBox.Show("Finished Dumping");
Run Code Online (Sandbox Code Playgroud)
如果guiPath为空,我会得到以下XML:
<?xml version="1.0"?>
<!--Config generated on 01/01/01-->
<Config>
<GuiPath />
</Config>
Run Code Online (Sandbox Code Playgroud)
但如果guiPath中有任何文本,那么没有任何内容写入文件.我甚至可以删除client_settings.xml文件并反复激活此代码,除非guiPath为空,否则永远不会生成XML文件.将类似"This is a test"的内容传递给WriteString()也可以.
更新
因为我试图写出一个系统路径,这似乎是个问题.如果我删除所有反斜杠,它将正确地写入结果字符串,但如果我将它传递给WriteString或WriteCData,则XML根本不会写入.
更新2
事实证明我遇到这么多问题的原因是因为XML文件是在guiPath设置的任何路径中生成的,而不是在应用程序运行的目录中生成的(所以对我来说看起来它没有生成在所有).因此,如果我将guiPath设置为'C:\ Program Files\externalApp\appName.exe',它将XML文件保存为'C:\ ProgramFiles\externalApp\client_settings.xml',而不是在应用的启动文件夹中.为什么,我不知道.我开始传递Application.StartupPath并将文件名附加到它,现在它工作得很好.
感谢您的帮助!
我有这个课程:
[DataContract]
class ClassA
{
[DataMember]
public Object Value; // and this can be of ClassB or some primitive type.
...
}
[DataContract]
class ClassB : IEnumerable<KeyValuePair<String, ClassA>>
{
[DataMember]
private Dictionary<String, ClassA> dictionary;
...
}
Run Code Online (Sandbox Code Playgroud)
但在序列化时发生此异常:
键入"MyNamespace.ClassA",数据合同名称为"ClassA:http://schemas.datacontract.org/2004/07/MyNamespace ".将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中.
我觉得我应该使用KnownType属性,但我无法弄清楚如何,因为我不拥有IEnumerable<T>.
有人可以帮忙吗?谢谢.
我们有一个Hashtable(特别是C#Dictionary类),它可以保存数千/数百万(Key,Value)对,用于近O(1)搜索命中/未命中.
我们希望能够将此数据结构刷新到磁盘(序列化)并稍后再次加载(反序列化),以便保留Dictionary的内部哈希表.
我们现在做的是:
List<KVEntity>.(KVEntity可序列化.我们使用Avro进行序列化 - 如果需要可以删除Avro)KVEntity从array =>字典中读取每一个.这将重新生成字典/散列表内部状态.myKVDict.Values.SelectMany(x => x)新的List<KVEntity>)List<KVEntity>)序列化为磁盘以保存原始数据请注意,在我们的保存/恢复期间,我们会丢失内部tashtable /字典状态,并且每次都必须重建它.
我们想直接序列化到/来自Dictionary(包括它的内部"实时"状态),而不是仅仅为磁盘i/o使用中间数组.我们怎么做?
一些伪代码:
// The actual "node" that has information. Both myKey and myValue have actual data work storing
public class KVEntity
{
public string myKey {get;set;}
public DataClass myValue {get;set;}
}
// unit of disk IO/serialization
public List<KVEntity> myKVList {get;set;}
// unit of run time processing. The string key is …Run Code Online (Sandbox Code Playgroud)