使用PCL Xamarin Forms将图像上载到FTP服务器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PCL Xamarin Forms将图像上载到FTP服务器相关的知识,希望对你有一定的参考价值。

我是Xamarin和C#世界的新手,我正在尝试将图像上传到FTP服务器。我看到FtpWebRequest类做到这一点,但我没有做对,我不知道如何注入plataform特定代码,我甚至不知道它是什么意思,已经看过这个视频(https://www.youtube.com/watch?feature=player_embedded&v=yduxdUCKU1c)但我不知道看看如何使用它来创建FtpWebRequest类并上传图像。

我看到这个代码(这里:https://forums.xamarin.com/discussion/9052/strange-behaviour-with-ftp-upload)发送图片,我无法使用它。

public void sendAPicture(string picture)
{

    string ftpHost = "xxxx";

    string ftpUser = "yyyy";

    string ftpPassword = "zzzzz";

    string ftpfullpath = "ftp://myserver.com/testme123.jpg";

    FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpfullpath);

    //userid and password for the ftp server  

    ftp.Credentials = new NetworkCredential(ftpUser, ftpPassword);

    ftp.KeepAlive = true;
    ftp.UseBinary = true;
    ftp.Method = WebRequestMethods.Ftp.UploadFile;

    FileStream fs = File.OpenRead(picture);

    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, buffer.Length);

    fs.Close();

    Stream ftpstream = ftp.GetRequestStream();
    ftpstream.Write(buffer, 0, buffer.Length);
    ftpstream.Close();
    ftpstream.Flush();

    //  fs.Flush();

}

我没有类型FileStream,WebRequestMethods和File,我的FtpWebRequest类也没有“KeepAlive”,“UseBinary”和“GetRequestStream”方法,而我的Stream类没有“Close”方法。

我的FtpWebRequest类:

public sealed class FtpWebRequest:WebRequest {public override string ContentType {get {throw new NotImplementedException(); }

    set
    {
        throw new NotImplementedException();
    }
}

public override WebHeaderCollection Headers
{
    get
    {
        throw new NotImplementedException();
    }

    set
    {
        throw new NotImplementedException();
    }
}

public override string Method
{
    get
    {
        throw new NotImplementedException();
    }

    set
    {
        throw new NotImplementedException();
    }
}

public override Uri RequestUri
{
    get
    {
        throw new NotImplementedException();
    }
}

public override void Abort()
{
    throw new NotImplementedException();
}

public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
{
    throw new NotImplementedException();
}

public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
{
    throw new NotImplementedException();
}

public override Stream EndGetRequestStream(IAsyncResult asyncResult)
{
    throw new NotImplementedException();
}

public override WebResponse EndGetResponse(IAsyncResult asyncResult)
{
    throw new NotImplementedException();
}

}

(我知道,我没有写任何东西,只按ctrl +。因为我不知道该写些什么)

有没有人能为我提供FtpWebRequest类的完整示例?我只发现上面这个使用的类。

答案

好吧,我只是想出了如何做到这一点,我将展示我是如何做到的,我真的不知道是否是更好,更正确的方法,但它确实有效。

首先,我必须在我的表单项目上创建一个名为IFtpWebRequest的接口类,其中包含以下内容:

namespace Contato_Vistoria
{
        public interface IFtpWebRequest
        {
            string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "");
        }
}

然后,在我的ios / droid项目中,我必须创建一个实现IFtpWebRequest的类caled FTP,并在该类中编写上传函数(我现在正在使用另一个),这里是整个FTP类:

using System;
using System.IO;
using System.Net;
using Contato_Vistoria.Droid; //My droid project

[assembly: Xamarin.Forms.Dependency(typeof(FTP))] //You need to put this on iOS/droid class or uwp/etc if you wrote
namespace Contato_Vistoria.Droid
{
    class FTP : IFtpWebRequest
    {
        public FTP() //I saw on Xamarin documentation that it's important to NOT pass any parameter on that constructor
        {
        }

