概要
少し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に書き込む
<appSettings>
<add key="StorageConnectionString" value="ここに接続情報"/>
</appSettings>
取り出す
ConfigurationManager.AppSettings["StorageConnectionString"]
web.confgのconnectionStringsに書き込む
<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;
}