You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#:替代过时FtpWebRequest实现FTP文件上传的方案

FTP文件上传:替代过时FtpWebRequest的解决方案

问题背景

需要通过FTP协议将本地文件复制到本地或远程文件夹,原使用FtpWebRequest的代码已被标记为过时,公司要求改用HttpClient,但尝试用MultipartFormDataContent实现时发现HttpClient不支持FTP协议,最终通过第三方库FluentFTP解决问题。


原过时代码(基于FtpWebRequest)

[Obsolete("Obsolete")]
private async Task UploadFile(FileDescriptionModel descriptionModel, FtpConfigModel configModel)
{
    try
    {
        var filePath = $"ftp://{configModel.Ip}:{configModel.Port}/{descriptionModel.RelativePath}";
        _logger.LogInformation("Started creating file");
        using var ms = new MemoryStream(await File.ReadAllBytesAsync(descriptionModel.FilePath));

        ms.Position = 0;
        ms.ToArray();
        _logger.LogInformation("Started connection to {ipPath}", filePath);
        var ftpWebRequest = (FtpWebRequest)WebRequest.Create(filePath);
        ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
        ftpWebRequest.Credentials = new NetworkCredential(configModel.User, configModel.Password);
        // convert contents to byte.
        await using Stream requestStream = ftpWebRequest.GetRequestStream();
        _logger.LogInformation("Started uploading");
        await ms.CopyToAsync(requestStream);
        _logger.LogInformation("Finished uploading");
    }
    catch (Exception e)
    {
        _logger.LogError("Stream cannot be read", e);
        throw;
    }
}

尝试的HttpClient方案(无法运行)

此方案失败的核心原因是:HttpClient仅支持HTTP/HTTPS协议,无法处理FTP请求,调用PostAsync传入ftp://开头的地址会直接报错。

private async Task<string> UploadFile2(FileDescriptionModel descriptionModel, FtpConfigModel configModel)
{
    var filePath = $"ftp://{configModel.Ip}:{configModel.Port}/{descriptionModel.RelativePath}";
    var httpClient = new HttpClient();
    httpClient.SetBasicAuthentication(configModel.User, configModel.Password);
    using (var multipartFormContent = new MultipartFormDataContent())
    {
        //Add other fields
        using var ms = new MemoryStream(await File.ReadAllBytesAsync(descriptionModel.FilePath));
        multipartFormContent.Add(new ByteArrayContent(ms.ToArray()), name: "SomeName", fileName: descriptionModel.RelativePath);

        //Send it
        var response = await httpClient.PostAsync(filePath, multipartFormContent);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

最终可行方案(基于FluentFTP)

使用第三方库FluentFTP,它专门针对FTP协议封装了简洁的API,支持异步操作,且无需手动处理复杂的FTP连接逻辑。

private async Task UploadFile3(FileDescriptionModel descriptionModel, FtpConfigModel configModel)
{
    var client = new AsyncFtpClient(configModel.Ip, configModel.User, configModel.Password,
        configModel.Port);

    // 连接服务器并自动检测适配的FTP设置
    await client.AutoConnect();

    // 上传文件
    var status = await client.UploadFile(descriptionModel.FilePath, $"{descriptionModel.RelativePath}");
}

内容的提问来源于stack exchange,提问作者Aleksandar Trifunović

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:53:17