Search code examples
c#asp.netsshsftp

Downloaded audio file by "SSH" and returned by the "Service" but API cannot return to user


Why does this action not return anything? Method DownloadCallVoiceFile works well:

public virtual async Task<ActionResult> DownloadCallVoiceFile(string uniqueId, CancellationToken cancellationToken)
{
    // CallReport is a MemoryStream and everything is okay 
    var callReport = await _callCenterService.DownloadCallVoiceFile(uniqueId, cancellationToken); 
        
    // here is problem... this line returns nothing
    return File(callReport, "audio/wav", "1.wav"); 
}

It even saves the file on the server correctly... see this :

public virtual async Task<ActionResult> DownloadCallVoiceFile(string uniqueId, CancellationToken cancellationToken)
{
    var callReport = await _callCenterService.DownloadCallVoiceFile(uniqueId, cancellationToken);
  
    using (FileStream file = new FileStream("C:\\Users\\Ya\\Desktop\\TestFile.wav", FileMode.Create, FileAccess.Write))
        // just for test... file is okay
        callReport.CopyTo(file); 

    return File(callReport, "audio/wav", "1.wav");
}

However, I don't think there is a need for this.

But for more information see the method:

public class SshServices
{
    private static SftpClient? s_sftpClient; //using Renci.SshNet

    public async Task<MemoryStream> DownloadCallVoiceFile(string uniqueId,CancellationToken cancellationToken)
    {
        s_sftpClient = new SftpClient("host", "user", "password");
        await s_sftpClient.ConnectAsync(CancellationToken.None);

        if (s_sftpClient != null && s_sftpClient.IsConnected)
        {
            var serverAddress = @"\file\monitor\saved\Voice.Wav";
            var stream = new MemoryStream();
            var result = s_sftpClient.BeginDownloadFile(serverAddress, stream);

            do
            {
                await Task.Delay(100, cancellationToken);
            }
            while (result == null || !result.IsCompleted);

            if (result != null && result.IsCompleted) 
                s_sftpClient.EndDownloadFile(result);

            s_sftpClient.Disconnect();

            stream.Position = 0;

            // Return is okay and stream is not null
            return stream;       
        }
        else
        {
            throw new Exception();
        }
    }
}

Solution

  • these 2 lines:

    callReport.CopyTo(file);
    return File(callReport, "audio/wav", "1.wav");
    

    the position of callReport after the first line is: at the EOF. CopyTo plays forward from the current position to the end. Because callReport is at the EOF, there are zero bytes remaining to return to the client from the second line.

    Try adding callReport.Position = 0; between the two lines.