Witam.
Czy mógłby mi ktoś pomóc, najlepiej podać przykład jak za pomocą bf dokonać deserializacji do typu zdefiniowanego w pliku dll. Bo wstyd mówić ale już od jakichś trzech dni próbuję dokonać tego dzieła i ciągle jakieś problemy. Próbowałem chyba wszystkiego. Nie wiem już co począć. Piszę komunikator.
Przykłady do klasy BinaryFormatter
masz na MSDN.
Pokaż swój kod, to co do tej pory zrobiłeś. Jak wygląda ten typ "zdefiniowany w pliku dll"? Masz do niego dodaną referencję czy robisz jakieś Assembly.Load()
?
Widziałem przykłady z MSDN, ale jakoś nie działają, muszę robić jakiś podstawowy błąd, tym bardziej, że nigdy nie pisałem w c# i nie używałem BF.
zawartość dll'a
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace VoicePad
{
[Serializable]
public class Master
{
public Dictionary<string, string> network;
public List<string> app_ips;
public string app_channel_name;
public string protocol_msg;
public Master()
{
this.network = new Dictionary<string, string>();
this.app_ips = new List<string>();
}
}
}
główny wątek klienta:
void main()
{
if (CLIENT.Connected)
{
NetworkStream ns = CLIENT.GetStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new Binder();
bf.Binder.BindToType(master_protocol.GetName().ToString(), "Master");
this.received = bf.Deserialize(ns); // received jest zmienną dynamiczną (dynamic)
if (this.update)
{
bf.Serialize(ns, send);
this.update = false;
}
ns.Close();
}
}
definicja bindera:
class Binder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
typeName = typeName.Replace("cltms", "VoicePad");
assemblyName = assemblyName.Replace("cltms", "VoicePad");
return Type.GetType(string.Format("{0}, {1}", typeName, assemblyName));
}
}
Server pod względem logiki wygląda tak samo. dll'a ładuję za pomocą Assembly.LoadFrom("nazwa_pliku") znajduje się on w tym samym folderze co plik "exek". Z Ładowaniem, nie ma żadnego problemu.
Czy nie możesz w kliencie referencjonować tej samej biblioteki i żywcem wrzucić typu do Bindera, a nie lepić go po stringach. Jeżeli nie masz tej biblioteki załadowanej do procesu to Typ, który w ten sposób utworzyłeś wygląda jak typ który chciałeś utworzyć ale nie NIE JEST!
Spróbuj użyć tak stworzonego Typu ale obawiam się, że będzie ten sam problem.
string path = C:\ myDll.dll
ObjectHandle formatParamsWrapper = Activator.CreateInstanceFrom(AppDomain.CurrentDomain, path, "VoicePad.Master");
object formatParams = formatParamsWrapper.Unwrap();
Type formatParamsType = formatParams.GetType();
Dzięki za zainteresowanie tematem, ale udało mi się już pozbyć problemu. Miałem po prostu nieaktualnego dll'a w projekcie servera. Serializowałem i deserializowałem dwie różne rzeczy.