从Azure Web App上传到Azure Blob存储时出现IO错误

时间:2018-08-15 12:57:51

标签: asp.net-mvc azure imageresizer azure-blob-storage

花了几个小时寻找答案后,我得出结论,这个问题需要重新关注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

1 个答案:

答案 0 :(得分:0)

您未指定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);
        }
        ....
    }