我有一个使用 DataContractSerializer 序列化的数据类。该类使用没有显式 Namespace 声明的 [DataContract] 属性。因此,生成的 xml 文件中的命名空间是基于类的命名空间生成的。
这个类基本上是这样的:
namespace XYZ
{
[DataContract]
public class Data
{
[DataMember(Order = 1)]
public string Prop1 { get; set; }
[DataMember(Order = 2)]
public int Prop2 { get; set; }
}
}
...以及生成的 xml:
<?xml version="1.0" encoding="utf-8"?>
<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/XYZ">
<Prop1>StringValue</Prop1>
<Prop2>11</Prop2>
</Data>
现在我想通过将 [DataContract] 属性更改为 [DataContract(Namespace = "")] 来更改类的命名空间(实际上是删除它)。但是,一旦我这样做,任何以前使用原始命名空间序列化的文件都不再反序列化。我收到以下异常:
第 1 行位置 XXX 错误。期待来自命名空间“”的元素“数据”。遇到名称为“数据”、命名空间为“http://schemas.datacontract.org/2004/07/XYZ”的“元素”。
这很有道理。我更改了命名空间。我没意见。但是,似乎必须有一种方法可以告诉 DataContractSerializer 继续并反序列化该数据,即使 namespace 不匹配也是如此。
最佳答案
一种可能的方法是将序列化程序使用的阅读器包装在一个将旧 namespace 映射到新 namespace 的阅读器中,如下所示。很多代码,但大部分都是微不足道的。
public class StackOverflow_11092274
{
const string XML = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Data xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/XYZ"">
<Prop1>StringValue</Prop1>
<Prop2>11</Prop2>
</Data>";
[DataContract(Name = "Data", Namespace = "")]
public class Data
{
[DataMember(Order = 1)]
public string Prop1 { get; set; }
[DataMember(Order = 2)]
public int Prop2 { get; set; }
}
public class MyReader : XmlReader
{
XmlReader inner;
public MyReader(XmlReader inner)
{
this.inner = inner;
}
public override int AttributeCount
{
get { return inner.AttributeCount; }
}
public override string BaseURI
{
get { return inner.BaseURI; }
}
public override void Close()
{
inner.Close();
}
public override int Depth
{
get { return inner.Depth; }
}
public override bool EOF
{
get { return inner.EOF; }
}
public override string GetAttribute(int i)
{
return inner.GetAttribute(i);
}
public override string GetAttribute(string name, string namespaceURI)
{
return inner.GetAttribute(name, namespaceURI);
}
public override string GetAttribute(string name)
{
return inner.GetAttribute(name);
}
public override bool IsEmptyElement
{
get { return inner.IsEmptyElement; }
}
public override string LocalName
{
get { return inner.LocalName; }
}
public override string LookupNamespace(string prefix)
{
return inner.LookupNamespace(prefix);
}
public override bool MoveToAttribute(string name, string ns)
{
return inner.MoveToAttribute(name, ns);
}
public override bool MoveToAttribute(string name)
{
return inner.MoveToAttribute(name);
}
public override bool MoveToElement()
{
return inner.MoveToElement();
}
public override bool MoveToFirstAttribute()
{
return inner.MoveToFirstAttribute();
}
public override bool MoveToNextAttribute()
{
return inner.MoveToNextAttribute();
}
public override XmlNameTable NameTable
{
get { return inner.NameTable; }
}
public override string NamespaceURI
{
get
{
if (inner.NamespaceURI == "http://schemas.datacontract.org/2004/07/XYZ")
{
return "";
}
else
{
return inner.NamespaceURI;
}
}
}
public override XmlNodeType NodeType
{
get { return inner.NodeType; }
}
public override string Prefix
{
get { return inner.Prefix; }
}
public override bool Read()
{
return inner.Read();
}
public override bool ReadAttributeValue()
{
return inner.ReadAttributeValue();
}
public override ReadState ReadState
{
get { return inner.ReadState; }
}
public override void ResolveEntity()
{
inner.ResolveEntity();
}
public override string Value
{
get { return inner.Value; }
}
}
public static void Test()
{
DataContractSerializer dcs = new DataContractSerializer(typeof(Data));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
try
{
XmlReader r = XmlReader.Create(ms);
XmlReader my = new MyReader(r);
Data d = (Data)dcs.ReadObject(my);
Console.WriteLine("Data[Prop1={0},Prop2={1}]", d.Prop1, d.Prop2);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
关于c# - DataContractSerializer - 更改命名空间并反序列化绑定(bind)到旧命名空间的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11092274/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最