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

EF Core中上传IFormFile到FTP服务器路径错误问题排查求助

问题排查

  • 路径传参错误:Handler里传给ImageUpload的path是@"\Image\Slider\"文件夹路径,不是具体文件路径。调用Path.GetFileName(path)只能拿到空值,导致FTP拼接的URL非法,同时File.OpenRead(path)尝试读取文件夹而非文件,直接触发路径错误。
  • IFormFile未落地:拿到前端上传的IFormFile对象后,没有先将文件内容写入本地对应路径,直接尝试读取不存在的本地文件,必然报错。
  • 返回值逻辑错误:ImageUpload方法固定返回null,会导致后续string.IsNullOrEmpty判断永远命中,直接返回文件类型不支持的错误,逻辑完全失效。
  • 空判断顺序错误:在调用_mapper.Map之后、使用mapped对象之后才判断mapped == null,顺序完全颠倒,就算映射失败也会先触发空引用异常。
  • FTP地址不完整:代码里写的@"cdnadress"不是合法的FTP地址前缀,需要补全ftp://开头的完整FTP服务地址。

提示:测试时请先确认FTP服务可以正常连接、对应目录有读写权限,同时替换代码中占位的FTP地址、账号密码、CDN前缀为实际业务值。


修复后的FileUpload扩展方法

public static class FileUpload
{
    public static string ImageUpload(this IFormFile file, string directoryPath)
    {
        // 目录不存在则自动创建
        if (!Directory.Exists(directoryPath))
        {
            Directory.CreateDirectory(directoryPath);
        }
        // 生成不重名的文件名,避免覆盖旧文件
        var fileName = $"{Guid.NewGuid()}_{Path.GetFileName(file.FileName)}";
        var fullLocalPath = Path.Combine(directoryPath, fileName);
        
        // 将前端上传的文件写入本地路径
        using (var localStream = new FileStream(fullLocalPath, FileMode.Create))
        {
            file.CopyTo(localStream);
        }

        // 拼接合法FTP地址,注意补全ftp://前缀
        var ftpUrl = @"ftp://替换为你的FTP服务地址/" + fileName;
        FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(ftpUrl);

        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.Credentials = new NetworkCredential("替换为FTP用户名", "替换为FTP密码");
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = true;

        // 读取本地文件上传到FTP
        byte[] buffer;
        using (FileStream stream = File.OpenRead(fullLocalPath))
        {
            buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
        }

        using (Stream reqStream = request.GetRequestStream())
        {
            reqStream.Write(buffer, 0, buffer.Length);
        }

        // 返回可访问的资源地址,用CDN的话替换为CDN前缀即可
        return ftpUrl;
    }
}

修复后的SliderCreateHandler代码

public class SliderCreateHandler :
    IRequestHandler<SliderCreate, ApiResponse<SliderResponse>>
{
    private readonly IUnitOfWork _repo;
    private readonly IMapper _mapper;

    public SliderCreateHandler(IUnitOfWork repo, IMapper mapper)
    {
        _repo = repo;
        _mapper = mapper;
    }

    public async Task<ApiResponse<SliderResponse>> Handle(
        SliderCreate request, CancellationToken cancellationToken)
    { 
        // 先判断映射结果是否为空,再执行后续操作
        var mapped = _mapper.Map<Slider>(request);
        if (mapped == null)
            return new ErrorApiResponse<SliderResponse>(ResultMessage.NotCreatedSlider);

        var path = Path.Combine(Environment.CurrentDirectory, @"Image\Slider\");
        mapped.ImageUrl = request.file.ImageUpload(path);

        if (string.IsNullOrEmpty(mapped.ImageUrl)) 
            return new ErrorApiResponse<SliderResponse>(ResultMessage.UnsupportedFileType);

        var model = await _repo.Sliders.AddAsync(mapped);
        var response = _mapper.Map<SliderResponse>(model);

        return new SuccessApiResponse<SliderResponse>(response);
    }
}

内容的提问来源于stack exchange,提问作者user16695025

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:15:07