c# - 从 ASP.NET 上传到 Azure blob 的文件为空

标签 c# asp.net-mvc azure file-upload azure-storage

我不确定到底是什么问题。我正在开发一个简单的测试,即将图像上传到我的 Azure 存储。但是,该文件存在,但在存储上为空。好像上传失败,我不明白为什么。我有这个 Controller :

创建.cshtml.cs

namespace CoreWebApp.Pages
{
    public class CreateModel : PageModel
    {
        public void OnGet()
        {
        }

        [BindProperty]
        public CountryForm Country { get; set; }

        [HttpPost("CreateCountry")]
        public async Task<IActionResult> OnPostAsync(IFormFile file)
        {
            if (!ModelState.IsValid)
                return Page();

            /*var errors = ModelState.Where(x => x.Value.Errors.Count > 0)
                                    .Select(x => new { x.Key, x.Value.Errors })
                                    .ToArray();*/

            var filePath = Path.GetTempFileName();
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);

                string pictureUrl = Shared.AzureCloud.AzureCDN.GetAzureCDNInstance().UploadFile(stream, file.Name);
                try
                {
                    if (pictureUrl != null)
                        Shared.Database.SqlAction.CountriesTable.AddCountry(new Country()
                        {
                            Name = Country.Name,
                            PictureUrl = pictureUrl
                        });
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }

            return Page();
        }
    }
}

创建.cshtml

@page
@model CreateModel
@{
    ViewData["Title"] = "Create";    
}

<div class="container">
  <div class="row">
    <div class="col-lg-3" style="background-color:#FF0000;">
        <h4>Add a Country</h4>
        <form class="form form-horizontal" method="post" enctype="multipart/form-data" asp-controller="Create">
          <div asp-validation-summary="All"></div>
          <div class="row">
            <div class="col-md-12">
              <div class="form-group">
                <label asp-for="Country.Name" class="col-md-3 right">Name:</label>
                <div class="col-md-9">
                  <input asp-for="Country.Name" class="form-control" />
                  <span asp-validation-for="Country.Name"></span>
                </div>
              </div>
              <div class="form-group">
                <div class="col-md-10">
                    <p>Picture</p>
                    <input type="file" name="file" />
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-md-12">
              <button type="submit">Create</button>
            </div>
          </div>
        </form>
    </div>
    <div class="col-*-*"></div>
  </div>
  <div class="row">
    <div class="col-*-*"></div>
    <div class="col-*-*"></div>
    <div class="col-*-*"></div>
  </div>
  <div class="row">
    ...
  </div>
</div>

我的AzureCDN类只是一个封装:

namespace Shared.AzureCloud
{
    public class AzureCDN
    {
        private CloudStorageAccount storageAccount { get; set; }
        private CloudBlobClient blobClient { get; set; }
        private CloudBlobContainer container { get; set; }
        private CloudBlockBlob blockBlob { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:Shared.AzureCloud.AzureCDN"/> class.
        /// </summary>
        public AzureCDN()
        {
            // Retrieve storage account from connection string.
            storageAccount = CloudStorageAccount.Parse(String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                                                                                         Shared.Constants.Azure.AccountName, Shared.Constants.Azure.AccountKey));
            // Create the blob client.
            blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve a reference to a container.
            container = blobClient.GetContainerReference("eyesmedias");

            // Create the container if it doesn't already exist.
            container.CreateIfNotExistsAsync();
        }

        /// <summary>
        /// Uploads the file.
        /// </summary>
        /// <returns>The file.</returns>
        /// <param name="fileStream">File stream.</param>
        /// <param name="fileName">File name.</param>
        public string UploadFile(FileStream fileStream, string fileName)
        {
            // Retrieve reference to a blob named {name}.
            blockBlob = container.GetBlockBlobReference(fileName);

            try
            {
                // Create or overwrite the {name} "blob with contents from a local file.
                blockBlob.UploadFromStreamAsync(fileStream);
                return (blockBlob.Uri.ToString());

            } catch (Exception e)
            {
                throw e;
            }
        }

        #region Singletown part

        /// <summary>
        /// The instance.
        /// </summary>
        private static AzureCDN Instance = null;

        /// <summary>
        /// Gets the azure CDN Instance.
        /// </summary>
        /// <returns>The azure CDNI nstance.</returns>
        public static AzureCDN GetAzureCDNInstance()
        {
            if (Instance == null)
            {
                Instance = new AzureCDN();
            }
            return (Instance);
        }

        /// <summary>
        /// Sets the azure CDN Instance.
        /// </summary>
        /// <param name="instance">Instance.</param>
        public static void SetAzureCDNInstance(AzureCDN instance)
        {
            Instance = instance;
        }

        /// <summary>
        /// Init this instance.
        /// </summary>
        public static void Init()
        {
            Instance = new AzureCDN();
        }

        #endregion
    }
}

问题是,blockBlob.UploadFromStreamAsync(fileStream); 似乎没问题,因为它不会引发任何异常,并且路径会很好地返回,但是,即使文件位于我的 CDN 上,它是空的,与我在 Mac 上从 ASP.NET 页面选择的文件不同。

我对 ASP.NET 还很陌生(我是 2 天前开始的),也欢迎有关从 Web 应用程序 ASP.NET 上传文件的建议:)

感谢您的帮助!

最佳答案

将文件复制到流后,必须使用 stream.Seek(0, SeekOrigin.Begin); 再次将流的位置设置为开头;(请参阅 docs )因此将上传实际内容:

        [HttpPost("CreateCountry")]
        public async Task<IActionResult> OnPostAsync(IFormFile file)
        {
            if (!ModelState.IsValid)
                return Page();

            /*var errors = ModelState.Where(x => x.Value.Errors.Count > 0)
                                    .Select(x => new { x.Key, x.Value.Errors })
                                    .ToArray();*/

            var filePath = Path.GetTempFileName();
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);

                stream.Seek(0, SeekOrigin.Begin); 

                string pictureUrl = Shared.AzureCloud.AzureCDN.GetAzureCDNInstance().UploadFile(stream, file.Name);
                try
                {
                    if (pictureUrl != null)
                        Shared.Database.SqlAction.CountriesTable.AddCountry(new Country()
                        {
                            Name = Country.Name,
                            PictureUrl = pictureUrl
                        });
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }

            return Page();
        }

如果您不这样做,那么您上传的流中当前位置已经位于末尾,因此将上传一个空文件。

关于c# - 从 ASP.NET 上传到 Azure blob 的文件为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47608947/

相关文章:

c# - 将 UInt32 转换为 Int32 : Different compiler results

c# - 在 MVC Core 应用程序中使用 AddAzureADB2C 时向 ClaimsPrincipal 添加自定义声明

asp.net-mvc - MVC Web 应用程序应该是 3 层吗?

visual-studio - 无法使用 Visual Studio 访问 Azure SQL 数据库,但可以使用 SSMS

c# - 从 C# SyndicationFeed 读取所有 rss 项目

jquery - 使用jquery获取同名下拉菜单的值

asp.net-mvc - MVC 中的打印页面功能

azure - 有没有办法在 Azure DevOps 测试结果选项卡中显示 Cypress 测试结果?

python - 无法从 az cli 部署 python 应用程序

c# - 使用字段掩码并强制光标向左