        /// Upload File to Specified FTP Url with username and password and Upload Directory if need to upload in sub folders
        ///Base FtpUrl of FTP Server
        ///Local Filename to Upload
        ///Username of FTP Server
        ///Password of FTP Server
        ///[Optional]Specify sub Folder if any
        /// Status String from Server
        public string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "")
        {
            try
            {

                string PureFileName = new FileInfo(fileName).Name;
                String uploadUrl = String.Format("{0}{1}/{2}", FtpUrl, UploadDirectory, PureFileName);
                FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
                req.Proxy = null;
                req.Method = WebRequestMethods.Ftp.UploadFile;
                req.Credentials = new NetworkCredential(userName, password);
                req.UseBinary = true;
                req.UsePassive = true;
                byte[] data = File.ReadAllBytes(fileName);
                req.ContentLength = data.Length;
                Stream stream = req.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Close();
                FtpWebResponse res = (FtpWebResponse)req.GetResponse();
                return res.StatusDescription;

            }
            catch(Exception err)
            {
                return err.ToString();
            }
        }
    }
}

在我的iOS项目中它几乎是一样的,但无论如何我都会发布它来帮助像我这样不太了解的人,并且需要看到如何做到这一点的完整示例。这里是:

using System;
using System.Net;
using System.IO;
//Only thing that changes to droid class is that /
using Foundation;
using UIKit;
using Contato_Vistoria.iOS;


[assembly: Xamarin.Forms.Dependency(typeof(FTP))]
namespace Contato_Vistoria.iOS  //   /
{
    class FTP : IFtpWebRequest
    {
        public FTP()
        {

        }

        /// Upload File to Specified FTP Url with username and password and Upload Directory if need to upload in sub folders
        ///Base FtpUrl of FTP Server
        ///Local Filename to Upload
        ///Username of FTP Server
        ///Password of FTP Server
        ///[Optional]Specify sub Folder if any
        /// Status String from Server
        public string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "")
        {
            try
            {
                string PureFileName = new FileInfo(fileName).Name;
                String uploadUrl = String.Format("{0}{1}/{2}", FtpUrl, UploadDirectory, PureFileName);
                FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
                req.Proxy = null;
                req.Method = WebRequestMethods.Ftp.UploadFile;
                req.Credentials = new NetworkCredential(userName, password);
                req.UseBinary = true;
                req.UsePassive = true;
                byte[] data = File.ReadAllBytes(fileName);
                req.ContentLength = data.Length;
                Stream stream = req.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Close();
                FtpWebResponse res = (FtpWebResponse)req.GetResponse();
                return res.StatusDescription;

            }
            catch (Exception err)
            {
                return err.ToString();
            }
        }
    }
}

最后,回到我的Xamarin Forms项目,这就是我调用函数的方式。在我的GUI上按钮的简单点击事件中:

    protected async void btConcluidoClicked(object sender, EventArgs e)
    {
        if (Device.OS == TargetPlatform.android || Device.OS == TargetPlatform.iOS)
            await DisplayAlert("Upload", DependencyService.Get<IFtpWebRequest>().upload("ftp://ftp.swfwmd.state.fl.us", ((ListCarImagesViewModel)BindingContext).Items[0].Image, "Anonymous", "gabriel@icloud.com", "/pub/incoming"), "Ok");

        await Navigation.PopAsync();
    }

要调用该函数,您需要编写“DependencyService.Get()。YourFunction(函数的参数)”,以便更具体。

这就是我做到的,希望我能帮助别人。

以上是关于使用PCL Xamarin Forms将图像上载到FTP服务器的主要内容,如果未能解决你的问题,请参考以下文章

忽略 Xamarin.Forms (PCL) 中的 SSL 证书错误

我应该在 Xamarin.Forms 上使用哪些 SQLite (sqlite-net-pcl) 标志?

Xamarin.Forms PCL/SAP 自定义渲染,支持paintcode 3

有没有办法使用 Xamarin.Forms PCL 项目中的 Devexpress.Xamarin.Android.Charts

Xamarin.forms 使用 php 将图像上传到服务器目录

如何从 Xamarin.forms pcl 中的 Url 检索 json 字符串