かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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);
            }
        }
    }
}

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