.net remoting 抛出异常

本文告诉大家如何在使用 .net remoting 的时候,抛出异常。

所有在远程软件运行的类,如果需要传输到本地,都需要继承 MarshalByRefObject 或其他可以序列化的类。

在 .net Framework 4.0 就默认指定只反序列化基础类型,如果需要反序列化其他的类型,那么就需要设置TypeFilterLevel,设置的方法是在使用下面代码

      public static IChannel CreatChannel(string port = "")
        {
            if (string.IsNullOrEmpty(port))
            {
                port = Guid.NewGuid().ToString("N");
            }

            var serverProvider = new SoapServerFormatterSinkProvider();
            var clientProvider = new SoapClientFormatterSinkProvider();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
            IDictionary props = new Hashtable();
            props["portName"] = port.ToString();

            return new IpcChannel(props, clientProvider, serverProvider);
        }

但是设置了TypeFilterLevel不是对所有的类型都可以进行转换,如果不小心直接在调用方法抛出异常,那么会因为无法反序列,让本地拿不到

 // 远程

 public void Foo()
 {
 	throw new CsdnNotFoundException();
 }

 public class CsdnNotFoundException : Exception
 {
 	public CsdnNotFoundException(string str) :
 	       base(str)
 	{

 	}       
 }

这时本地会提示System.Runtime.Serialization.SerializationException程序无法序列。

如果需要在 .net remoting 使用异常,那么需要自己创建一个异常,继承 RemotingException

反序列

因为默认的 RemotingException 没有反序列,所以需要添加 Serializable 特性

 [Serializable]
 public class CsdnNotFoundException : RemotingException
 {
 	public CsdnNotFoundException(string str) :
 	       base(str)
 	{

 	}       
 }

微软建议继承ISerializable,标记特性

 [Serializable]
 public class CsdnNotFoundException : RemotingException, ISerializable
 {
 	public CsdnNotFoundException(string str) :
 	       base(str)
 	{

 	}       
 }

如果直接运行,会发现报告System.Runtime.Serialization.SerializationException:“未找到反序列化“lindexi.Csdn.CsdnNotFoundException”类型对象的构造函数

解决方法是创建一个构造函数,写入这个函数就不需要再写其他的代码。

        protected CsdnNotFoundException([NotNull] SerializationInfo info, StreamingContext context) : base(info,
            context)
        {
        }

如果有一些特殊的属性需要自己设置,建议创建一个默认构造函数,和两个方法,因为使用上面的方法不会序列化自己定义的属性。

 [Serializable]
 public class CsdnNotFoundException : RemotingException, ISerializable
 {
    public CsdnNotFoundException()
    {
    	//默认构造,可以在反射创建
    }

 	public CsdnNotFoundException(string str) :
 	       base(str)
 	{

 	}      

 	      protected CsdnNotFoundException([NotNull] SerializationInfo info, StreamingContext context) 
 	      //: base(info, context) 不使用基类的原因是基类会报告 找不到 ClassName 和其他很多的坑
        {
            //反序列化创建

            Message = (string) info.GetValue(MessageSerialization, typeof(string));
        } 

        // 重写消息,用于在构造设置值
        public override string Message { get; }

        // 用于在构造拿到消息的值
        private const string MessageSerialization = "Message";

        // 重写这个方法,在序列化调用
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(MessageSerialization, Message);
        }
 }

在 GetObjectData 拿到必要的属性,这个需要自己把需要的属性写入。然后在构造函数重写[NotNull] SerializationInfo info, StreamingContext context方法的,可以拿到值

因为上面的代码用到 Message ,需要重写这个属性,因为默认是只读,不能在构造函数设置。

是不是觉得很复杂,实际上简单的方法是通过 json 在GetObjectData把类转换为json,在构造转换为类。

ISerializable

那么为什么在使用 Serializable 特性还需要继承 ISerializable ,因为继承 ISerializable 就可以在一个构造函数xx([NotNull] SerializationInfo info, StreamingContext context)进行处理和处理如何序列化。处理如何序列化可以提高性能,因为自己知道哪些需要序列化,哪些不需要。

关于 ISerializable 请看 c# - What is the point of the ISerializable interface? - Stack Overflow

How to: Create an Exception Type That Can be Thrown by Remote Objects


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

采用一个自创的"验证框架"实现对数据实体的验证[扩展篇]

关于“验证框架”,先后推出了《编程篇》、《设计篇》和《改进篇》,本不打算再写《XXX篇》的。但是今天收到两个园友的短消息,想了解一下如何定义自己的验证规则。这实...

2207
来自专栏醒者呆

掌握一门语言Go

摘要:Go语言的优势不必多说,通过本篇文章,让我们花时间来掌握一门外语,Let's Go! 关键字:Go语言,闭包,基本语法,函数与方法,指针,slic...

4249
来自专栏技术博客

编写高质量代码改善C#程序的157个建议[泛型集合、选择集合、集合的安全]

    软件开发过程中,不可避免会用到集合,C#中的集合表现为数组和若干集合类。不管是数组还是集合类,它们都有各自的优缺点。如何使用好集合是我们在开发过程中必须...

1333
来自专栏大内老A

通过扩展改善ASP.NET MVC的验证机制[实现篇]

在《使用篇》中我们谈到扩展的验证编程方式,并且演示了本解决方案的三大特性:消息提供机制的分离、多语言的支持和多验证规则的支持,我们现在来看看这样的验证解决方案最...

20710
来自专栏跟着阿笨一起玩NET

开源实体映射框架EmitMapper介绍

EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/。

1362
来自专栏影子

jQuery中的常用内容总结(三)

转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7571998.html

1011
来自专栏影子

jQuery中的常用内容总结(三)

4559
来自专栏小樱的经验随笔

Codeforces 714A Meeting of Old Friends

A. Meeting of Old Friends time limit per test:1 second memory limit per test:256...

37710
来自专栏熊二哥

让我们一起写出更有效的CSharp代码吧,少年们!

周末空闲,选读了一下一本很不错的C#语言使用的书,特此记载下便于对项目代码进行重构和优化时查看。 Standing On Shoulders of Giant...

1855
来自专栏游戏杂谈

JavaScript立即调用的函数表达式

主要参考知乎上这个问题:javascript 匿名函数有哪几种执行方式 长天之云的回答。

1272

扫码关注云+社区

领取腾讯云代金券