Deserializing .Net Object From PHP Using COM - c#

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.

Related

How to serialize an object as JSON and write it to a pipe asynchronously in .Net Core 3.1?

I want to asynchronously serialize a POCO object and write it to the response body without:
Having to buffer the response myself.
Going through an UTF-16 string.
Here is what I have now:
await using var w = new Utf8JsonWriter(context.Response.BodyWriter);
JsonSerializer.Serialize(w, rpcResult, serializationOptions);
The problem is that JsonSerializer.Serialize is not async.
JsonSerializer.SerializeAsync does not seem to have an overload that accepts Utf8JsonWriter. while JsonSerializer.Serialize does.
What am I missing?
According to the official documentation from Microsoft, you can actually call SerializeAsync with UTF8 stream object. Please check that.

Deserialize IEnumerable of protocol Buffer object sent by C# in C++

I got a task that I got something likeIEnumerable<State> StateList; sending from a C# based sever and I need to deserialize it in C++ based client. (State here is a proto class). I have no control on the proto. file so I can't just add any repeated message in the proto and make it work like a STL in C++. I don't know how I can deserialize this thing.
In C#,
System.IO.MemoryStream ms = new System.IO.MemoryStream (56 * stateList.Count());
ProtoBuf.Serializer.Serialize(ms, StateList);
So I think it use protobuf-net and use this function
public static void Serialize<T>(Stream destination, T instance);
BTW, we use MQTT as our transmit protocol.

Sending protobuf serialized object from c# to java server not working?

I have simple c# client app which sends object to java based server app.
Note:I am using protobuf-net on clinet side. For this application I have simple .proto file with only one field and .java class is generated by protoc compiler.
.Proto file:
message Person {
required string id = 1;
}
C# client to send object
MemoryStream ms = new MemoryStream();
Person per = new Person();
per.id = "TestId001";
Serializer.Serialize<Person>(ms, per);
byte[] buffer = ms.ToArray();
clientSocket.SendTo(buffer, hostEP);
Java based server to receive object
DataInputStream inputStream=new DataInputStream(socket.getInputStream());
Person person = Person.parseFrom(socket.getInputStream());
System.out.println("Id: " + person.getId());
Problem: I not getting the serialized message as sent by the c# app.Even I am not getting
any errors. That's why I was unable to figureout the problem.
"Problem: I not getting the serialized message"
This sounds simply like the classic "sockets are streams" issue (second example here: http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html). If you have written data to a stream but haven't closed that stream, the receiving stream does not terminate. It also does not automatically know that the client sent (say) 117 bytes that should be considered a single message. You have two options:
close the outbound stream after writing (only suitable for sending single messages, not for continued discussions between two nodes)
introduce some form of framing - for example a length-prefix - so that the receiver knows to only try to read a certain amount of data, rather than trying to read to the EOF (which will never come if you haven't closed the outbound stream)
Note: in addition to the "sockets are streams" issue, also keep in mind that protobuf messages are appendable. A protobuf message, by itself, has no notion of where it ends. Fortunately, both the existing bullet points above will address this. But importantly, you can't just write 3 Person object to the stream in a frame (or close the stream), and then expect to be able to get back 3 Person objects at the other end: you will get one Person object. In this scenario, the simplest option is to add a wrapper object, i.e.
message SomeMessage {
repeated Person people = 1;
}
Try adding these attributes to your class in C# and check if the input is ok in Java.
[ProtoContract]
class Person
{
[ProtoMember(1)]
public string id = "1";
}

How to send a brokermessage that is a list of other types

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);

ActiveMQ - deserialize an ActiveMQBytesMessage message

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?

Categories