2017-12-02 14 views
0

何が問題なのか分かりません。私はAzureストレージに画像をアップロードする簡単なテストを開発しています。ただし、ファイルは存在しますが、ストレージ上ではnullです。アップロードがうまくいかず、理由がわからないようです。私はこのコントローラを持っている:アップロードしたファイルをASP.NETからAzure BLOBにコピーしました

Create.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(); 
     } 
    } 
} 

Create.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からファイルのアップロードに関するアドバイスは任意の助け

感謝をも:)歓迎されています!

+1

1メガバイトのブロックを別々に、または並行してアップロードできます。すべてのブロックのアップロードが完了すると、ファイルをコミットし、Azure BLOBストレージにまとめられます。 CloudBlockBlob.PutBlockとCloudBlockBlob.PutBlockListを見てください。 HTMLに埋め込むファイルをアップロードする場合は、コンテンツタイプを持つことが賢明です。ファイルへのリンクをダウンロードリンクにしたい場合、あなたはそうする必要はありません。それは決して傷つけることはできません。 blockBlob.Properties.ContentType = "image/jpeg" –

答えて

1

あなたがストリームにファイルをコピーした後、あなたが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(); 
     } 

あなたの場合現在の位置がすでに終わっているストリームをアップロードしているので、空のファイルがアップロードされるよりも、これをしないでください。

+0

それはちょうどそれのためだった:(私はストリーム論理でこの "位置"について知りませんでした。 – Emixam23

関連する問題