I'm wondering is there a way to send some kind of generics for example List <float> floatValues = new List<float>() need to be sent to udp client. I don't know how to do that, any help will be appreciated!
You can serialize floatValues using some serialization facility (like XmlSerializer, BinaryFormatter or DataContractSerializer) and than deserialize it back.
Or you can create your own "application level protocol" and put to the stream type name and serializer type and use this information during deserialization process.
What you want to do is known as serialization/deserialization
In computer science, in the context of data storage and transmission, serialization, is the process of converting a data structure or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and "resurrected" later in the same or another computer environment
Instead of building your own serializer, I would recommend to use one of the existing libraries like
XmlSerializer,
SoapFormatter,
BinaryFormatter,
DataContractSerializer ,
DataContractJsonSerializer,
JavaScriptSerializer,
Json.Net,
ServiceStack,
Protobuf.Net ........
Here is an example using Json serialization
//Sender
string jsonString = new JavaScriptSerializer().Serialize(floatValues);
byte[] bytesToSend = Encoding.UTF8.GetBytes(jsonString);
//Receiver
string receivedJson = Encoding.UTF8.GetString(bytesToSend);
List<float> floatValues2 = new JavaScriptSerializer()
.Deserialize<List<float>>(receivedJson);
Related
I'm trying to store large objects as gzipped JSON text to an Azure blob.
I don't want to hold the serialized data in memory, and I don't want to spool to disk if I can avoid it, but I don't see how to just let it serialize and compress on the fly.
I'm using JSON.NET from Newtonsoft (pretty much the de facto standard JSON serializer for .NET), but the signatures of the methods don't really seem to support on-the-fly streaming.
Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob has an UploadFromStream(Stream source, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) method, but in order for that to work properly, I need to have the position of the stream be 0, and the JsonSerializer.SerializeObject doesn't do that. It just acts on a stream, and when it's done the stream position is at EOF.
What I'd like to do is something like this:
public void SaveObject(object obj, string path, JsonSerializerSettings settings = null)
{
using (var jsonStream = new JsonStream(object, settings ?? _defaultSerializerSettings))
using (var gzipStream = new GZipStream(jsonStream))
{
var blob = GetCloudBlockBlob(path);
blob.UploadFromStream(gzipStream);
}
}
...the idea being, serialization does not start until something is pulling data (in this case, the GZipStream, which does not compress data until pulled by the blob.UploadFromStream() method) thus it maintains a low overhead. It does not need to be a seekable stream, it just needs to be read on demand.
I trust everyone can see how this would work if you were doing a stream from System.IO.File.OpenRead() instead of new JsonStream(object obj). While it gets a bit more complicated because Json.NET needs to "look ahead" and potentially fill a buffer, they got it working with the CryptoStream and GZipStream and that works real slick.
Is there a way to do this that does not load the entire JSON representation of the object into memory, or spool it to disk first just to regurgitate? If CryptoStreams can do it, we should be able to do it with Json.NET without a large amount of effort. I would think.
I have a .net Web service Method 'CheckCustomerLicense', and this method returns a C sharp serialized object, I am calling this method via Soap from PHP.
I am getting the serialized object which is binary formatted and not in XML.
I want to access that data as object in PHP, but to do this I must desirealize it, and since its a .NET object I want to use .NET built in class 'System.Runtime.Serialization.Formatters.Binary.BinaryFormatter' via COM.
The Code I am Using For This Is Shown Below:
<?php
class eToolsLicenseNew
{
}
$url='http://mail.ucm.com.au/eToolsLicenseWebService/eToolsLicenseWebUpdateService.asmx?WSDL';
$soap = new SoapClient($url, array(
"trace" => 1, // enable trace to view what is happening
"exceptions" => 1, // disable exceptions "cache_wsdl" => 1)
);
try {
$customer=array('customerId'=>'12345');
$result=$soap->CheckCustomerLicense($customer);
//print_r($result);
$obj = new COM("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter");
$object=new eToolsLicenseNew();
$object=$obj->Deserialize($result); // call to deserilize method
}
catch (SoapFault $e)
{
echo "Error: {$e->faultstring}";
}
?>
But When I call 'Deserializing Method' Giving Internal Server Error....
Other than that every thing is fine, Can Any one is there to help me... Please...
The data your receive is a byte array. If it contains a .NET binary formatted object, you will need to have a BinaryFormatter to deserialize it. A binary formatters Deserialize method however, does not take a byte array. It takes a stream of any kind. The simplest conversion method from byte array to a stream is using a MemoryStream. This takes a byte array as constructor parameter.
var bytes = new byte[50]; // example byte array
using(var stream = new MemoryStream(bytes))
{
BinaryFormatter formatter = new BinaryFormatter();
var obj = (YourExpectedType)formatter.Deserialize(stream);
}
This is what the C# code would look like, you will need to adapt it to the COM/PHP variant.
Again, if this is really the case, someone is sending a binary serialized object via XML serialized SOAP to someone, then the first someone needs to learn how to code webservices. Because this is not an interoperable webservice, this is C#-to-C# communication wasting time using SOAP.
I'm trying to send a broker message to a service bus and I want the message to be a list of multiple types. I've tried using interfaces as well as objects and it works fine until I add more than one type to the list. I'm read several posts and online articles about doing something similar and they all seem to be specific to doing manual xml seralization or using WCF. In this case the seralization is happening automatically.
My code is like so:
Queue<Object> x = new Queue<Object>();
x.Enqueue(new VRequest());
x.Enqueue(new PRequest());
ServiceBus.TrackerClient.SendAsync(new BrokeredMessage(x) { ContentType = "BulkRequest" });
Then my broker message handler (where a seralization error occurs):
var bulk = message.GetBody<Queue<Object>>();
Any ideas on how I can send a single broker message with multiple types?
To anyone interested you can use a binary formatter and memory stream to accomplish this. It's super flexible since you are working binary data... You can even use interfaces, etc. You will need to convert to a byte array once you have the memory stream so you can send it over the network. Then you are able to deserialize it on the other end. Also make sure you mark your objects are serializable.
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
Queue<IYodas> q = new Queue<IYodas>();
q.Enqueue(new Yoda());
q.Enqueue(new Yoda2());
formatter.Serialize(stream, q);
Byte[] package = stream.ToArray();
// Send broker message using package as the object to send
....
// Then on the other end (you will need a byte array to object function)
Queue<IYodas> result = (Queue<IYodas>)ByteArrayToObject(package);
In my job, I work with an application developped partly in c++ and C#. The C++ code is responsible to manage activeMQ (send, receive message).
I've developped an application to monitor the messages sent in the topic by subscribing myself with my C# application.
So when a message is sent to a topic, my application manage to handle the message, but the message is serialized in ActiveMQBytesMessage.
How can I deserialize this object ?
public void OnMessage(IMessage message)
{
if (message != null)
{
var content = (message as ActiveMQBytesMessage).Content; // This is a byte[], I tried to deserialize using BinaryFormatter but it throws an exception, I can't write it here because I'm at home.
}
}
I just noticed that ActiveMQBytesMessage inherits IBytesMessage from namespace Apache.NMS, but I see nothing which helps me to deserialize the message.
I use the last version of ActiveMQ with NMS
[NB] The goal of my C# application is to simply monitor what's happening inside an ActiveMQ channel. That's why I need to deserialize the ActiveMQBytesMessage so I can display the name of the object and its content in a gridview.
[Added more information]
Here's what i tried to deserialize.
var memoryStream = new MemoryStream((message as ActiveMQBytesMessage).Content);
var binaryFormatter = new BinaryFormatter();
memoryStream.Position = 0;
var deserializedMessage = binaryFormatter.Deserialize(memoryStream);
And I get this error when it deserializes:
The input stream is not a valid binary format. The starting contents (in bytes) are: 00-00-00-00-00-00-4F-8C-00-00-00-09-00-00-00-00-54 ...
(I am making a few assumptions here, since you didn't specify certain details.) The BinaryFormatter you are attempting to use will only work for .NET objects, not for C++ objects. Most likely, these objects have not been encoded in a platform neutral way, and are in a C++ format specific to that particular compiler and platform. Therefore, it is up to you to parse the binary code directly to determine what object is encoded, and then to manually decode the data. If these are non-trivial objects, this will be a difficult task. If at all possible, try to get the original application to encode the objects into a platform neutral format that can be easily parsed and instantiated in C#. (I prefer using a TextMessage and XML encoding.) It won't be as efficient as the direct C++ to C++ encoding/decoding that is apparently going on right now, but it will allow external monitoring of the message stream. When I do this, I put the full typename (including namespace) of the object in the NMSType header property. This then tells me the internal structure of message content, and I can instantiate the correct object for parsing the data out of the message.
If all of that doesn't help, or the assumption is wrong and you are using Managed C++, perhaps this question/answer will help you: What serialization method is used for an ActiveMQ NMS C# object message?
I am working on C# sockets and using XMLSerializer to send and receive data.
The XML data are sent from a server to a client over a network connection using TCP/IP protocol. The XML.Serializer.Serialize(stream) serializes the XML data and send them over the socket connection but when I want to use the XMLSerializer.Deserialize(stream) to read. The sent data returns a xml parse error.
Here is how I'm serializing:
Memory Stream ms = new MemoryStream();
FrameClass frame= new FrameClass ();
frame.string1 = "hello";
frame.string2 = "world";
XmlSerializer xmlSerializer = new XmlSerializer(frame.GetType());
xmlSerializer.Serialize(ms, frame);
socket.Send(ms.GetBuffer(), (int)ms.Length, SocketFlags.None);
Deserializing:
FrameClass frame;
XmlSerializer xml = new XmlSerializer(typeof(FrameClass));
frame= (FrameClass)xml.Deserialize(new MemoryStream(sockCom.SocketBuffer));
listbox1.Items.Add(frame.string1);
listbox2.Items.Add(frame.string2);
I think it has something to do with sending the data one right after another.
Can anyone teach me how to do this properly?
Have you received all of the data before attempting to deserialize (it's not clear from your code). I'd be inclined to receive all of the data into a local string and the deserialize from that rather than attempting to directly deserialize from the socket. It would also allow you to actually look at the data in the debugger before deserializing it.
Try this:
using (MemoryStream ms = new MemoryStream())
{
FrameClass frame= new FrameClass ();
frame.string1 = "hello";
frame.string2 = "world";
XmlSerializer xmlSerializer = new XmlSerializer(frame.GetType());
xmlSerializer.Serialize(ms, frame);
ms.Flush();
socket.Send(ms.GetBuffer(), (int)ms.Length, SocketFlags.None);
}
If you're sending the Frame XML one right after the other, then you're not sending an XML document. The XML Serializer will attempt to deserialize your entire document!
I don't have time to research this now, but look into the XmlReaderSettings property for reading XML fragments. You would then create an XmlReader over the memorystream with those settings, and call it in a loop.
The important thing is to flush the stream. It's also useful to put the stream in a using block to ensure it's cleaned up quickly.
Besides what #John said about the Flush call, your code looks alright.
You say you're sending multiple FrameClass data pieces, then the code should work sending just a single piece of data.
If you need to send multiple data objects, then you cannot send them all in one go, otherwise the deserialization process will stumble over the data.
You could setup some communication between the server & the client so the server knows what it's getting.
client: I have some data
Server: ok I'm ready, send it
client: sends
Server: done processing
repeat process...