前回は、3.2の最後、Windows Azure への配置まで行った。今回は、3.3のストレージサービスから試す。
ストレージサービス
ストレージサービスには以下の物がある。
- BLOB
- テーブル
- キュー
ストレージサービスは RESTインタフェースでアクセスでき、云々と本に記載がある。この辺は知識になると思うので、割愛する。
基本は書籍通り!を目指しているが、かなり手間取った。
書籍では、Photoリストを作成することで、ストレージ等について説明が続く。
はまった点(StorageClient が見つからない)
サンプルとして、StorageClientがあるとあったが、見つからなかったので別のサンプルsamples-cs\Thumbnails\ を参考にしつつ変更した。
とりあえずローカルで動く事を目指し、試行錯誤の結果以下のようにした。
コンフィギュレーションの追加
DataConnectionStringのアイテムを追加した。なお、Azure環境上で試す場合には、ここに固有の値を入れる必要があるらしいが、今回はローカル確認のみ。
- ServiceConfiguration.cscfg
<ConfigurationSettings> <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" /> </ConfigurationSettings>
- ServiceDefinition.csdef
<ConfigurationSettings> <Setting name="DataConnectionString" /> </ConfigurationSettings>
CloudStorageAccountの更新(?)
この後、CloudStorageAccountを用いて、ストレージに接続するので、この初期設定を追加した。
- WebRole.csのpublic override bool OnStart()内
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
// configuration settings change in the service configuration file.
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
// Provide the configSetter with the initial value
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
RoleEnvironment.Changed += (sender, arg) =>
{
if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
.Any((change) => (change.ConfigurationSettingName == configName)))
{
// The corresponding configuration setting has changed, propagate the value
if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
{
// In this case, the change to the storage account credentials in the
// service configuration is significant enough that the role needs to be
// recycled in order to use the latest settings. (for example, the
// endpoint has changed)
RoleEnvironment.RequestRecycle();
}
}
};
});
オリジナルコードは以下のようになっていた。
public override bool OnStart()
{
DiagnosticMonitor.Start("DiagnosticsConnectionString");
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
RoleEnvironment.Changing += RoleEnvironmentChanging;
//ここに追加した
return base.OnStart();
}
初期設定
以下の処理を1度行う事でストレージにアクセスできるようになるという事で、とりあえず、開発環境用ということで Button2 に割りつけた。
private static CloudBlobClient blobStorage;
protected void Button2_Click(object sender, EventArgs e)
{
System.Diagnostics.Trace.TraceInformation("Button2_Click");
System.Diagnostics.Trace.TraceInformation("FromConfigurationSetting");
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
System.Diagnostics.Trace.TraceInformation("CreateCloudBlobClient");
blobStorage = storageAccount.CreateCloudBlobClient();
System.Diagnostics.Trace.TraceInformation("GetContainerReference");
var container = blobStorage.GetContainerReference("photo");
{
try
{
System.Diagnostics.Trace.TraceInformation("CreateIfNotExist");
container.CreateIfNotExist();
System.Diagnostics.Trace.TraceInformation("GetPermissions");
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
System.Diagnostics.Trace.TraceInformation("SetPermissions");
container.SetPermissions(permissions);
System.Diagnostics.Trace.TraceInformation("GetPermissions");
permissions = container.GetPermissions();
}
catch (StorageClientException ex)
{
System.Diagnostics.Trace.TraceInformation("StorageClientException");
if (ex.ErrorCode == StorageErrorCode.TransportError)
{
System.Diagnostics.Trace.TraceError(string.Format("Connect failure! The most likely reason is that the local " +
"Development Storage tool is not running or your storage account configuration is incorrect. " +
"Message: '{0}'", ex.Message));
System.Threading.Thread.Sleep(5000);
}
else
{
throw;
}
}
}
}
書籍を読むと、Page_Loadで行うようになっていしたし、またsamples-cs\Thumbnails\ではもう少し立派なコードが書かれていた。
また CloudBlobClient blobStorage は、後々アクセスするということで、インスタンス変数 (なんていうんだっけ?メンバ変数?)にしておいてある。
BlobProparties
書籍リスト3-13 では、BlobPropartiesを用いてた。しかし現在のAzure SDK だと BlobProparties のコンストラクタに文字列が渡せないので悩んだ。
samples-cs\Thumbnails\を参考に以下のようにした。
protected void Button3_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
System.Diagnostics.Trace.TraceInformation("string.Format");
var uniqBlobName = string.Format("img_{0}_{1}.jpg",
DateTime.UtcNow.ToString("yyyyMMddHHmmss"),
Guid.NewGuid().ToString());
System.Diagnostics.Trace.TraceInformation("GetContainerReference");
var container = blobStorage.GetContainerReference(@"photo");
System.Diagnostics.Trace.TraceInformation("UploadFromStream");
container.GetBlockBlobReference(uniqBlobName).UploadFromStream(FileUpload1.FileContent);
}
}
ファイル送信ボタンをButton3として、FileUpload1にファイルがあるとして、それを元に BLOBにファイルを登録した。
表示
一番最後に登録した画像を取得して Image1 へ。
また、thumbnailsとしたListViewに、登録してある画像を追加するということで以下のコードとした。
protected void Page_PreRender(object sender, EventArgs e)
{
try
{
var container = blobStorage.GetContainerReference(@"photo");
Image1.ImageUrl = container.ListBlobs().Last().Uri.AbsoluteUri;
thumbnails.DataSource = from o in container.ListBlobs()
select new { Url = o.Uri };
thumbnails.DataBind();
}
catch (Exception)
{
}
}
分からない点が多すぎる。
じつはASP.NETは今回が初めて。感覚が分からず悩む事が多々ある。
さいごに
今回は、3.3のBLOB追加までいった。資料の中の記述が若干古いので手間取ったが、逆にこのくらいの方が、中身を知るきっかけになっていいと思う。
次回は、3.3の残りを試す。


コメントする