当前位置: 首页 > news >正文

成功网站管理系统wordpress主题vue

成功网站管理系统,wordpress主题vue,青岛营销型网站,马蹄室内设计论坛在前一篇文章中我曾经说过#xff0c;现在正在做一个小小的框架以实现采用统一的API实现对上下文#xff08;Context#xff09;信息的统一管理。这个框架同时支持Web和GUI应用#xff0c;并支持跨线程传递和跨域传递#xff08;这里指在WCF服务调用中实现客户端到服务端隐… 在前一篇文章中我曾经说过现在正在做一个小小的框架以实现采用统一的API实现对上下文Context信息的统一管理。这个框架同时支持Web和GUI应用并支持跨线程传递和跨域传递这里指在WCF服务调用中实现客户端到服务端隐式传递以及对上下文项目ContextItem的读写控制。关键就在于后面两个特性的支持上面出现一个小小的关于序列化的问题。解决方案只需要改动短短的一行代码结果却让我折腾了老半天。 一、问题重现 为了重现我实际遇到的问题我特意将问题简化为此我写了一个简单的例子你可以从这里下载。在下面的代码片断中我创建了一个名称为ContextItem的类型代表一个需要维护的上下文项。由于需要在WCF服务调用实现自动传递我将起定义成DataContract。ContextItem包含KeyValue和ReadOnly三个属性不用说ReadOnly表示该ContextItem可以被修改。注意Value属性Set方法的定义——如果ReadOnly则抛出异常。 1: [DataContract(Namespace http://www.artech.com)] 2: public class ContextItem 3: { 4: private object value null; 5: [DataMember] 6: public string Key { get; private set; } 7: [DataMember] 8: public object Value 9: { 10: get 11: { 12: return this.value; 13: } 14: set 15: { 16: if (this.ReadOnly) 17: { 18: throw new InvalidOperationException(Cannot change the value of readonly context item.); 19: } 20: this.value value; 21: } 22: } 23: [DataMember] 24: public bool ReadOnly { get; set; } 25: public ContextItem(string key, object value) 26: { 27: if (string.IsNullOrEmpty(key)) 28: { 29: throw new ArgumentNullException(key); 30: } 31: this.Key key; 32: this.Value value; 33: } 34: } 为了演示序列化和反序列化我写了如下两个静态的帮助方法。Serialize和Deserialize分别用于序列化和反序列化前者将对象序列成成XML并保存到指定的文件中后者则从文件读取XML并反序列化成相应的对象。 1: public static T DeserializeT(string fileName) 2: { 3: DataContractSerializer serializer new DataContractSerializer(typeof(T)); 4: using (XmlReader reader new XmlTextReader(fileName)) 5: { 6: return (T)serializer.ReadObject(reader); 7: } 8: } 9:  10: public static void SerializeT(T instance, string fileName) 11: { 12: DataContractSerializer serializer new DataContractSerializer(typeof(T)); 13: using (XmlWriter writer new XmlTextWriter(fileName, Encoding.UTF8)) 14: { 15: serializer.WriteObject(writer, instance); 16: } 17: Process.Start(fileName); 18: } 我们的程序很简单。从如下的代码片断中我们先创建一个ContextItem对象然后将ReadOnly属性设置成true。然后调用Serialize方法将对象序列化成XML并保存在一个名称为context.xml的文件中。然后调用Deserialize方法读取该文件进行反序列化。 1: static void Main(string[] args) 2: { 3: var contextItem1 new ContextItem(__userId, Foo); 4: contextItem1.ReadOnly true; 5: SerializeContextItem(contextItem1, context.xml); 6: var contextItem2 DeserializeContextItem(context.xml); 7: } 序列化操作能够正常执行但当程序执行到Deserialize的时候抛出如下一个InvalidOperationException异常。 二、问题分析 从上面给出的截图我们不难看出异常是在给ContextItem对象的Value属性赋值的时候抛出的。如果对DataContractSerializer序列化器的序列化/反序列化规则的有所了解的话应该知道对于数据契约DataContract基于属性Property的数据成员DataMember序列器在反序列化的时候是通过调用Set方法对其进行初始化的。在本例中由于ReadOnly是True在对Value进行反序列化的时候必然会调用Set方法。但是只读的ContextItem却不能对其赋值所以异常抛出。 那么如何来解决这个问题呢我最初的想法是这样在序列化的时候将ReadOnly属性设置成False然后添加另一个属性专门用于保存真实的值。在进行反序列的时候由于ReadOnly为false所以不会出现异常。当反序列化完成之后在将ReadOnly的初始值赋上。虽然上述的方案能够解决问题但是为此对ContextItem添加一个只在序列化和反序列化的过程中在有用的属性总觉得很丑陋。 我们不妨换一种思路异常产生于对Value属性凡序列化时发现ReadOnly非True的情况。那么怎样采用避免这种情况的发生呢如果Value属性先于ReadOnly属性被序列化那么ReadOnly的初始值就是False这个问题不就解决了吗这就是我们的第一个解决方案。 三、解决方案一通过控制属性反序列化顺序 那么如果控制那么属性先被反序列化那么后被序列化呢这就是要了解DataContractSerializer序列化器的序列化和发序列化规则了。在默认的情况下DataContractSerializer是按照数据成员的名称的顺序进行序列化的。这可以从生成出来的XML的结构看出来。而XML元素的先后顺序决定了反序列化的顺序。 1: ContextItem xmlns:ihttp://www.w3.org/2001/XMLSchema-instance xmlnshttp://www.artech.com 2: Key__userId/Key 3: ReadOnlytrue/ReadOnly 4: Value xmlns:d2p1http://www.w3.org/2001/XMLSchema i:typed2p1:stringFoo/Value 5: /ContextItem 在上面的例子中ContextItem的ReadOnly排在Value的前面会先被序列化。那么是不是我们要更新Value或者ReadOnly的数据成员DataMember不是属性名称呢这肯定不是我们想要的解决方案。在SOA的世界中DataMember是契约的一部分往往是不容许更改的。 如果在不更改数据成员名称的前提下让属性Value先于ReadOnly被序列化需要用到DataContractSerializer另一条反序列化规则我们可以通过DataMemberAttribute特性的Order属性控制序列化后的属性在XML元素列表中的位置。 为此我们有了答案我们只需要将ContextItem稍加改动就可以了。在如下的代码中在为Value和ReadOnly两个属性应用DataMemberAttribute的时候将Order属性分别设置成1和2这样就能使ContextItem对象在被序列化的时候Value和ReadOnly属性对应的XML元素将永远会有前后之分。这里还需要注意的是在Value属性的Set方法中判断是否只读采用的不是ReadOnly属性而是对应的readonly字段。这一点非常重要如果调用ReadOnly属性将会迫使该属性被反序列化。 1: [DataContract(Namespace http://www.artech.com)] 2: public class ContextItem 3: { 4: private object value null; 5: private bool readOnly; 6: [DataMember] 7: public string Key { get; private set; } 8:  9: [DataMember(Order 1)] 10: public object Value 11: { 12: get 13: { 14: return this.value; 15: } 16: set 17: { 18: if (this.readOnly) 19: { 20: throw new InvalidOperationException(Cannot change the value of readonly context item.); 21: } 22: this.value value; 23: } 24: } 25: [DataMember(Order 2)] 26: public bool ReadOnly 27: { 28: get 29: { 30: return readOnly; 31: } 32: set 33: { 34: readOnly value; 35: } 36: } 37: //Others 38: } 有兴趣的读者可以亲自试试看如果我们进行了如上的更改前面的程序就能正常运行了。到这里有的读者可以要问了你不是说仅仅有一行代码的变化吗我看上面改动的不止一行嘛。没有错我们完全可以作更少的更改来解决问题。 四、解决方案二将数据成员定义在字段上而不是属性上 我们再换一种思维之所以出现异常是在反序列化的时候调用Value属性的Set方法所致。如果在反序列化的时候不调用这个方法不就得了吗那么如何才能避免对Value属性的Set方法的调用呢?方法很简单那就是将数据成员定义在字段上而不是属性上。基于属性的数据成员在反序列化的时候不得不通过调用Set方法对数据项进行初始化而基于字段的数据成员在反序列化的时候只需要直接对其复制就可以了。 基于这样的思路我们对原来的ContextItem进行简单的改动——将DataMemberAttribute特性从Value属性移到value字段上。需要注意的为了符合于原来的Schema需要将DataMemberAttribute特性的Name属性设置成“Value”。 1: [DataContract(Namespace http://www.artech.com)] 2: public class ContextItem 3: { 4: [DataMember] 5: public string Key { get; private set; } 6:  7: [DataMember(Name Value)] 8: private object value null; 9: public object Value 10: { 11: get 12: { 13: return this.value; 14: } 15: set 16: { 17: if (this.ReadOnly) 18: { 19: throw new InvalidOperationException(Cannot change the value of readonly context item.); 20: } 21: this.value value; 22: } 23: } 24: [DataMember] 25: public bool ReadOnly { get; set; } 26: //Others 27: } 28: } 总结 虽然这仅仅是一个很小的问题解决的方案看起来也是如此的简单。但是这并不意味着这是一个可以被忽视的问题背后隐藏对DataMemberAttribute序列化的序列化规则的理解。 作者蒋金楠 微信公众账号大内老A 微博www.weibo.com/artech 如果你想及时得到个人撰写文章以及著作的消息推送或者想看看个人推荐的技术资料可以扫描左边二维码或者长按识别二维码关注个人公众号原来公众帐号蒋金楠的自媒体将会停用。 本文版权归作者和博客园共有欢迎转载但未经作者同意必须保留此段声明且在文章页面明显位置给出原文连接否则保留追究法律责任的权利。 原文链接
http://www.pierceye.com/news/922503/

