.NET智能卡 – 序列化/反序列化远程对象。 输入流不是有效格式

我使用的是.NET智能卡,它具有与.NET远程处理相同的概念。

所以我的智能卡(作为服务器)有这个服务:

public class MyService : MarshalByRefObject { string a = "abC"; public byte[] MySampleMethod() { MyService obj = new MyService(); return help.ObjectToByteArray( obj); }}} 

这是ObjectToByteArray(obj)

 public static byte[] ObjectToByteArray(MyService obj) { if (obj == null) return null; BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(0); bf.Serialize(ms, obj); return ms.ToArray(); } 

至于客户:

  public static void Main() { // create and register communication channel APDUClientChannel channel = new APDUClientChannel(); ChannelServices.RegisterChannel(channel); // get the referenc to remote object MyService service = (MyService)Activator.GetObject(typeof(MyService), URL); // invoke the remote method byte[] result = service.MySampleMethod(); MyService obj = ByteArrayToObject(result); Console.WriteLine(result[0]); Console.ReadLine(); // unregister the communication channel ChannelServices.UnregisterChannel(channel); } 

ByteArrayToObject

  public static MyService ByteArrayToObject(byte[] arrBytes) { MemoryStream memStream = new MemoryStream(0); BinaryFormatter binForm = new BinaryFormatter(); memStream.Write(arrBytes, 0, arrBytes.Length); memStream.Seek(0, SeekOrigin.Begin); //memStream.Position = 0; MyService obj = (MyService)binForm.Deserialize(memStream); return obj; } 

问题是当我想反序列化对象时。

我测试了这个字符串“ABCDE”,在卡片中将其序列化,结果hex为:

1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05-00-00-00-01-41-00-42-00-43-00- 44-00 -45-00

当我在我的电脑上序列化时的结果是:

00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-00-06-01-00-00-00-05-41-42- 43-44 -45-0B。

所以在我的PC应用程序中,反序列化第二个工作正常,但当我反序列化第一个字符串(从智能卡)我得到:

“输入流不是有效的二进制格式。起始内容(以字节为单位)为:1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05- 00-00 ……“

Gemalto.NET智能卡仅支持通过引用进行编组,因此您可以在客户端访问服务器中的任何基元和结构类型,而无需序列化,因为您已经通过远程调用获得了对象的引用:

所以首先注册您的服务:

 public class MyServer { ///  /// specify the exposed remote object URI. ///  private const string REMOTE_OBJECT_URI = "MyService.uri"; ///  /// Register the server onto the card. ///  ///  public static int Main() { // Register the channel the server will be listening to. ChannelServices.RegisterChannel(new APDUServerChannel()); // Register this application as a server RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyService), REMOTE_OBJECT_URI, WellKnownObjectMode.Singleton); return 0; } } 

然后定义服务类,您可以为gemalto文档返回基本类型和结构:

可以编组的类型包括基本值类型(byte,short,char,int,long,string等),结构,基本类型数组和MemoryStreams

 public class MyService : MarshalByRefObject { public struct Person { public string name; public int id; public Person(int id, string name) { this.name = name; this.id = id; } public string getName() { return this.name; } public int getId() { return this.id; } } public string MySampleMethod() { return "This is return String"; } public Person getPerson() { Person person = new Person(15, "Wajdy"); return person; } } 

现在在客户端应用程序中,您将获得对服务对象的引用,您可以正常调用这些方法:

 public class MyClient { private const string URL = "apdu://selfdiscover/MyService.uri"; public static void Main() { // create and register communication channel APDUClientChannel channel = new APDUClientChannel(); ChannelServices.RegisterChannel(channel); // get the referenc to remote object MyService service = (MyService)Activator.GetObject(typeof(MyService), URL); Console.WriteLine(service.MySampleMethod()); MyService.Person person = service.getPerson(); Console.WriteLine(person.getName()); Console.WriteLine(person.getId()); Console.ReadLine(); // unregister the communication channel ChannelServices.UnregisterChannel(channel); } }