asp.net-mvc - 从 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
解决方案
您没有指定 中使用的整个路径var fileStream = System.IO.File.OpenRead(path)
,因此默认情况下它是当前目录。
在 Azure 上,进程当前工作目录是D:\Windows\system32\
,我们无权写入,上传的文件也不在那里。
更新
建议使用 InputStream,这样我们就不必在 Web 服务器上保存文件了。
只需替换
System.IO.File.OpenRead(path)
为fb.InputStream
.要使用
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); } .... }
推荐阅读
- karate - 如何为来自数组的每个 json 请求多次调用端点
- c++ - 为构造构造函数声明相同的结构 2 次有什么用?
- python - 如果在扫描 qrcode 后得到相同类型的盒子,我如何增加相同类型盒子的计数?
- kotlin - forEach { } 会自动关闭流吗?
- git - 显示多个提交的“压缩差异”
- android - 无需重新引入即可重新连接到 NFC TAG
- regression - 使用 xarray 对 netCDF 数据进行单变量回归
- mongodb - 在 mongodb 中加入多个表以从另一个表中获取 id 值数组
- python - 如何从单个数组中拆分两个元素?
- c++ - 如何为具有自定义类型的 std::vector 创建显式模板实例化声明?