高分相赠,Remoting难度问题,本帖次日加分至200,两帖总共400分

bingdian37 2009-03-11 03:45:46
在remoting使用过程中
从客户端创建一个对象
传递到服务端
服务端有个持久化的功能,将对象进行二进制序列化到文件,保存起来
这个时候,从客户端传递过来的对象会无法序列化
提示:System.Runtime.Remoting.ServerIdentity未标记为可序列化

网上查了查,似乎是因为从客户端传递过来的对象存在一个透明代理
这个是无法序列化的

不知道应该如何解决。。。。

需要注意的是,在客户端与服务端的对象传递过程中,是没有问题的

真正的问题是,客户端传递到服务端之后,再次,手工序列化失败的问题


200分原帖地址:http://topic.csdn.net/u/20090310/16/3792b369-ed83-4297-b855-f9686fa9a3e5.html

本帖次日加分到200

如果解决,高分相赠
...全文
148 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
fantasyzc 2009-03-26
  • 打赏
  • 举报
回复
标记下
bingdian37 2009-03-26
  • 打赏
  • 举报
回复
暂时将该问题放放,结贴
ylwqhr 2009-03-20
  • 打赏
  • 举报
回复
传说回帖是一种美德!每天回帖即可获得 10 分可用分!
wanabe 2009-03-20
  • 打赏
  • 举报
回复
up
jf
feizai1314 2009-03-19
  • 打赏
  • 举报
回复
期待中
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
冤枉好人了

目前看来似乎不是抽象类的事情,是动态创建的ascx控件的问题

继续探索...
zzxap 2009-03-12
  • 打赏
  • 举报
回复
不懂太抽象了
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
自己顶一个
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
xiaoyuzi

你说的非常对

我就是通过客户端传递一个标记了可序列化标签的对象(但是不是继承自MarshalByRefObject),来确保对象是通过二进制序列化进行值传递,而不是引用传递的

目前可以传递到服务端,也可以正常使用

在这个传递过程中是没有问题的,可以确定不是传递的对象引用,因为如果客户端要传递一个MarshalByRefObject的对象,默认是不允许的.

即使打开了权限,传递过去之后,调用也会有问题(如果不经过处理的话)

现在的问题就是:那个通过二进制序列化之后,以值传递方式传递到服务端的对象.......无法被我手动序列化到一个文件

提示System.Runtime.Remoting.ServerIdentity未标记为可序列化

我考虑的原因是:在封送过来之后,在原始对象外面有个动态代理,而这个东西是无法序列化的

不知道如何解除他

不知道思路是不是有问题

如何解决

bingdian37 2009-03-12
  • 打赏
  • 举报
回复
到现在还没吃饭呢。。。

问题出在抽象类上。

解决彻底后上帖,给分
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
哈哈哈哈哈,发现了,也不是上面我说的原因


是抽象与继承的问题

正在整理东西,给大家一个交代
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
好像可以解决问题了

因为我的传递过程过于复杂啦..呵呵

我的参数传递过程

一个继承自MarshalByRefObject的RemoteObjectA.服务端一个继承自MarshalByRefObject的静态对象B.服务端一个继承自MarshalByRefObject的集合Cset.AddObject(clientType clientobject)

然后这个对象就无法序列化了

我在RemoteObjectA还有一个.AddObject(clientType clientobject)方法

所以就把原先的
RemoteObjectA.B.Cset.AddObject(clientobject)

改为
RemoteObjectA.AddObject(clientobject)

发现就可以了

我再去确认一下..

感谢xiaoyuzi代码的提示...因为我看到他的示例代码跟我的模式基本是一致的,但是他就可以

所以我也用简化后的东东试了试,居然可以了

现在先确认一下,如果OK就结贴散分


bingdian37 2009-03-12
  • 打赏
  • 举报
回复
zzxap

就是服务端从客户端接收了一个对象,却无法再次进行二进制序列化..
bingdian37 2009-03-12
  • 打赏
  • 举报
回复
wonder888888

这个问题愁死人啦

我可不想再给每个类增加一个copy方法,然后创建一个新对象出来..

希望早日解决
wonder888888 2009-03-12
  • 打赏
  • 举报
