.net remoting 文章

.net remoting 框架简介http://www.g2host.cn/www/Article/Program/Net/200701/10786.html

How to monitor if Remote Objects have been deployed successfully
 
在调试 .Net Remoting 程序时,经常会出现一些莫名其妙的问题, IDE 提示的异常信息有时也不一定正确。很多时候都是自己粗心,配置 configuration 文件上出了问题,包括 Client Server 端的配置文件。另外,我感觉 .Net Remoting 中还有许多陷阱( trap ),如前面 posting SoapSuds工具的一些不足之处 》所提及的,不只这些,还有许多。如果陷入这些 trap ,而且又不知道的话,就麻烦了,调试半天也不知道问题在哪里。有空的时间,我准备花些时间整理一下 .Net Remoting 中的 trap
 
言归正传,这里看看如何检测 Remote Objects 是否部署成功。 Remote Objects 部署成功是第一步,否则 Client 端调用 Remote Objects 肯定会抛异常信息了。因此,如出现异常信息,首先检测 Remote Objects 是否成功部署在 Server 端。
 
下面根据激活类型分两种情况: SAO (服务端激活对象)和 CAO (客户端激活对象)。
 
1 SAO 对象
SAO 对象而言,比较简单。根据 Server 端配置文件中 <wellknown> 节或 RemotingConfiguration.RegisterWellKnownServiceType() 方法中指定的 URL ,通过 IE 浏览器检测,如下所示:
http://<hostname>:<port>/<ApplicationName>/<URL>?wsdl
如果 IE 返回 WSDL 信息,则显示 Remote Objects 部署成功。其实只要看到 IE 有正确返回信息就行了,如果你了解 WSDL Web Services Description Language ),可以进一步看看是否调用的 Remote Method 是否有出现。
 
需要注意的地方:
1 )如果 Remote Objects 部署在 IIS 中, <ApplicationName> 则为虚拟目录名称( Virtual Directory Name ),并且不要在 Web.Config 配置文件中设定 Application Name 。同时 Remote Objects URL 需要以 soap rem 为后缀名。
2 )如果 Remote Objects 不是部署在 IIS 中,则必须在 configuration 配置文件或者在代码中 RemotingConfiguration.Application=”<ApplicationName>” 来指定 ApplicationName
 
2 CAO 对象
对于 CAO 对象,和 SAO 对象不一样。需要如下的 URL 来测试:
http://<hostname>:<port>/<ApplicationName>/RemoteActivationService.rem?wsdl
 
后面是 RemoteActivationService.rem ,这点和 SAO 对象不一样。
 
需要注意的地方:
1 )在调用 CAO 对象时,需要在 Client 端的配置文件中 <client> 节指定 Remote Objects url 属性。如何使用 .Net Remoting 的配置文件,可以参考《 .Net Remoting配置文件的用法》。

 注:访问IIS元数据库失败

装了VS2005再装IIS,结果出了些小问题
访问IIS元数据库失败
思考可能是次序出了问题,解决
1、打开CMD,进入 C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727
2、输入 aspnet_regiis.exe -i
稍等片刻,注册成功就解决问题了。  

接着还会出现“未能创建 Mutex”的问题 
解决方法:
1、先关闭你的VS2005。
2、打开 C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files  找到你刚才调试的程序的名字的目录删除它。
3、关闭IIS服务器,重开一次。
4、用IE浏览一下你的程序,问题解决。

都是次序惹的祸,最好是先IIS 再VS2K5 
    最近项目开发中的传输数据是围绕Remoting而召开的,所以想把所有的数据实体都定义统一的格式,于是就写了一个基于DataTable的基类BaseModal,其他数据实体全部继承于它。此BaseModal基类还包括了一些其他的自有的属性,例如pageSize每页记录数、currentPage当前页码等等,代码如下:

  1
  2文件描述
 13
 14修改记录
 21
 22using System;
 23using System.Data;
 24using System.Text;
 25using System.Runtime.Serialization;
 26
 27namespace Colorful.Model
 28{
 29    /// <summary>
 30    /// 数据基本表
 31    /// </summary>

 32    [Serializable]
 33    public class BaseModel : DataTable
 34    {
 35        protected   int     index;          //记录当前行
 36        protected   int     pageSize;       //每页记录数
 37        protected   int     currentPage;    //当前页码
 38        protected   int     pages;          //总页数
 39        protected   long    totalRecord;    //总记录数
 40        protected string description;    //其他描述,及其辅助功能
 41
 42        public int PageSize
 54
 55        public int CurrentPage
 67
 68        public int Pages
 80
 81        public long TotalRecord
 93
 94        public string Description
106
107        public string GUID
128
129        
130
131        #region public BaseModel()
132        // -----------------------------------------------------------------------------------------
133        /// <summary>
134        /// 构造函数
135        /// </summary>

136        public BaseModel()
137        {
138            index = -1;
139            pageSize = 20;
140            currentPage = 1;
141            pages = 1;
142            totalRecord = 0;
143            description = "";
144
145            Columns.Add("GUID"typeof(string));
146        }

147        // -----------------------------------------------------------------------------------------
148        #endregion

149
150        public bool MoveNext()
166
167        public bool MovePre()
183
184        public bool GoToRow(int rowIndex)
202
203        public bool GoToFirst()
220
221        public bool GoToLast()
238
239        public void Insert()
251
252        public void Delete()
270
271        }

272}

