I want to pass extra information besides the response structure in service method. e.g if the service method returns list of Customer then depending on some condition I would like to pass extra guid to the client. How can I do this?
I have looked at envelopes but I am not sure whether they will do what I want, so I want to ask a question before I go and implement custom envelope.
I should have been more precise, I need to pass extra information which could be errors or work log back to the client, but it is optional. The solution should be able to work with all the server methods, which are 100+ now. That is the reason I was thinking of using envelopes. If using envelopes is the correct solution could you please provide some example code.
yes, this is correct solution. in your case, you should have active envelope on server side and inactive on client side.
in this case, client will be able to decode data passed by server and will not pass anything to server.
simple example:
type
TMyEnvelope = class(TROMessageEnvelope)
private
fData: String;
protected
procedure intProcessOutgoing(Source, Dest: TStream; aMessage: IROMessage); override;
procedure intProcessIncoming(Source, Dest: TStream; aMessage: IROMessage); override;
function GetDefaultEnvelopeMarker: string; override;
published
property ExtraData: String read fData write fData;
end;
{ TMyEnvelope }
function TMyEnvelope.GetDefaultEnvelopeMarker: string;
begin
Result := 'ExtraData';
end;
procedure TMyEnvelope.intProcessIncoming(Source, Dest: TStream;
aMessage: IROMessage);
var
len: integer;
begin
Source.Read(len, Sizeof(Integer));
if len > 0 then begin
SetLength(fData, len div sizeof(Char));
Source.Read(Pointer(@fData)^, len);
end
else
len := 0;
Dest.CopyFrom(Source, Source.Size - Source.Position);
end;
procedure TMyEnvelope.intProcessOutgoing(Source, Dest: TStream;
aMessage: IROMessage);
var
len: integer;
begin
len := Length(fData)*SizeOf(Char);
Dest.Write(len, Sizeof(Integer));
if len > 0 then
Dest.Write(Pointer(@fData)^, len);
Dest.CopyFrom(Source, Source.Size);
end;
unit V6LinkEnvelope;
interface
uses
{$IFDEF DELPHIXE2UP}
System.SysUtils, System.Classes,
{$ELSE}
SysUtils, Classes,
{$ENDIF}
uROMessage, uROClientIntf;
type
Tv6LinkEnvelope = class(TROMessageEnvelope)
private
FData: string;
protected
procedure intProcessIncoming(Source: TStream; Dest: TStream;
aMessage: IROMessage); override;
procedure intProcessOutgoing(Source: TStream; Dest: TStream;
aMessage: IROMessage); override;
function GetDefaultEnvelopeMarker: string; override;
end;
implementation
{ Tv6LinkEnvelope }
function Tv6LinkEnvelope.GetDefaultEnvelopeMarker: string;
begin
Result := 'V6LinkEnvelope';
end;
procedure Tv6LinkEnvelope.intProcessIncoming(Source, Dest: TStream;
aMessage: IROMessage);
var
iLen: integer;
begin
Source.Read(iLen, Sizeof(Integer));
if iLen > 0 then begin
SetLength(FData, iLen div sizeof(Char));
Source.Read(Pointer(@FData)^, iLen);
end
else
iLen := 0;
Dest.CopyFrom(Source, Source.Size - Source.Position);
end;
procedure Tv6LinkEnvelope.intProcessOutgoing(Source, Dest: TStream;
aMessage: IROMessage);
var
iLen: integer;
begin
FData := 'Hello World How Are You';
iLen := Length(FData) * SizeOf(Char);
Dest.Write(iLen, Sizeof(Integer));
if iLen > 0 then
Dest.Write(Pointer(@FData)^, iLen);
Dest.CopyFrom(Source, Source.Size);
end;
end.
and C# code is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using RemObjects.SDK.Helpers;
namespace Softtech.V6API
{
public class V6LinkEnvelope : RemObjects.SDK.MessageEnvelope
{
public override string DefaultEnvelopeMarker
{
get { return "V6LinkEnvelope"; }
}
protected override MemoryStream InternalUnwrap(Stream source)
{
var dest = new MemoryStream();
var reader = new BinaryReader(source);
var dataSize = reader.ReadInt32();
var data = reader.ReadBytes(dataSize);
string dataString = System.Text.Encoding.UTF8.GetString(data);
source.CopyTo(dest);
return dest;
}
protected override MemoryStream InternalWrap(Stream source, byte[] header)
{
return source as MemoryStream;
}
}
}
It is working but I do not get the FData string set in Delphi in “dataString” variable in C#. Could you please have a look?
You cannot decode Delphi-sent string as UTF8. Depending on Delphi version you need to use either System.Text.Encoding.ASCII or System.Text.Encoding.Unicode to decode incoming bytes.