2017-06-12 51 views
0

我們正在使用SAS密鑰從我們的Azure服務器訪問文件。鏈接使用ASP.NET控制器檢索並使用HTML元素顯示。僅鏈接到Azure存儲資源第一次工作

我們第一次請求鏈接時,圖片顯示完美。第二次請求圖像(例如,頁面刷新)時,它們不顯示 - 控制檯狀態403文件找不到圖像。如果我們將鏈接從HTML元素複製到新的瀏覽器選項卡中,則圖像顯示出來。

有沒有人有這個問題的經驗?

謝謝。

控制器

// GET: /<controller>/edit 
    public async Task<IActionResult> Edit(int id) 
    { 

     Checklist checklist = await AM.Checklist.FindAsync(id); 

     if (checklist == null) 
     { 
      return StatusCode(404); 
     } 

     ChecklistViewModel cVM = new ChecklistViewModel(checklist); 

     cVM.productPartNum = (await AM.Product.FindAsync(checklist.productNum)).partId; 
     cVM.checklistTypesDropdown = await cVM.GetChecklistOptions(AM); 
     List<Field> fields = await AM.Field.Where(x => x.checklistId == checklist.id).OrderBy(x=>x.section).ThenBy(x=>x.order).ToListAsync(); 




     //connect to the file storate account 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); 

     // Create a CloudFileClient object for credentialed access to File storage. 
     CloudFileClient fileClient = storageAccount.CreateCloudFileClient(); 

     // Get a reference to the file share 
     CloudFileShare share = fileClient.GetShareReference("newfileshare"); 


     string policyName = "sampleSharePolicy" + DateTime.UtcNow.Ticks; 
     CloudFileDirectory rootDir = null; 
     CloudFileDirectory fileDir = null; 

     // Ensure that the share exists. 
     if (share.Exists()) 
     { 


      // Create a new shared access policy and define its constraints. 
      SharedAccessFilePolicy sharedPolicy = new SharedAccessFilePolicy() 
      { 
       SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5), 
       SharedAccessExpiryTime = DateTime.UtcNow.AddHours(8), 
       Permissions = SharedAccessFilePermissions.Read | SharedAccessFilePermissions.Write 
      }; 

      // Get existing permissions for the share. 
      FileSharePermissions permissions = await share.GetPermissionsAsync(); 

      //Check length of SharedAccessPolicies 
      if (permissions.SharedAccessPolicies.Count >= 5) 
      { 
       permissions.SharedAccessPolicies.Remove(permissions.SharedAccessPolicies.Keys.First()); 
      } 

      // Add the shared access policy to the share's policies. Note that each policy must have a unique name. 
      permissions.SharedAccessPolicies.Add(policyName, sharedPolicy); 
      await share.SetPermissionsAsync(permissions); 

      // Generate a SAS for a file in the share and associate this access policy with it. 
      rootDir = share.GetRootDirectoryReference(); 
     } 



     cVM.changeHappened = new List<bool>(); 

     cVM.Fields = new List<FieldViewModel>(); 
     int i = 0; 
     foreach(Field f in fields) 
     { 
      FieldViewModel newFVM = new FieldViewModel(f); 

      cVM.changeHappened.Add(false); 

      if (f.attachmentReq && f.attachmentData != null) 
      { 

       //changeHappened will keep track of what images have been changed in order to avoid resubmitting same images 
       cVM.changeHappened.Add(false); 



       if (f.attachmentType.Contains("image")) 
       { 
        fileDir = rootDir.GetDirectoryReference("Images"); 
       } 
       else 
       { 
        fileDir = rootDir.GetDirectoryReference("files"); 
       } 

       CloudFile file = fileDir.GetFileReference(f.attachmentData); 
       string sasToken = file.GetSharedAccessSignature(null, policyName); 
       string tick = $"&{ DateTimeOffset.UtcNow.Ticks}"; 
       Uri fileSasUri = new Uri(file.StorageUri.PrimaryUri.ToString() + sasToken + tick); 

       newFVM.link = fileSasUri.AbsoluteUri; 

       //// Create a new CloudFile object from the SAS, and write some text to the file. 
       //CloudFile fileSas = new CloudFile(fileSasUri); 
       //fileSas.UploadText("This write operation is authenticated via SAS."); 
       //Console.WriteLine(fileSas.DownloadText()); 
      } 



      if (newFVM.textReq) 
      { 
       newFVM.fieldDropdownOptions = await newFVM.getDropdownOptions(AM); 
      } 

      cVM.Fields.Add(newFVM); 
     } 

     return View(cVM); 
    } 

