【问题标题】:Delphi datasnap send an from image to server (to be stored in database)Delphi datasnap 将图像发送到服务器(存储在数据库中)
【发布时间】:2016-03-07 14:01:37
【问题描述】:

我已经到处搜索了使用 datasnap 方法将图像(例如 tpngimage)发送到服务器的工作解决方案 - 但我无法使其工作。

当我加载图像并将其保存到内存流时,我能够从流中读取图像 - 在客户端本地读取,这并不奇怪。但是当调用服务器方法时,流是 nil 并且不包含任何内容,其他参数都很好(简单数据类型和对象)。

我在这里错过了什么明显的东西吗?我的印象是 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;

Server 方法如下所示 - 由于 APictureStream 为 nil 而失败。

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;

【问题讨论】:

  • 在客户端,APicture 没有做任何事情,尽管这不是您的问题。实际上,您并没有像您的问题所描述的那样“发送TPngImage”。你只是发送一个文件。
  • 是的,我尝试了不同的解决方案,现在不管是文件还是图像。我只想获取一些流数据。现在,有趣的是,我刚刚删除了这条线客户端... APicture.LoadFromStream(AStream);还有 vupti - 现在服务器端有可用的数据......

标签: delphi datasnap


【解决方案1】:

当您调用APicture.LoadFromStream(AStream); 时,流的位置会到达末尾,因此当将其传递给ClientModule1 时,它没有任何数据可供读取。要么删除将流写入TPngImage 的不必要部分,要么在该部分之后将流的位置重置回 0。

【讨论】:

    猜你喜欢
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2012-12-11
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多