使用 PCL Xamarin Forms 将图像上传到 FTP 服务器
Upload image to a FTP Server using PCL Xamarin Forms
我是 Xamarin 和 C# 世界的新手,我正在尝试将图像上传到 FTP 服务器。我看到 FtpWebRequest class 可以做到这一点,但我没有做对,我不知道如何注入特定于平台的代码,我什至不知道它的真正含义,已经看过这个视频(https://www.youtube.com/watch?feature=player_embedded&v=yduxdUCKU1c) 但我不知道如何使用它来创建 FtpWebRequest class 并上传图像。
我看到这个代码(这里: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 class 也没有 "KeepAlive"、"UseBinary" 和 "GetRequestStream" 方法,并且我的 Stream class 没有 "Close" 方法。
我的 FtpWebRequest Class:
public 密封 class FtpWebRequest : WebRequest
{
public 覆盖字符串内容类型
{
得到
{
抛出新的 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 示例 class?我只发现 class 像上面这样使用。
好的,我刚刚想出了如何做到这一点,我会展示我是怎么做的,我真的不知道这是否是更好和正确的方法,但它有效。
首先,我必须在我的表单项目上创建一个名为 IFtpWebRequest 的接口Class,它包含以下内容:
namespace Contato_Vistoria
{
public interface IFtpWebRequest
{
string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "");
}
}
然后,在我的 iOS/droid 项目中,我必须创建一个 class caled FTP 来实现 IFtpWebRequest 并在那个 class 中编写上传函数(我'我现在正在使用另一个),这是整个 FTP class:
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 项目几乎相同,但我还是会 post 帮助那些像我这样不太了解并且需要查看完整示例的人去做吧。这是:
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(Parameters of the function)",更具体。
我就是这样做的,希望我能帮助到别人。
我是 Xamarin 和 C# 世界的新手,我正在尝试将图像上传到 FTP 服务器。我看到 FtpWebRequest class 可以做到这一点,但我没有做对,我不知道如何注入特定于平台的代码,我什至不知道它的真正含义,已经看过这个视频(https://www.youtube.com/watch?feature=player_embedded&v=yduxdUCKU1c) 但我不知道如何使用它来创建 FtpWebRequest class 并上传图像。
我看到这个代码(这里: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 class 也没有 "KeepAlive"、"UseBinary" 和 "GetRequestStream" 方法,并且我的 Stream class 没有 "Close" 方法。
我的 FtpWebRequest Class:
public 密封 class FtpWebRequest : WebRequest { public 覆盖字符串内容类型 { 得到 { 抛出新的 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 示例 class?我只发现 class 像上面这样使用。
好的,我刚刚想出了如何做到这一点,我会展示我是怎么做的,我真的不知道这是否是更好和正确的方法,但它有效。
首先,我必须在我的表单项目上创建一个名为 IFtpWebRequest 的接口Class,它包含以下内容:
namespace Contato_Vistoria
{
public interface IFtpWebRequest
{
string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "");
}
}
然后,在我的 iOS/droid 项目中,我必须创建一个 class caled FTP 来实现 IFtpWebRequest 并在那个 class 中编写上传函数(我'我现在正在使用另一个),这是整个 FTP class:
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 项目几乎相同,但我还是会 post 帮助那些像我这样不太了解并且需要查看完整示例的人去做吧。这是:
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(Parameters of the function)",更具体。
我就是这样做的,希望我能帮助到别人。