事業部,顯示圖像

         <div class="col-sm-5"> 


              @if (Model.Fields[i].attachmentData != null) 
              { 
               @if (Model.Fields[i].attachmentType.Contains("image/")) 
               { 

                <img src="@Model.Fields[i].link" id="[email protected]" height="50" width="50" align="middle"/> 
                <a hidden="hidden" id="[email protected]"></a> 
               } 
               else 
               { 
                <img hidden="hidden" id="[email protected]" height="50" width="50" align="middle"/> 
                <a id="[email protected]">@Model.Fields[i].attachmentData</a> 
               } 

              } 
              else 
              { 
               <img hidden="hidden" id="[email protected]" height="50" width="50" align="middle"/> 
               <a hidden="hidden" id="[email protected]"></a> 
              } 

             </div> 

回答

1

根據你的描述和代碼,我已複製了問題。

我猜你面對403錯誤的原因是你的MVC代碼發送請求到文件存儲之前,文件存儲已經設置並啓用權限的SharedAccessPolicies。

所以它會返回403禁止的錯誤,說你的SAS令牌是無用的。

再說,我不建議你添加SharedAccessPolicies每一次,因爲如果6個人在同一時間訪問您的網站,第一個人的SharedAccessPolicies可能會被刪除。所以第一個人無法獲得文件圖像。

我建議你可以使用一個SharedAccessPolicies。

您可以每次重置SharedAccessFilePolicy的SharedAccessExpiryTime。

更多細節,你可以參考下面的代碼示例:

//connect to the file storate account 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(" "); 

    // Create a CloudFileClient object for credentialed access to File storage. 
    CloudFileClient fileClient = storageAccount.CreateCloudFileClient(); 

    // Get a reference to the file share 
    CloudFileShare share = fileClient.GetShareReference("brandofirstsharetest"); 


    string policyName = "sampleSharePolicy" + DateTime.UtcNow.Ticks; 
    CloudFileDirectory rootDir = null; 
    CloudFileDirectory fileDir = null; 

    // Ensure that the share exists. 
    if (share.Exists()) 
    { 

     // Get existing permissions for the share. 
     FileSharePermissions permissions = await share.GetPermissionsAsync(); 
     //if the SharedAccessPolicies is exists just get the SharedAccessPolicies 
     if (permissions.SharedAccessPolicies.Count > 0) 
     { 
       policyName = permissions.SharedAccessPolicies.First().Key; 
       SharedAccessFilePolicy sharedPolicy = permissions.SharedAccessPolicies.First().Value; 
       sharedPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(8); 
       await share.SetPermissionsAsync(permissions);     
     } 
     else 
     { 
      // Create a new shared access policy and define its constraints. 
      SharedAccessFilePolicy sharedPolicy = new SharedAccessFilePolicy() 
      { 
       SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15), 
       SharedAccessExpiryTime = DateTime.UtcNow.AddHours(8), 
       Permissions = SharedAccessFilePermissions.Read | SharedAccessFilePermissions.Write 
      }; 
      permissions.SharedAccessPolicies.Add(policyName, sharedPolicy); 
      await share.SetPermissionsAsync(permissions); 
     } 


     // Add the shared access policy to the share's policies. Note that each policy must have a unique name. 


     // Generate a SAS for a file in the share and associate this access policy with it. 
     rootDir = share.GetRootDirectoryReference(); 
    } 

    CloudFile file = rootDir.GetFileReference("Penjs.png"); 
     string sasToken = file.GetSharedAccessSignature(null, policyName); 
     string tick = $"&{ DateTimeOffset.UtcNow.Ticks}"; 
     Uri fileSasUri = new Uri(file.StorageUri.PrimaryUri.ToString() + sasToken + tick);