[Remoting FAQ]传递Remoting参数时遇到的两种常

系统 1656 0

[Remoting FAQ]

传递 Remoting 参数时遇到的两种常见错误

Version

Date

Creator

Description

1.0.0.1

2006-4-25

郑昀 @Ultrapower

草稿

 

继续阅读之前,我们假设您熟悉以下知识:

n          Remoting

[ 现象 1]

我们先来描述一个简单的错误。当你激活远端 Remoting Objects 时,却得到了这样的错误提示:

提示信息

Type 'Common.BTRequest' in Assembly

'Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

is not marked as serializable.

这个错误很容易理解。就是你的 Remoting Method 用到了一个输入参数,这个输入参数声明为“ Common.BTRequest ”类,它没有做序列化。

[ 解决 1 ]

很简单。

在你的 BTRequest 类前面加一行:

[ Serializable ]

public class BTRequest

即可。

[ 背景资料 1 ]

Piet Obermeyer 的《 .NET 中的对象序列化 》讲解得非常详细:

微软资料

由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable (请参阅 基本序列化 )。否则,当序列化程序试图序列化未标记的对象时将会出现异常。

 

对象仅在创建对象的应用程序域中有效。除非对象是从 MarshalByRefObject 派生得到或标记为 Serializable ,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。如果对象标记为 Serializable ,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称为按值封送。

 

[ 现象 2]

下面这个错误比较诡异,而且不是通常大家所解决掉的那种错误。当你激活远端 Remoting Objects 时,却得到了这样的错误提示:

提示信息

Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot be accessed.

最开始被误导到我的另一篇文章《 [Remoting]dotNet Framework 升级后 Remoting 信道使用的安全问题 》,这篇文章中谈到的“ typeFilterLevel="Full" ”解决问题方式在

http://www.ingorammer.com/remotingFAQ/changes2003.html

http://www.codeproject.com/csharp/PathRemotingArticle.asp

http://msdn2.microsoft.com/en-us/library/61w7kz4b.aspx

都论述过了。

但是,这次情况却不一样。

我并不是 framework1.0 编译的东西在 framework1.1 环境下使用,而且把 Remoting 配置文件中修改为:

< channels >

        < channel ref = " http " />

        < serverProviders >

          < provider ref = " wsdl " />

          < formatter ref = " binary " typeFilterLevel = " Full " />

        </ serverProviders >

</ channels >

最终也无济于事。

 

[ 解决 2 ]

注意到我 Remoting Method 用到了 BTRequest 的输入参数,它却继承了 MarshalByRefObject 接口。这就是问题之所在。

也就是说,如果我的一个输入参数类这么声明:

public class BTRequest : MarshalByRefObject

前面加不加“ [ Serializable ] ”的标记都无所谓,都可以让客户端得到异常:

提示信息

Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot

  be accessed.

 

Server stack trace:

   at System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(

Type type)

   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.ParseObject(Pars

eRecord pr)

   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Parse(ParseRecor

d pr)

   at System.Runtime.Serialization.Formatters.Soap.SoapHandler.StartChildren()

   at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml()

   at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()

只要不让这个输入参数类继承 MarshalByRefObject 接口就好了!

[ 背景资料 2 ]

Piet Obermeyer 的《 .NET 中的对象序列化 》讲到:

微软资料

如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。 也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable 远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector ,序列化体系结构将遵从下面的标准序列化规则(请参阅 序列化过程的步骤 )。

那既然我愿意传递对象引用,那么为什么在配置文件上配置 typeFilterLevel 不起作用呢?

服务器端配置:

< channels >

        < channel ref = " http " />

        < serverProviders >

          < provider ref = " wsdl " />

           < formatter ref = " binary " typeFilterLevel = " Full " />

        </ serverProviders >

</ channels >

客户端配置:

< channels >

        < channel ref = " http " />

          < clientProviders >

            < formatter ref = " binary " />

          </ clientProviders >

          < serverProviders >

             < formatter ref = " binary " typeFilterLevel = " Full " />

          </ serverProviders >

</ channels >

 

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=676972


[Remoting FAQ]传递Remoting参数时遇到的两种常见错误


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论