首页 > 解决方案 > 从 Azure Web 应用上传到 Azure Blob 存储时出现 IO 错误

问题描述

在花了几个小时寻找答案后,我得出结论,需要将问题重新集中在 Azure 存储连接字符串上

       <add key="yadayadayada_AzureStorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=yadayada;AccountKey=yoyoyoyo==;EndpointSuffix=core.windows.net" />

以及 ImageResizer 和 AzureReader2 的使用,它们也有一个连接字符串。其设置是:

     <resizer>
<pipeline defaultCommands="autorotate.default=true" />
<plugins>
  <add name="AzureReader2" connectionString="DefaultEndpointsProtocol=https;AccountName=accountname;AccountKey=acctkey==" endpoint="http://acctnumber.blob.core.windows.net/" prefix="~/azure" />
</plugins>

当我更改端点时,我会遇到不同的错误。当我将 azure 前缀更改为“~/”时,它会崩溃。

这是最初的问题,但我更确定地询问存储连接字符串应该是什么来授权上传到我的天蓝色网站。

这是最初的问题:从我的开发机器上传到 Azure blob 存储工作正常。但是,从已部署的(在 Azure 上)asp.net mvc 应用程序上传会出现此错误: System.IO.FileNotFoundException: 找不到文件 'D:\Windows\system32\ 我是否需要为应用程序建立写权限,如果又怎样?

还是我的代码有问题?

  private CloudBlobContainer GetCloudBlobContainer()
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                CloudConfigurationManager.GetSetting("accountidhere_AzureStorageConnectionString"));
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("FOLDER NAME HERE");
        return container;
    }


  public async Task<ActionResult> AddAnnouncementPhotos(AddPhotosViewModel vm, FormCollection fcoll)
    {
        if (ModelState.IsValid)

        {
            int theID = vm.ThePost.PostId;

            foreach (string fileName in Request.Files)
            {
                HttpPostedFileBase fb = Request.Files[fileName];

                string caption = fileName.Replace("File", "Photo");
                var phostring = caption + ".PhotoCaption";

                if (fb != null && fb.ContentLength > 0 && fb.ContentType.StartsWith("image"))
                {
                    string path = fb.FileName;

                    string ext = path.Substring(path.LastIndexOf("."));
                    string newname = Guid.NewGuid() + ext;

                    CloudBlobContainer container = GetCloudBlobContainer();

                    CloudBlockBlob blob = container.GetBlockBlobReference(newname);
                    blob.Properties.ContentType = fb.ContentType;

                    using (var fileStream = System.IO.File.OpenRead(path))
                    {
                        blob.UploadFromStream(fileStream);
                    }

添加堆栈跟踪:

        FileNotFoundException: Could not find file 'D:\Windows\system32\DSC02724.JPG'.]
   System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +519
   System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) +829
   System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) +65
   swIndWorkshop.Controllers.<AddAnnouncementPhotos>d__14.MoveNext() in C:\Users\JHstandard\Documents\aspnetProjects\swIndWorkshop\swIndWorkshop\Controllers\AnnouncementsController.cs:420
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +61
   System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
   System.Web.Mvc.Async.<>c__DisplayClass8_0.<BeginInvokeAsynchronousActionMethod>b__1(IAsyncResult asyncResult) +17
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__11_0() +50
   System.Web.Mvc.Async.<>c__DisplayClass11_1.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +228
   System.Web.Mvc.Async.<>c__DisplayClass7_0.<BeginInvokeActionMethodWithFilters>b__1(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass3_6.<BeginInvokeAction>b__3() +35
   System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__5(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +11
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +45
   System.Web.Mvc.<>c.<BeginExecute>b__151_2(IAsyncResult asyncResult, Controller controller) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +28
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +577
   System.Web.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0() +24
   System.Web.StepInvoker.Invoke(Action executionStep) +100
   System.Web.<>c__DisplayClass4_0.<Invoke>b__0() +17
   Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step) +64
   System.Web.<>c__DisplayClass284_0.<OnExecuteRequestStep>b__0(Action nextStepAction) +54
   System.Web.StepInvoker.Invoke(Action executionStep) +84
   System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +100
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163

标签: asp.net-mvcazureimageresizerazure-blob-storage

解决方案


您没有指定 中使用的整个路径var fileStream = System.IO.File.OpenRead(path),因此默认情况下它是当前目录。

在 Azure 上,进程当前工作目录是D:\Windows\system32\,我们无权写入,上传的文件也不在那里。

更新

  1. 建议使用 InputStream,这样我们就不必在 Web 服务器上保存文件了。

    只需替换System.IO.File.OpenRead(path)fb.InputStream.

  2. 要使用System.IO.File.OpenRead(path),需要在 if 段中进行一些修改。

    if (fb != null && fb.ContentLength > 0 && fb.ContentType.StartsWith("image"))
    {
        string path = fb.FileName;
        // add these two line to save file on web app server
        var wholePath = Path.Combine(Server.MapPath("~/"), path);
        fb.SaveAs(wholePath);
        .....
        using (var fileStream = System.IO.File.OpenRead(wholePath))
        {
            blob.UploadFromStream(fileStream);
        }
        ....
    }
    

推荐阅读