2016-03-07 56 views
1

我已經搜索高和低的工作解決方案發送圖像(例如tpngimage)到服務器使用datasnap方法 - 但我不能做到工作。德爾福datasnap發送從圖像到服務器(將存儲在數據庫中)

當我加載圖像並將其保存到內存流中時,我能夠從流中讀取圖像 - 本地在客戶機中,這並不令人意外。但是,當服務器方法被調用時,流是零且不包含任何內容,其他參數都很好(簡單數據類型和對象)。

我在這裏錯過了一些明顯的東西嗎?我的印象是TStream是datasnap方法的有效數據類型,但也許我錯了?

從客戶端看起來像這樣。

function TPerson.Update: Boolean; 
var 
    AStream : TMemoryStream; 
    APicture : TPngImage; 
    ASize : Integer; 
begin 
    if (FId > 0) then // if Id below zero we have a problem 
    begin 

    ClientModule1.ServerMethods1Client.UpdatePerson(Self); 
    APicture := TPngImage.Create; 
    AStream := TMemoryStream.Create; 
    try 
     // Temp just use a file 
     AStream.LoadFromFile('.\images\075.png'); 
     ASize := AStream.Size; 
     AStream.Position := 0; // wind back if needed 

     // just for testing, we can read back the image from the stream 
     APicture.LoadFromStream(AStream); 

     ClientModule1.ServerMethods1Client.UpdatePersonPicture(self, ASize, AStream); 

    finally 
     FreeAndNil(AStream); 
     FreeAndNil(APicture); 
    end; 

    end; 
    FModified := False; 
end; 

和代理方法看起來像這樣

procedure TServerMethods1Client.UpdatePersonPicture(APerson: TPerson; ASize: Integer; APictureStream: TMemoryStream); 
begin 
    if FUpdatePersonPictureCommand = nil then 
    begin 
    FUpdatePersonPictureCommand := FDBXConnection.CreateCommand; 
    FUpdatePersonPictureCommand.CommandType := TDBXCommandTypes.DSServerMethod; 
    FUpdatePersonPictureCommand.Text := 'TServerMethods1.UpdatePersonPicture'; 
    FUpdatePersonPictureCommand.Prepare; 
    end; 
    if not Assigned(APerson) then 
    FUpdatePersonPictureCommand.Parameters[0].Value.SetNull 
    else 
    begin 
    FMarshal := TDBXClientCommand(FUpdatePersonPictureCommand.Parameters[0].ConnectionHandler).GetJSONMarshaler; 
    try 
     FUpdatePersonPictureCommand.Parameters[0].Value.SetJSONValue(FMarshal.Marshal(APerson), True); 
     if FInstanceOwner then 
     APerson.Free 
    finally 
     FreeAndNil(FMarshal) 
    end 
    end; 
    FUpdatePersonPictureCommand.Parameters[1].Value.SetInt32(ASize); 
    FUpdatePersonPictureCommand.Parameters[2].Value.SetStream(APictureStream, FInstanceOwner); 
    FUpdatePersonPictureCommand.ExecuteUpdate; 
end; 

服務器的方法看起來是這樣的 - 它不能由於APictureStream爲零。

procedure TServerMethods1.UpdatePersonPicture(APerson: TPerson; ASize: integer; 
    APictureStream: TMemoryStream); 
var 
    APicture : TPngImage; 
begin 
    fdqPersons.Close; 
    fdqPersons.SQL.Clear; 
    fdqPersons.Connection.StartTransaction; 
    try 
    fdqPersons.SQL.Add('update Persons set Picture=:Picture '); 
    fdqPersons.SQL.Add('where Id=:Id'); 
    fdqPersons.ParamByName('Id').Value := APerson.Id; 

    APicture := TPngImage.Create; 
    try 
     // APicture for testing - but APictureStream is nil! 
     APicture.LoadFromStream(APictureStream); 
     fdqPersons.ParamByName('Picture').Assign(APicture); 
     fdqPersons.ExecSQL; 
    finally 
     FreeAndNil(APicture); 
    end; 
    fdqPersons.Close; 
    fdqPersons.Connection.Commit; 
    LogEvent(format('Person picture updated ID: %d',[APerson.id])); 
    except 
    on e:exception do 
    begin 
     fdqPersons.Connection.Rollback; 
     LogEvent(format('Error updating person picture %s',[e.Message])); 
     raise; 
    end; 
    end; 
end; 
+1

在客戶端,「APicture」沒有做任何事情,雖然這不是你的問題。事實上,你不是「發送一個'TPngImage'」作爲你的問題描述。你只是發送一個文件。 –

+0

是的,我已經嘗試了不同的解決方案,現在如果它是一個文件或圖像並不重要。我只想得到一些流數據。 現在,有趣的是,我只是刪除了這一行客戶端... APicture.LoadFromStream(AStream); 和vupti - 現在有可用的數據在服務器端.... – hhaumann

回答

2

當你調用APicture.LoadFromStream(AStream);流的位置,去年底,因此路過的時候它變成ClientModule1任何留下的數據被讀取它沒有。擺脫寫入數據流的不必要部分到TPngImage,或者在該部分之後將流的位置重置爲0。