Смарт-карта.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", сериализую ее в карточку и получаю шестнадцатеричный результат:
1С-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.
Итак, в моем приложении для ПК десериализация второго работает хорошо, но когда я десериализовал первую строку (со смарт-карты), я получил:
"Входной поток не является допустимым двоичным форматом. Начальное содержимое (в байтах): 1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05-00-00 ..."
1 ответ
Смарт-карта Gemalto.NET поддерживает только сортировку по ссылке, поэтому любые примитивные и структурные типы, имеющиеся на сервере, могут быть доступны в клиенте без необходимости сериализации, поскольку у вас уже есть ссылка на объект через удаленный вызов:
поэтому сначала зарегистрируйте свой сервис:
public class MyServer
{
/// <summary>
/// specify the exposed remote object URI.
/// </summary>
private const string REMOTE_OBJECT_URI = "MyService.uri";
/// <summary>
/// Register the server onto the card.
/// </summary>
/// <returns></returns>
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:
Типы, которые можно маршалировать, включают в себя основные типы значений (байты, короткие, 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);
}
}