相关文章:

  • 汽车网站建设策划方案24小时永久有效在线观看
  • 潍坊做网页的公司潍坊网站排名优化
  • 中建铁路建设有限公司网站微信群营销工具
  • 单位网站建设意见建议百度关键词检测工具
  • 重庆网站建设方案书免费网上咨询医生是哪个网
  • 临沂市开发区可以做分销的网站网络域名综合查询
  • 建设银行企业网银网站过期银州手机网站建设
  • 导航网站 win8风格企业服务官网
  • 樟树有哪几个网站做爆药库在线制作图片视频生成器
  • 汕头网站定制青年汇网站开发公司
  • 厦门专业网站设计公司防控措施持续优化
  • wordpress子网站杭州化工网站建设
  • 怎样做网站 - 百度兰州家政公司
  • 网站上的字体大小福建省建设注册执业管理中心网站
  • 七台河做网站手机wap浏览器
  • 最新手机网站推荐哪个推广平台效果好
  • 百度官方网站关键词营销seo
  • 网站建设开发流程做网站的毕业设计
  • 网站模块wordpress图片多选
  • 济源市住房和城乡建设局网站公示聊城市城乡建设部网站查询
  • 阿里网 网站备案流程长春公司网站建设
  • 临沂做商城网站设计网站设计 线框图 怎么画
  • 台江网站建设建设网站的意义
  • 西安做网站公司报价沧州
  • 有了网站 怎么做排名优化企业黄页官网
  • 临夏州建设银行网站深圳官网
  • 手机互动网站建设昆山网络公司哪家比较好
  • 桐城网站建设推荐做网站的公司
  • 中国 网站服务器 租金手机免费网址
  • php网站如何做多语言网站域名有效期