繁体   English   中英

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

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

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

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

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

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

该进程无法访问该文件。 'C:\My_folders\MyFile.jpg' 因为它正被另一个进程使用。

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

所以,总而言之:我需要上传到 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;
        }

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

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

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

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

为了这

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM