Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
MemoryStream zu string und wieder retour...
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

MemoryStream zu string und wieder retour...

beantworten | zitieren | melden

Hallo C# Fans!

Ich habe ein skurilles Problem:

Zur Versendung instanziierter Objekte via WebService serialisiere ich diese und verschicke sie als string zum Client.

Das geschieht folgendermaßen:


		public static string SerializeBinary(object request) 
		{
			string theString = "";

			System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = 
				new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
			System.IO.MemoryStream memStream = new System.IO.MemoryStream();
			serializer.Serialize(memStream, request);

			// convert memory stream to string
			memStream.Position=0;	
			using (System.IO.StreamReader sr = new System.IO.StreamReader(memStream) ) 
			{
				theString = sr.ReadToEnd();
				// Close and clean up the StreamReader
				sr.Close();
			}

			// return xml string
			return theString;
		}

Mit dieser Methode erhalte ich von dem entsprechenden Objekt einen serialisierten String.

Problem taucht dann aber beim Client auf. Ich bekomme es nicht geregelt, diesen String wieder in ein MemoryStream zu wandeln um mit serializer.Deserialize(memStream); den deserialisierungsprozess anzuschmeissen :-(


Wie wandle ich den String um und übergebe ihn der Deserialize() Funktion? Konkretes Problem:
Wenn ich einen MemoryStream aus dem String ertstelle, dann ist er geschlossen, und es gibt einen Laufzeitfehler, oder ich schließe ihn nach der Verarbeitung, dann meldet aber Deserialize() dass ein unerwartetes Ende im Stream aufgetreten ist ???

ODER: vielleicht gibt es eine andere Art und Weise aus dem String wieder ein instanziiertes Objekt zu machen?


Für Hilfe wäre ich sehr dankbar,

Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo norman_timo,

du brauchst nichts in String umzuwandeln. Du musst nur den Stream wieder an den Anfang zurückspulen, bevor du deserialisierst. Ich denke es gibt eine Seek-Methode oder eine Position-Eigenschaft dafür - habe aber gerade die Doku nicht zur Hand.

herbivore
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

beantworten | zitieren | melden

Jo, das ist prinzipiell richtig Herbivore, danke dafür!

Mein Problem ist aber, dass ich das Objekt via WebService verschicke!

Schicke ich den MemoryStream über SOAP (das geht nämlich nicht) dann bekomme ich nur die Info, an welcher Speicheraddresse und welche Länge das Speicherabbild auf dem Server hat, und das ist auf dem Client nicht zu verwerten.

Deshalb die Umwandlung in einen String, der wird nämlich problemlos via SOAP verschickt, auch weil es sich um einen Standarsdtyp dreht.

Auf dem Client steht also nur der String zur Verfügung.


Oder geht das komfortabler?

Ich bin für jede Idee zu haben und habe vollkommene Programmierhoheit :-)

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo norman_timo,

ok, überzeugt. Doch in einen String wandeln.

Beim Rückwandeln: MemoryStream öffnen (read/write), String reinschreiben (StreamWriter), Stream zurückspulen, deserialisieren.

HTH

herbivore
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.972

beantworten | zitieren | melden

Du weist schon, das ein WebService eigentlich auch in der Lage ist
jedes serialisierbare Object ohne umwandlung zu empfangen/Verschicken?
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

beantworten | zitieren | melden

Jo, auch das hab ich schon probiert:


			System.IO.MemoryStream memStream = new System.IO.MemoryStream();
			object retValue;

			// convert string to memory stream
			using (System.IO.StreamWriter sw = new System.IO.StreamWriter(memStream)) 
			{
				sw.WriteLine(theString);

				// convert memory stream to object
				System.Runtime.Serialization.Formatters.Soap.SoapFormatter deserializer = 
					new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();

				memStream.Position=0;
				retValue = deserializer.Deserialize(memStream);

				// Close and clean up the StreamReader
				memStream.Close();
				sw.Close();
			}


Das resultiert in folgender Fehlermeldung:
Zitat
{"An unexpected end of file parsing NAME has occurred. Line 37, position 2." }

Nu, aber es gibt bei mir in dem String kein Ding wie NAME, ich denke dass er aber irgendwo ein EOS (EndOfStream) erwartet, das er nicht bekommt, weil der Stream noch nicht geschlossen wurde :-(

Schließe ich ihn vorher meckert er, dass er geschlossen ist, und nicht verwenden kann ???

Was mache ich verkehrt?

Norman-Timo


[EDIT Sorry, nicht verwirren lassen, dass ich einmal den BinaryFormatter benutzt hab, und jetzt den SOAPFormatter, ich unterstütze BEIDES, pass aber schon auf, dass ich immer nur eine Version beim Server und Client verwende :-)[/EDIT]
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

beantworten | zitieren | melden

@FZelle:

Ja, das versuche ich irgendwie, muss aber sagen, dass ich das Serialisieren selbst in die Hand nehmen möchte, da ich Objekte serialisieren will, OHNE dass Klassen, die vererbt worden sind mitserialisert werden!

Ist es dann immer noch problemlos möglich?

Und wenn wie?

Vielleicht ist das eine Lösung die mir zusagt?

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

beantworten | zitieren | melden

Trööööt!

Ich bin so blöd :-)))

Naja eigentlich nicht, aber es reimt sich doch so toll :-)

Ich habe den Fehler gefunden:

eine kleine Zeile im Code mehr:



// ...

sw.Flush();

// ...


schreibt den kompletten String in den MemoryStream und wird somit auch als komplett erkannt!

Jetzt bin ich auf eine andere Fehlermeldung gestoßen:
Zitat
{"The constructor to deserialize an object of type CPM.Std.Tracking.WebControls.WebTrackingMap was not found." }

aber das ist klar, weil ich dem Objkekt noch nicht erklärt hab, wie es sich deserialisieren soll, das ist eine Kleinigkeit!

Dank allen trotzdem, vielleicht haben andere genau das gleiche Problem?

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
VizOne
myCSharp.de - Member

Avatar #avatar-1563.gif


Dabei seit:
Beiträge: 1.373

beantworten | zitieren | melden

Wäre es in deinem Fall nicht besser, den String als z.B. Base64 zu codieren? Sonst hast du doch die ganzen nicht-druckbaren Zeichen mit drin:


...
return Convert.ToBase64String(memStream.GetBuffer(), 0, memStream.Length);

Deserialisieren:


byte[] data = Convert.FromBase64String(theString);
MemoryStream ms = new MemoryStream(data);
....

Also nichts mit StreamReader/StreamWriter. Das ganze ist nicht nur einfacher sondern IMHO auch besser für SOAP.


MfG VizOne
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

Themenstarter:

beantworten | zitieren | melden

Yes!

Nochmal um einiges besser!

Das werd ich sofort mit einbauen, weil ich nämlich auch festgestellt hab, dass beim BinaryFormatter er das Problem mit der Übertragung hat (whrscheinlich eben Druckzeichen :-)

Herzlichen Dank, ein wundervoller Beitrag hierzu!

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers