かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Silverlight 4でドロップされたデータをサーバに保存

WCF RIA Servicesと、Silverlight 4のファイルドロップで作ってみた。

早速作ろう

まずは、XAMLから。味気ないです。

MainPage.xaml
<UserControl x:Class="FileUpTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White" AllowDrop="True" Drop="LayoutRoot_Drop">
    </Grid>
</UserControl>
FileUploadDomainService.cs

サーバ側です。単純に受け取ったものをファイルに保存してます。

using System.IO;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;

namespace FileUpTest.Web
{
    [EnableClientAccess()]
    public class FuleUploadDomainService : DomainService
    {
        // ファイルを保存するパス(Global.asaxあたりでセットするといいよ)
        public static string AppDataPath { get; set; }

        public bool Upload(string fileName, byte[] data)
        {
            try
            {
                // 引数で渡されたbyte列をファイルに保存
                using (var w = new FileStream(
                    Path.Combine(AppDataPath, fileName),
                    FileMode.OpenOrCreate,
                    FileAccess.Write))
                {
                    w.Write(data, 0, data.Length);
                }
                return true;
            }
            catch
            {
                // 何か失敗
                return false;
            }
        }
    }
}
MainPage.xaml.cs

コードビハインドで、さっきのWCF RIA Servicesのクラスを使ってさくっとアップロードします。

using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using FileUpTest.Web;

namespace FileUpTest
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void LayoutRoot_Drop(object sender, DragEventArgs e)
        {
            // ドロップされたファイルを
            var file = ((FileInfo[])e.Data.GetData(DataFormats.FileDrop)).FirstOrDefault();
            if (file == null) return;

            // 開いて
            using (var stream = file.OpenRead())
            {
                // バイト列にして
                var ms = new MemoryStream();
                byte[] buffer = new byte[1024 * 100];
                while (stream.Read(buffer, 0, buffer.Length) != 0)
                {
                    ms.Write(buffer, 0, buffer.Length);
                }

                // アップロード
                var ctx = new FuleUploadDomainContext();
                ctx.Upload(file.Name, 
                    ms.ToArray(),
                    result =>
                    {
                        // アップロード結果を表示
                        if (result.Value)
                        {
                            MessageBox.Show("アップロード成功");
                        }
                        else
                        {
                            MessageBox.Show("何かアップロード失敗");
                        }
                    }, null);
            }
        }
    }
}

こんなんで、ファイルアップロードできました。
大きなサイズのファイルとかあると、悲しい結果に終わるだろうから、ちょっと工夫しないといけないのかな?
工夫の仕方は、思いつかない。