273
结果发现数据在放序列化的时候出错,发现原来是没有加入序列化和反序列化构造函数,虽然BaseModal继承于DataTable,并且加入了[Serializable]树序列化属性,但是要实现想继承序列化,还是要加入构造函数,于是加入:
 1 #region protected BaseModel(SerializationInfo info, StreamingContext context) : base(info, context)
 2        // -----------------------------------------------------------------------------------------
 3        /// <summary>
 4        /// 反序列化构造函数
 5        /// </summary>
 6        /// <param name="si">反序列化所需的全部数据</param>
 7        /// <param name="context">目标描述</param>

 8        protected BaseModel(SerializationInfo info, StreamingContext context) : base(info, context)
 9        {
10        }

11        // -----------------------------------------------------------------------------------------
12        #endregion

13
14          #region public override void GetObjectData(SerializationInfo info, StreamingContext context)
15        // -----------------------------------------------------------------------------------------
16        /// <summary>
17        /// 序列化函数
18        /// </summary>
19        /// <param name="info">序列化所需的全部数据</param>
20        /// <param name="context">目标描述</param>

21        public override void GetObjectData(SerializationInfo info, StreamingContext context):base.GetObjectData(info, context)
22        {
23         }

24        // -----------------------------------------------------------------------------------------
25        #endregion

结果编译,没有任何错误,但是类中的属性(pageSize等)值却获取不到,想了很久,发现其实道理跟前面有些类似,因为自己加入的属性根本就没有“告诉”序列化函数去处理,自然而然值就丢失了,于是修改函数如下:
 1 #region protected BaseModel(SerializationInfo info, StreamingContext context) : base(info, context)
 2        // -----------------------------------------------------------------------------------------
 3        /// <summary>
 4        /// 反序列化构造函数
 5        /// </summary>
 6        /// <param name="si">反序列化所需的全部数据</param>
 7        /// <param name="context">目标描述</param>

 8        protected BaseModel(SerializationInfo info, StreamingContext context) : base(info, context)
 9        {
10            index = info.GetInt32("index");
11            pageSize = info.GetInt32("pageSize");
12            currentPage = info.GetInt32("currentPage");
13            pages = info.GetInt32("pages");
14            totalRecord = info.GetInt64("totalRecord");
15            description = info.GetString("description");
16        }

17        // -----------------------------------------------------------------------------------------
18        #endregion

19
20          #region public override void GetObjectData(SerializationInfo info, StreamingContext context)
21        // -----------------------------------------------------------------------------------------
22        /// <summary>
23        /// 序列化函数
24        /// </summary>
25        /// <param name="info">序列化所需的全部数据</param>
26        /// <param name="context">目标描述</param>

27        public override void GetObjectData(SerializationInfo info, StreamingContext context)
28        {
29            info.AddValue("index", index);
30            info.AddValue("pageSize", pageSize);
31            info.AddValue("currentPage", currentPage);
32            info.AddValue("pages", pages);
33            info.AddValue("totalRecord", totalRecord);
34            info.AddValue("description", description);
35            base.GetObjectData(info, context);
36        }

37        // -----------------------------------------------------------------------------------------
38        #endregion

OK,一切搞定了
posted on 2006-08-29 15:10 blockhead 阅读(1343) 评论(1)   编辑  收藏 引用 网摘 所属分类: Remoting
<script type="text/javascript"> // </script>

FeedBack:
#  re: Remoting系列专题---自定义序列化类
2006-08-29 18:16 | blockhead
刚看到一个夏桅 (xia4 wei2)提供的的技巧,在加入自定义字段,可以不用自己一个个加入,如夏桅所说:
根据我的experiance,需要自己实现ISerializable接口的情形,往往是因为“大部分字段可以自动序列化(比如int、string),而少数字段不支持序列化(比如Thread、WaitHandle),但这些字段对于对象又是必不可少的”的需求。也就是说,这些不支持序列化的字段在反序列化后仍不允许为空时,你得自己控制序列化/反序列化行为,在反序列化构造函数重新建立它们的实例。

这里的问题是,大部分字段都可以自动序列化的;但是为了少数几个不支持序列化的字段,却需要编写代码为所有字段都进行手工的序列化 — 这些代码不但冗繁,而且容易出错(比如忘掉了处理某个字段)。我一直希望能自己参与自动序列化/反序列化的行为,比如在自动反序列化之后,运行时能自动调用一段我自己的代码,处理那些不支持序列化的字段。

class SerializationHelper
...{
public static void Serialize(object obj, SerializationInfo info, StreamingContext context)
...{
MemberInfo[] members = FormatterServices.GetSerializableMembers(obj.GetType(), context);
foreach(FieldInfo field in members)
...{
info.AddValue(field.Name, field.GetValue(obj), field.FieldType);
}
}

public static void Deserialize(object obj, SerializationInfo info, StreamingContext context)
...{
MemberInfo[] members = FormatterServices.GetSerializableMembers(obj.GetType(), context);
foreach(FieldInfo field in members)
...{
field.SetValue(obj, info.GetValue(field.Name, field.FieldType));
}
}
}

下面是利用了这个SerializationHelper的自定义序列化方案:

[Serializable]
class Person : ISerializable
...{
// public field
public string Name = "Vista Xia";
// private field
private int age = 23;
// public property (no use in serialization)
public int Age
...{
get ...{ return age; }
set ...{ age = value; }
}
[NonSerialized]
public string Award;
// event/delegate
public event EventHandler Birthday;

public Person()
...{
Award = "MVP";
}

protected Person(SerializationInfo info, StreamingContext context)
...{
SerializationHelper.Deserialize(this, info, context);
Award = "MVP";
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
...{
SerializationHelper.Serialize(this, info, context);

如有不明白处,请查看夏桅 (xia4 wei2)的Blog
http://blog.joycode.com/sunmast/   回复   更多评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值