回复
正在帮你解决,皆分
zzxap 2009-03-12
  • 打赏
  • 举报
回复
问题太大了,把问题分小一点吧,要不没人帮你。
只要把问题分小,自己最后都知道解决方法了。
xiaoyuzi 2009-03-12
  • 打赏
  • 举报
回复
remoting 类忘发了

public class RemotingObj:MarshalByRefObject
{
public void SendAndSerialize(Student stu)
{
Stream stream = File.Open("c:\\Student.ser", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();

bformatter.Serialize(stream, stu);
stream.Close();
}
}
xiaoyuzi 2009-03-12
  • 打赏
  • 举报
回复
我做了一个例子。在单机上跑没有问题的,因为没有两台机器,没有测试两台机器情况。应该没有问题的。

要传输的对象和remoting对象类

[Serializable]
public class Student:ISerializable
{
private string name;

public string Name
{
get { return name; }
set { name = value; }
}

private int age;

public int Age
{
get { return age; }
set { age = value; }
}

public Student()
{ }

// For deserialize
public Student(SerializationInfo info, StreamingContext ctxt)
{
this.name = (string)info.GetValue("Name", typeof(string));
this.age = (int)info.GetValue("Age", typeof(int));
}

public override string ToString()
{
return "Age is:" + this.age.ToString() + ",Name is:" + this.name;
}

#region ISerializable Members

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", this.name);
info.AddValue("Age", this.age);
}

#endregion
}


Remoting server

static void Main(string[] args)
{
try
{
BinaryClientFormatterSinkProvider clientProvider = null;

BinaryServerFormatterSinkProvider serverProvider =
new BinaryServerFormatterSinkProvider();

serverProvider.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

System.Collections.IDictionary props = new System.Collections.Hashtable();


props["port"] = 5008;
props["typeFilterLevel"] = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
props["CustomErrorsEnabled"] = false;
TcpChannel chan = new TcpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(chan, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(ObjLib.RemotingObj),
"ObjLib.RemotingObj", WellKnownObjectMode.Singleton);

Console.WriteLine("Remoting server is started \r\n");
}
catch (RemotingException re)
{
Console.WriteLine(re.Message);
}


// Wait for Quit to terminate program
while (!(Console.In.ReadLine().Equals("Quit")))
{
;
}
}


client

static void Main(string[] args)
{
try
{
BinaryClientFormatterSinkProvider clientProvider =
new BinaryClientFormatterSinkProvider();

BinaryServerFormatterSinkProvider serverProvider =
new BinaryServerFormatterSinkProvider();

serverProvider.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

System.Collections.IDictionary props = new System.Collections.Hashtable();
props["port"] = 0;
props["name"] = System.Guid.NewGuid().ToString();
props["typeFilterLevel"] = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
props["CustomErrorsEnabled"] = false;
TcpChannel chan =
new TcpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(chan, false);

string strURL = String.Format("{0}{1}:{2}/{3}", "tcp://", "9.123.74.36", 5008, "ObjLib.RemotingObj");
ObjLib.RemotingObj rmtObj = (ObjLib.RemotingObj)Activator.GetObject(typeof(ObjLib.RemotingObj), strURL);

ObjLib.Student stu = new ObjLib.Student();
stu.Age = 30;
stu.Name = "Tommy";
rmtObj.SendAndSerialize(stu);
Console.WriteLine("Send object finish.\r\n");
}
catch (RemotingException re)
{
Console.WriteLine(re.Message);
}


// Wait for Quit to terminate program
while (!(Console.In.ReadLine().Equals("Quit")))
{
;
}
}
xiaoyuzi 2009-03-11
  • 打赏
  • 举报
回复
感觉你有点搞混淆了,.net remoting相当于远程方法调用,这个对象并不能在server段得到。传递对象只能定义一个函数方法,参数就是你的对象,但是对象如果要通过remoting传递,那么这个对象所有的成员都能够串行化,.net framework 数据类型一般都实现了串行化,如果你使用了很多自定义类型,你自己得实现。
简单做法是在客户端系列化通过字节流来传递到服务端,服务端要使用这个对象的话,再反系列化

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