ファイルを圧縮してからサーバーにアップロードすることができます。それには、ComponentOne Studio for Silverlight に含まれる C1Zip クラスとC1Uploader クラスを使用します。このトピックでは、ファイルを圧縮してアップロードするアプリケーションを作成します。
次の手順に従います。
-
Visual Studio で、[ファイル]→[新しいプロジェクト]を選択します。
-
[新しいプロジェクト]ダイアログボックスの左ペインから言語を選択し、テンプレートリストから[Silverlight アプリケーション]を選択します。プロジェクトの[名前]を入力し、[OK]をクリックします。[新しい Silverlight アプリケーション]ダイアログボックスが表示されます。
-
[OK]をクリックしてデフォルト設定を受け入れ、[新しい Silverlight アプリケーション]ダイアログボックスを閉じると、プロジェクトが作成されます。MainPage.xaml ファイルが開きます。
-
ソリューションエクスプローラウィンドウでプロジェクトを右クリックし、[参照の追加]を選択します。
-
[参照の追加]ダイアログボックスで、C1.Silverlight.Zip.dll および C1.Silverlight.Uploader.dll アセンブリを見つけて選し、[OK]をクリックしてプロジェクトに参照を追加します。
-
プロジェクトの XAML ウィンドウで、<Grid> タグと </Grid> タグを削除します。これらのタグは、次の手順で書き換えます。
-
次の XAML マークアップを MainPage.xaml ファイルの <UserControl> タグと </UserControl> タグの間に追加します。
XAML |
|
<StackPanel Orientation="Horizontal" x:Name="LayoutRoot" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center" MinHeight="400">
<Border Padding="5" BorderBrush="Black" BorderThickness="1" Margin="2" MinWidth="200">
<StackPanel>
<Button Content="ファイルを開く" Click="OpenFiles" />
<TextBlock Text="開いているファイル:" FontWeight="Bold" Margin="10"/>
<ItemsControl Name="files"/>
</StackPanel>
</Border>
<Button Content="圧縮してファイルをアップロードする >" Grid.Column="1" VerticalAlignment="Center" Margin="10" Click="ZipAndUpload" Name="zipAndUploladButton"/>
<Border Padding="5" BorderBrush="Black" BorderThickness="1" Margin="2" Grid.Column="2">
<StackPanel>
<TextBlock Text="サーバー上の圧縮されたファイル:" FontWeight="Bold" Margin="10"/>
<ItemsControl Name="zips" Background="White"/>
</StackPanel>
</Border>
</StackPanel>
|
このマークアップは、いくつかのパネルと1つのボタンを作成します。ユーザーがこのボタンをクリックすると、ファイルが圧縮されてサーバーにアップロードされます。
-
ソリューションエクスプローラで、MyProject.Web アプリケーションを右クリックします。"MyProject" には、実際のプロジェクトアプリケーションの名前が入ります。[新しいフォルダ]を選択し、フォルダ名を "Zips" に指定します。このフォルダには、圧縮されたファイルが置かれます。
-
ソリューションエクスプローラで、MainPage.xaml ファイルを右クリックして[コードの表示]を選択し、コードビューに切り替えます。
-
コードビューで、次の Imports または using 文をページの先頭に追加します(ページに含まれていない場合)。
|
|
Imports System.IO
Imports C1.C1Zip
Imports C1.Silverlight.Uploader
|
|
|
using System.IO;
using C1.C1Zip;
using C1.Silverlight.Uploader;
|
-
MainPage クラスのすぐ内側で、次の変数を定義します。
|
|
Dim fileInfos As IEnumerable(Of FileInfo)
Dim zipCount As Integer = 0
|
|
|
IEnumerable fileInfos;
int zipCount = 0;
|
-
MainPage.xaml.cs または MainPage.xaml.vb ファイルで MainPage クラスの他のすべてのメソッドの下に、次のイベントハンドラを追加します。
|
|
Private Sub OpenFiles(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim dialog = New OpenFileDialog()
dialog.ShowDialog()
If dialog.Files Is Nothing Then
Exit Sub
End If
fileInfos = dialog.Files
files.ItemsSource = fileInfos.[Select](Function(fi) fi.Name)
zipAndUploladButton.IsEnabled = fileInfos.Any()
End Sub
|
|
|
private void OpenFiles(object sender, RoutedEventArgs e)
{
var dialog = new OpenFileDialog { Multiselect = true };
dialog.ShowDialog();
if (dialog.Files == null)
{
return;
}
fileInfos = dialog.Files;
files.ItemsSource = fileInfos.Select(fi => fi.Name);
zipAndUploladButton.IsEnabled = fileInfos.Any();
}
|
このイベントハンドラは、最初に、ユーザーがアップロードするファイルを選択するための OpenFileDialog を表示します。
-
アップロードファイルを圧縮する次のイベントハンドラをプロジェクトに追加します。
|
|
Private Sub ZipAndUpload(ByVal sender As Object, ByVal e As RoutedEventArgs)
' メモリストリームと zip ファイルを作成します
Dim stream = New MemoryStream()
Dim zip = New C1ZipFile(stream, True)
' 圧縮するファイルを追加します
For Each fileInfo In fileInfos
Dim fileStream = fileInfo.OpenRead()
zip.Entries.Add(fileStream, fileInfo.Name)
fileStream.Close()
Next
' アップローダーを作成します
Dim uploader As C1Uploader = New C1UploaderPost(BuildAbsoluteUri("Upload.ashx"))
' ストリームを先頭に設定し、アップローダーにストリームを追加します
stream.Seek(0, SeekOrigin.Begin)
Dim zipName = System.Threading.Interlocked.Increment(zipCount) & ".zip"
uploader.AddFile(zipName, stream)
' アップロードが完了したら、Zips リストに表示します
Dim hb As New HyperlinkButton
hb.Content = zipName
hb.NavigateUri = BuildAbsoluteUri("Zips/" + zipName)
If uploader.IsBusy = False Then
Me.zips.Items.Add(hb)
End If
' zip ファイルをアップロードします
uploader.BeginUploadFiles()
End Sub
|
|
|
private void ZipAndUpload(object sender, RoutedEventArgs e)
{
// メモリストリームと zip ファイルを作成します
var stream = new MemoryStream();
var zip = new C1ZipFile(stream, true);
// 圧縮するファイルを追加します
foreach (var fileInfo in fileInfos)
{
var fileStream = fileInfo.OpenRead();
zip.Entries.Add(fileStream, fileInfo.Name);
fileStream.Close();
}
// アップローダーを作成します
C1Uploader uploader = new C1UploaderPost(BuildAbsoluteUri("Upload.ashx"));
// ストリームを先頭に設定し、アップローダーにストリームを追加します
stream.Seek(0, SeekOrigin.Begin);
var zipName = ++zipCount + ".zip";
uploader.AddFile(zipName, stream);
// アップロードが完了したら、Zips リストに表示します
uploader.UploadCompleted += (s, e2) =>
{
zips.Items.Add(new HyperlinkButton
{
Content = zipName,
NavigateUri = BuildAbsoluteUri("Zips/" + zipName)
});
};
// zip ファイルをアップロードします
uploader.BeginUploadFiles();
}
|
-
プロジェクトに次のイベントハンドラを追加します。
|
|
Public Shared Function BuildAbsoluteUri(ByVal relativeUri As String) As Uri
' 現在の絶対 URI を取得します。これは、アプリケーションが展開される場所に依存します
Dim uri As Uri = System.Windows.Browser.HtmlPage.Document.DocumentUri
Dim uriString As String = uri.AbsoluteUri
' ページ名を相対サービス URI に置き換えます
Dim ls As Integer = uriString.LastIndexOf("/"c)
uriString = uriString.Substring(0, ls + 1) + relativeUri
' 新しい URI を返します
Return New Uri(uriString, UriKind.Absolute)
End Function
|
|
|
public static Uri BuildAbsoluteUri(string relativeUri)
{
// 現在の絶対 URI を取得します。これは、アプリケーションが展開される場所に依存します
Uri uri = System.Windows.Browser.HtmlPage.Document.DocumentUri;
string uriString = uri.AbsoluteUri;
// ページ名を相対サービス URI に置き換えます
int ls = uriString.LastIndexOf('/');
uriString = uriString.Substring(0, ls + 1) + relativeUri;
// 新しい URI を返します
return new Uri(uriString, UriKind.Absolute);
}
|
-
Visual Studio のソリューションエクスプローラで、MyProject.Web ソリューションを右クリックします。"MyProject" には、実際のプロジェクト名が入ります。[追加]→[新しい項目]オプションを選択します。
-
[新しい項目の追加]ダイアログボックスで、[ジェネリックハンドラー]テンプレートを選択し、新しいクラス名を "Upload.ashx" に指定します。これは、前に C1Uploader オブジェクトを作成した際に使用した URI です。
-
[追加]をクリックしてプロジェクトにファイルを追加したら、[新しい項目の追加]ダイアログボックスを閉じます。
-
Upload.ashx コードファイルを開き、次の Imports または using 文が含まれていない場合は、これをページの先頭に追加します。
|
|
Imports System.Web.Services
|
|
|
using System.Web.Services;
|
-
ProcessRequest メソッドのデフォルトの実装を次のコードに置き換えます。
|
|
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Const MAXFILES As Integer = 30
' クリーンアップします
Dim path As String = context.Request.MapPath("Zips")
Dim files As String() = System.IO.Directory.GetFiles(path)
If files.Length >= MAXFILES Then
For Each fileName As String In files
System.IO.File.Delete(fileName)
Next
End If
' アップロードされるファイルを取得します
Dim i As Integer = 0
While i < context.Request.Files.Count AndAlso i < MAXFILES
Dim file As HttpPostedFile = context.Request.Files(i)
' ファイルを Zips フォルダに保存します
Dim fileName As String = context.Request.MapPath("Zips/" & file.FileName)
file.SaveAs(fileName)
i += 1
End While
End Sub
|
|
|
public void ProcessRequest(HttpContext context)
{
const int MAXFILES = 30;
// クリーンアップします
string path = context.Request.MapPath("Zips");
string[] files = System.IO.Directory.GetFiles(path);
if (files.Length >= MAXFILES)
{
foreach (string fileName in files)
System.IO.File.Delete(fileName);
}
// アップロードされるファイルを取得します
for (int i = 0; i < context.Request.Files.Count && i < MAXFILES; i++)
{
HttpPostedFile file = context.Request.Files[i];
// ファイルを Zips フォルダに保存します
string fileName = context.Request.MapPath("Zips/" + file.FileName);
file.SaveAs(fileName);
}
}
}
|
このコードは、最初に、画像フォルダに 30 個を超えるファイルがある場合に、その Zips フォルダをクリーンアップします。このコードは、クリーンアップ後に、context.Request.Files コレクション内のファイルをループ処理し、各ファイルを Zips フォルダに保存します。
ここまでの成果
これで、圧縮したファイルをアップロードする Silverlight アプリケーションを作成できました。アプリケーションの機能を確認するには、次の手順に従います。
-
[デバッグ]→[デバッグ開始]を選択して、アプリケーションを実行します。
-
[ファイルを開く]ボタンをクリックし、アップロードするファイルを選択します。
-
[開く]ダイアログボックスで、アップロードするファイルを1つ以上選択し、[開く]ボタンをクリックします。ダイアログボックスが閉じます。
-
[圧縮してファイルをアップロードする]ボタンをクリックして、選択したファイルをアップロードします。
-
圧縮されたファイルのリンクが表示されます。最初にアップロードされたファイルは、"1.zip" になります。
-
その zip ファイルのリンクをクリックし、コンピュータに保存します。
-
その zip ファイルを展開し、アップロードした項目がファイルに含まれていることを確認します。
関連トピック