LoginSignup
0
0

More than 3 years have passed since last update.

Asp.Net MVC5 でblobへファイルをアップロードする(覚書)

Posted at

概要

少しASP.NET MVCを触ったときに、自分用のメモ
間違ってたり、するかも!!

環境

  • windows10
  • visual studio 2017
  • c#

パッケージ

Visual Studio パッケージ マネージャーから下記コマンドを入力

Install-Package WindowsAzure.Storage

アカウント情報について

開発環境でblobを使う

「Azure Storage Emulator」があるのでそれを使う。

デフォルトでの接続情報は、次のようになる模様

DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;
AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;
QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;

参考URL: https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-emulator

web.confgのappsettingsに書き込む

web.config
<appSettings>
    <add key="StorageConnectionString" value="ここに接続情報"/>
</appSettings>

取り出す

 ConfigurationManager.AppSettings["StorageConnectionString"]

web.confgのconnectionStringsに書き込む

web.config
  <connectionStrings>
    <add name="StorageConnection" connectionString="ここに接続情報"/>
  </connectionStrings>

取り出す

ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString

セキュリティの観点から

ソースへの直書きは、ちょっとやりたくない。
そのため、Azure key valt 等が使えればよいが、今回は使わず簡単に環境変数に設定を行って、そこから取り取り出す形。(Git管理とかで、多くの人にさらすより多少まし)

環境変数値を設定することで、「appSettings」の「connectionStrings」に上書きor追加を行うようにする。
ソースコードとしては、次を参照。
環境変数のキーの頭に「AppSettingsPrefix」の値を付けた、環境変数を設定することで、「appSettings」に上書き、追加される。

「connectionStrings」のほうも同様だが、「sql」の場合には「providerName」が必要となってしまう。そのため、「providerName」が必要なものと不必要なものに分かれている

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Web;

[assembly: PreApplicationStartMethod(typeof(CareMatchingSystem.App_Start.OverrideBootstrapper), "Start")]

namespace CareMatchingSystem.App_Start
{
    public class OverrideBootstrapper
    {
        public static void Start()
        {
            var environmentVariables = Environment.GetEnvironmentVariables()
                                                  .Cast<DictionaryEntry>()
                                                  .ToDictionary(x => (string)x.Key, x => (string)x.Value);

            foreach (var appSetting in environmentVariables.Where(x => x.Key.StartsWith(AppSettingsPrefix, StringComparison.OrdinalIgnoreCase)))
            {
                ConfigurationManager.AppSettings[appSetting.Key.Substring(AppSettingsPrefix.Length)] = appSetting.Value;
            }

            var connectionStrings = new ConnectionStringSettingsCollectionWrapper(ConfigurationManager.ConnectionStrings);

            foreach (var connectionString in environmentVariables.Where(x => x.Key.StartsWith(SqlServerConnStrPrefix, StringComparison.OrdinalIgnoreCase)))
            {
                connectionStrings.AddOrUpdate(connectionString.Key.Substring(SqlServerConnStrPrefix.Length), connectionString.Value, SqlServerProviderName);
            }

            foreach (var connectionString in environmentVariables.Where(x => x.Key.StartsWith(ConnStrPrefix, StringComparison.OrdinalIgnoreCase)))
            {
                connectionStrings.AddOrUpdate(connectionString.Key.Substring(ConnStrPrefix.Length), connectionString.Value);
            }
        }

        private const string AppSettingsPrefix = "APPSETTING_";
        private const string SqlServerConnStrPrefix = "SQLSERVERCONNSTR_";
        private const string ConnStrPrefix = "CONNSTR_";

        private const string SqlServerProviderName = "System.Data.SqlClient";
    }


    internal class ConnectionStringSettingsCollectionWrapper
    {
        public ConnectionStringSettingsCollectionWrapper(ConnectionStringSettingsCollection connectionStrings)
        {
            _connectionStrings = connectionStrings;

            typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
                                                    .SetValue(_connectionStrings, false);
        }

        private readonly ConnectionStringSettingsCollection _connectionStrings;

        public void AddOrUpdate(string name, string connectionString, string providerName)
        {
            var settings = _connectionStrings[name];

            if (settings == null)
            {
                _connectionStrings.Add(new ConnectionStringSettings
                {
                    Name = name,
                    ConnectionString = connectionString,
                    ProviderName = providerName
                });
            }
            else
            {
                typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
                                            .SetValue(settings, false);

                settings.ConnectionString = connectionString;
                settings.ProviderName = providerName;
            }
        }

        public void AddOrUpdate(string name, string connectionString)
        {
            var settings = _connectionStrings[name];

            if (settings == null)
            {
                _connectionStrings.Add(new ConnectionStringSettings
                {
                    Name = name,
                    ConnectionString = connectionString
                });
            }
            else
            {
                typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
                                            .SetValue(settings, false);

                settings.ConnectionString = connectionString;
            }
        }
    }


}

blobへのアップロードは次のようにする。

viewModels.PostedFileはHttpPostedFileBaseになり、Postされたファイルが入っている。

        /// <summary>
        /// Blobにアップロード
        /// </summary>
        /// <param name="FileStream">アップロードファイル</param>
        /// <param name="ContainerString">コンテナ名(コンテナ命名規約に注意)</param>
        /// <param name="FileNameAfterUpload">アップロード後のファイル名</param>
        /// <returns></returns>
        public static void BlobUpload(System.IO.Stream FileStream, string ContainerString, string FileNameAfterUpload)
        {

            //アカウント情報を取得
            string storageConnectionString = ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString;

            CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
            CloudBlobClient serviceClient = account.CreateCloudBlobClient();

            // コンテナを新規作成
            var container = serviceClient.GetContainerReference(ContainerString);
            container.CreateIfNotExistsAsync().Wait();

            //アップロード後のファイル名を設定
            CloudBlockBlob blob = container.GetBlockBlobReference(FileNameAfterUpload);

            //ファイルをアップロード
            blob.UploadFromStream(FileStream);


        }

blobダウンロード


        /// <summary>
        /// Blobからダウンロード(Byte)
        /// </summary>
        /// <param name="ContainerString">コンテナ名</param>
        /// <param name="DownloadFileName">ダウンロードファイル名(Pathを含む)</param>
        /// <returns></returns>
        public static Byte[] BlobDownloadToByte(string ContainerString, string DownloadFileName)
        {

            //アカウント情報を取得
            string storageConnectionString = ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString;

            CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
            CloudBlobClient serviceClient = account.CreateCloudBlobClient();

            //コンテナをセット
            var container = serviceClient.GetContainerReference(ContainerString);

            //ダウンロードのファイル名をセット
            CloudBlockBlob blockBlobDownload = container.GetBlockBlobReference(DownloadFileName);

            //ファイル情報を取得
            blockBlobDownload.FetchAttributes();

            //データ長に合わせ初期化
            byte[] data = new byte[blockBlobDownload.Properties.Length];

            //byte型で取得
            blockBlobDownload.DownloadToByteArray(data, 0);

            return data;

        }
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0