C# - 如何将文件上传到 Azure 存储 Blob(未知物理路径)

C# - How to upload files to Azure Storage Blob (unknown phisic path)

在我的网络应用程序中,我需要允许用户从他们的机器上选择一个图像并上传它,并将该图像物理存储到我的容器中32=]存储 在 Azure 中。

我在很多地方都找到了这样做的方法,它对我有用,但是 重要例外 在所有示例中,他们都从自己的机器上传文件并了解或编码物理路径。

但是出于安全考虑,输入文件无法读取客户端的物理地址,我只好使用了策略:

  1. 我将图像上传到网络服务器的已知路径。
  2. 我走那条路,我用它上传到 Azure 存储 Blob。
  3. 已确认,我不希望该文件保留在服务器上,我只希望它在我的容器中, 所以我继续删除文件。
  4. 我得到以下异常:

The process cannot access the file. 'C:\My_folders\MyFile.jpg' because it is being used by another process.

注意:我尝试使用项目目录和操作系统的临时目录。对于这两种情况,我得到相同的结果。

所以,总而言之:我需要上传到 Azure S Blob,但据我所知,为此我需要文件的物理路径,所以我需要将它上传到我的服务器,然后从那里上传。

我希望你能帮助我做出这些选择:

  1. 能够在没有物理路径的情况下上传它。 或者能够关闭我现在的进程,确保删除服务器上的临时文件。
  2. 您的任何建议。

非常感谢! _________________________代码________________________ 前面

<form method="POST" enctype="multipart/form-data" id="fileUploadForm">
<div class="row">
        <div class="col-md-12" id="conten_CargaImagenes">
            <div class="card card-success">
                <div class="card-header">
                    <h3 class="card-title" id="tituloAbmHorarios">
                        <i class="far fa-image"></i> Nueva Imagen
                    </h3>
                </div>
                
                <div class="card-body">
                    <div class="row">

                        <div class="col-md-12">
                            <div class="form-group">
                                <input asp-for="File" class="form-control custom-file-input" />
                                <label id="fileImageLabel" asp-for="File" class="custom-file-label "></label>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <button type="button" class="btn bg-gradient-success btn-sm pull-left" onclick="GuardarImagen()">
                                <i class="fas fa-file-upload"></i> Grabar Imagen
                            </button>
                        </div>

                    </div>
                </div>
            </div>
        </div>
</div>

JS 方法

function GuardarImagen() {

    var form = $('#fileUploadForm')[0];

    var model = new FormData(form);
    model.append('IdComercio', $('#Id').val());

    $.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/Comercios/GrabaFile",
        data: model,
        processData: false,
        contentType: false,
        cache: false,
        timeout: 600000,
        success: function (e) {

            if (!e.isError) {
                $("#File").val(null);
                document.getElementById("fileImageLabel").innerHTML = '';

                toastr.success(textos.imagenGrabadaOk, { timeOut: 2000 });
                InjectarNuevaImagenEnPantalla(e.data);
            } else {
                toastr.error(e.data, { timeOut: 2000 });
            }
        }
    });
}

返回

[HttpPost]
        public ReturnData GrabaFile(UploadFileComercioDTO pData)
        {

            if (pData.File != null)
            {
                try
                {
                    var result = UploaderFilesService.UploadToAzure(pData.File, FolderPath, pData.IdComercio.ToString());
                    
                }
                catch (Exception ex)
                {
                    do something...
                }
            }
            else
            {
                return messageError
            }
        }


public static ReturnData UploadToAzure(IFormFile pFile, string pFolder, string pIdComercio)
        {
            ReturnData returnData = new();

            if (pFile != null)
            {
                if (ValidaFile(pFile.ContentType, pFile.Length))
                {
                    try
                    {
                        string nombreOriginal = pFile.FileName;
                        var nombrePartes = nombreOriginal.Split(".");
                        string extension = nombrePartes[(nombrePartes.Length - 1)];

                        string nombreFinal = GenerarTextoUnico() + "." + extension;
                        string soloNOmbre = nombreFinal; // ****

                        pFolder = Path.GetTempPath(); // *************
                        string filePath = Path.Combine(pFolder, nombreFinal);

                        using (var stream = File.Create(filePath))
                        {
                            pFile.CopyTo(stream);
                        }

                        string connectionString = "adsfasfasdfasdf";
                        string containerName = "asdfasdf";

                        nombreFinal = pIdComercio + "/" + nombreFinal;

                        BlobContainerClient container = new BlobContainerClient(connectionString, containerName);
                        var upload = container.UploadBlob(nombreFinal, File.OpenRead(filePath));

                        try
                        {
                            File.Delete(filePath);
                        }
                        catch (IOException e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }
                    catch (Exception ex)
                    {
                        ...
                    }
                }
                else
                {
                    ...
                }
            }
            else
            {
                ...
            }

            return returnData;
        }

我找到了问题和解决方案。

问题是上传时没有关闭流。

要进行的修改是在 UploadToAzure 方法中,更改以下行

var upload = container.UploadBlob(finalName, File.OpenRead(filePath));

为此

using (var stream = File.OpenRead(filePath))
{
   var upload = container.UploadBlob(endName, stream);
}

那样当我退出时 使用 流已经关闭,我可以继续删除它。