Search code examples
c#windows-phone-8bitmapftpcompact-framework

Windows Phone 8 FtpClient won't upload stream data previously used for issue with BitmapImage


I will try my best to explain the issue clearly. I'm using the code from

http://msdn.microsoft.com/en-us/magazine/dn385710.aspx

to create a photo sharing app. I am able to FTP images to my server fine. The issue I'm facing is when I tried to create the app to preview the picture and then FTP it. The FTP will still transfer the file, but the file size is always 0 size. I'm not sure if this is a bug or possibly me not disposing a certain object before FTP. Below are my codes:

Page 1

BitmapImage bitmapImage;

public PhotoPreview()
{
    InitializeComponent();

    btnYes.Tap += btnYes_Tap;

    imgPreview.Width = G.getScreenWidth();
    imgPreview.Height = G.getScreenHeight() - 250;

    //windows phone 8 bug. When bitmap image is set...it blocks the FTP process thread. Will perform FTP on seperate page
    previewPhoto();
}

void previewPhoto()
{
    bitmapImage = new BitmapImage();
    bitmapImage.SetSource(G.myStream);
    imgPreview.Source = bitmapImage;
}

private void btnYes_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    disposeImage(bitmapImage);

    NavigationService.Navigate(new Uri("/PhotoFTP.xaml", UriKind.Relative));
}

private void disposeImage(BitmapImage img)
{
    if (img != null)
    {
        try
        {
            using (var ms = new MemoryStream(new byte[] { 0x0 }))
            {
                img = new BitmapImage();
                img.SetSource(ms);
            }
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine("ImageDispose FAILED " + e.Message);
        }
    }
}

Page 2

const string 
    IP_ADDRESS = "888.88.888",
    FTP_USERNAME = "test",
    FTP_PASSWORD = "test123"
    ;

string filename;

FtpClient ftpClient = null;
TestLogger logger = null;

public PhotoFTP()
{
    InitializeComponent();

    DateTime thisDay = DateTime.Today;
    string timestamp = thisDay.Hour.ToString() + "_" + thisDay.Minute.ToString() + "_" + thisDay.Second.ToString();
    filename = timestamp + ".jpg";
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Test_connect();
}

private async void Test_connect()
{
    logger = TestLogger.GetDefault(this.Dispatcher);
    lstLogs.ItemsSource = logger.Logs;

    ftpClient = new FtpClient(IP_ADDRESS, this.Dispatcher);

    ftpClient.FtpConnected += ftpClient_FtpConnected;
    ftpClient.FtpFileUploadSucceeded += ftpClient_FtpFileUploadSucceeded;
    ftpClient.FtpFileUploadFailed += ftpClient_FtpFileUploadFailed;
    ftpClient.FtpAuthenticationSucceeded += ftpClient_FtpAuthenticationSucceeded;
    ftpClient.FtpAuthenticationFailed += ftpClient_FtpAuthenticationFailed;

    logger = TestLogger.GetDefault(this.Dispatcher);

    await ftpClient.ConnectAsync();

    logger.AddLog("Connecting...");
}

async void ftpClient_FtpConnected(object sender, EventArgs e)
{
    logger.AddLog("Preparing...");
    await (sender as FtpClient).AuthenticateAsync(FTP_USERNAME, FTP_PASSWORD);
}

private async void Test_upload()
{
    logger.AddLog("Uploading photo...");
    await ftpClient.UploadFileAsync(G.myStream, "username_timestamp.jpg");
}

void ftpClient_FtpAuthenticationFailed(object sender, EventArgs e)
{
    logger.AddLog("Connection error.");
}

void ftpClient_FtpAuthenticationSucceeded(object sender, EventArgs e)
{
    logger.AddLog("Connection established.");
    Test_upload();
}

void ftpClient_FtpFileUploadFailed(object sender, FtpFileTransferFailedEventArgs e)
{
    logger.AddLog("Failed.");
}

Boolean firstTime = true;
void ftpClient_FtpFileUploadSucceeded(object sender, FtpFileTransferEventArgs e)
{
    logger.AddLog("Completed.");
}

If I comment out the line previewPhoto(); in page 1, it will FTP the file to my server fine. I believe the issue is the

bitmapImage.SetSource(G.myStream);

I've also tried to create two separate stream. One to preview the photo and the other to FTP. The result still resulted in 0 size file when FTP to the my server.


Solution

  • It's because the BitmapImage reads to the end of the stream, so the FtpClient has no data to read/upload.

    Use Stream.Seek to reset the stream pointer back to the beginning.

    G.myStream.Seek(0, SeekOrigin.Begin);