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

本地可正常保存带图片用户,Azure环境下失败求修复方案

Azure部署后文件上传失败问题排查与解决

问题描述

本地环境中,以下Create方法和UploadFile方法运行正常,用户数据和图片均能保存到wwwroot目录;但部署到Azure App Service后,选择图片上传时用户数据和图片都无法保存,不选择图片自动使用placeholder.png时,用户数据可以正常保存。生产环境无错误提示,提交后直接跳转至Index页面。

Create方法代码

public PatientViewModel Create(PatientViewModel model)
{
    try
    {
        model.patient!.photoPath = (model.file != null) ? UploadFile(model.file) : "placeholder.png";
        model.patient.appUser = appuserAwhole(model);
        model.patient.appUser.user = (!model.mode) ? model.user : model.Users!.Where(r => r.userId == model.userid).First();
        _idb.patients.Add(model.patient);
        idbSaveChanges();
        Patientfile pf = new Patientfile();
        pf.patientMail = model.patient.emailAddress;
        _fdb.patientfiles.Add(pf);
        fdbSaveChanges();
    }
    catch (Exception e) {
        System.Diagnostics.Debug.WriteLine(e.Message);
    }
    return model;
}

UploadFile方法代码

private string UploadFile(IFormFile photo)
{
    string wwwPath = this._env.WebRootPath;
    string contentPath = this._env.ContentRootPath;

    string path = Path.Combine(wwwPath, "img\\PatientPhotos");
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }

    if (photo == null)
    {
        return "default.png";
    }
    string fileName = Path.GetFileName(photo.FileName);
    using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
    {
        photo.CopyTo(stream);
    }

    return fileName;
}

控制器跳转代码

_db.Create(vm);
return RedirectToAction("Index");

解决步骤

  • 修复路径分隔符问题
    代码中硬编码了Windows风格的反斜杠\\,但Azure App Service默认使用Linux容器,路径分隔符为正斜杠。统一用Path.Combine拼接路径,避免跨平台问题:

    string path = Path.Combine(wwwPath, "img", "PatientPhotos");
    
  • 调整文件存储位置
    Azure App Service的wwwroot目录默认是只读的,直接写入会触发权限错误。建议:

    1. 使用Azure临时目录:路径可通过Path.GetTempPath()获取,但临时文件会在App Service重启后丢失;
    2. 使用App_Data目录:通过Path.Combine(_env.ContentRootPath, "App_Data", "PatientPhotos")拼接路径,需确保目录存在并配置写入权限;
    3. 推荐方案:改用Azure Blob Storage存储图片,实现持久化存储(代码示例见下文)。
  • 完善异常日志
    当前catch块仅输出Debug日志,生产环境无法查看。改用ILogger记录异常,便于排查问题:

    private readonly ILogger<YourController> _logger;
    
    // 构造函数注入ILogger
    public YourController(ILogger<YourController> logger)
    {
        _logger = logger;
    }
    
    // 修改catch块
    catch (Exception e)
    {
        _logger.LogError(e, "创建患者记录或上传图片时发生错误");
        // 可选择抛出异常,让上层处理或返回错误页面
        throw;
    }
    
  • 改用Azure Blob Storage存储图片
    长期来看,Azure App Service本地存储不适合持久化文件,推荐使用Blob Storage:

    1. 安装Azure.Storage.Blobs NuGet包;
    2. 在Azure Portal中创建Blob存储容器,并将连接字符串添加到App Service的应用设置中(键名如BlobConnectionString);
    3. 修改UploadFile方法:
      private async Task<string> UploadFile(IFormFile photo)
      {
          if (photo == null) return "placeholder.png";
      
          var blobServiceClient = new BlobServiceClient(Environment.GetEnvironmentVariable("BlobConnectionString"));
          var containerClient = blobServiceClient.GetBlobContainerClient("patient-photos");
          await containerClient.CreateIfNotExistsAsync(PublicAccessType.Blob);
      
          // 生成唯一文件名,避免冲突
          var blobName = $"{Guid.NewGuid()}{Path.GetExtension(photo.FileName)}";
          var blobClient = containerClient.GetBlobClient(blobName);
      
          using var stream = photo.OpenReadStream();
          await blobClient.UploadAsync(stream, new BlobUploadOptions
          {
              HttpHeaders = new BlobHttpHeaders { ContentType = photo.ContentType }
          });
      
          return blobClient.Uri.ToString();
      }
      
  • 检查文件上传大小限制
    Azure App Service默认限制上传文件大小为30MB,若图片超出此限制会失败。在Program.cs中配置更大的限制:

    builder.Services.Configure<FormOptions>(options =>
    {
        options.MultipartBodyLengthLimit = 104857600; // 设置为100MB
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:05:33