zoukankan      html  css  js  c++  java
  • .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

    我搭建了自己的博客 https://lindexi.gitee.io/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

    如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

  • 相关阅读:
    H
    GIS+=地理信息+行业+大数据——基于云环境流处理平台下的实时交通创新型app
    计算机图形学(一) 视频显示设备_3_随机扫描显示器
    实战c++中的vector系列--构造、operator=和assign差别
    【技术】正則表達式—匹配电话号码,网址链接,Email地址
    LeetCode(38)-Valid Sudoku
    传智播客《巴巴运动网视频教程(11-106)》avi格式以及兴许44集视频包括所有源码和资源
    mongodb常见管理命令
    Java web 项目读取src或者tomcat下class文件夹下的xml文件或者properties文件
    Axure 8.0.0.3312下载地址以及注册码
  • 原文地址:https://www.cnblogs.com/lindexi/p/12087143.html
Copyright © 2011-2022 走看看