非同期コントローラ使ってみた - まめしば雑記
http://d.hatena.ne.jp/shiba-yan/20100715/1279204349

上記のブログで非同期コントローラーが面白そうだったので、前回の ASP.NET MVC で複数ファイルのアップロード を少し修正して試してみました(※ASPX部分は そのまま使用しています)。

基本的には、基本クラス(Controller → AsyncController) とアクション名(Index → IndexAsync) を変えて、完了時のメゾット(IndexCompleted) を定義しているだけですが、アップロードされたファイルをそのまま保存しては、非同期にする意味がほとんどないので、保存後にメールでファイルを送る処理を追加しています。

    [HandleError]
    public class HomeController : AsyncController
    {
        [HttpPost]
        public ActionResult IndexAsync(HttpPostedFileBase[] fileUpload)
        {
            foreach (var f in fileUpload)
            {
                AsyncManager.OutstandingOperations.Increment();
                Thread t = new Thread(new ParameterizedThreadStart(Upload));
                t.Start(f);
            }
            return View();
        }

        private void Upload(object o)
        {
            HttpPostedFileBase f = (HttpPostedFileBase)o;
            if (f != null)
            {
                string filePath = Path.Combine(
                    HttpContext.Server.MapPath("~/App_Data/Uploaded/"),
                    Path.GetFileName(f.FileName));
                f.SaveAs(filePath);
				
                MyMail.Send(filePath);
            }
            AsyncManager.OutstandingOperations.Decrement();
        }

        public ActionResult IndexCompleted()
        {
            ViewData["msg"] = "アップロードが完了しました。";
            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }

 

メールを送ってる部分は、こんな感じです。

    public class MyMail
    {
        public static void Send(string fineName)
        {
            string from = "差出人メールアドレス";
            string to = "送信先メールアドレス";
            using (System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(from, to))
            {
                //添付ファイル
                System.Net.Mail.Attachment attachment;
                attachment = new System.Net.Mail.Attachment(fineName);
                attachment.ContentType = new System.Net.Mime.ContentType("image/jpeg");
                msg.Attachments.Add(attachment);

                System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient();
                sc.Host = "メールサーバ";

                sc.Send(msg);
            }
        }
    }

 

参考

非同期コントローラ使ってみた - まめしば雑記
http://d.hatena.ne.jp/shiba-yan/20100715/1279204349

ASP.NET MVC での非同期コントローラーの使用 - MSDN
http://msdn.microsoft.com/ja-jp/library/ee728598.aspx

環境:.NET Framework 4, ASP.NET MVC 2

ASP.NET MVC で複数のファイルをアップロードしてみます。

ファイルのアップロードが可能なフォームを作成して、ファイルを複数(今回は5つ)アップロードできるようにタグを記述します。

    <% using (Html.BeginForm("Index", "Home",
           FormMethod.Post, new { enctype = "multipart/form-data" }))
       { %>
    <p><input id="fileUpload1"  name="fileUpload" type="file" /></p>
    <p><input id="fileUpload2"  name="fileUpload" type="file" /></p>
    <p><input id="fileUpload3"  name="fileUpload" type="file" /></p>
    <p><input id="fileUpload4"  name="fileUpload" type="file" /></p>
    <p><input id="fileUpload5"  name="fileUpload" type="file" /></p>
    <p> <input type="submit" value="送信" /></p>
    <p><%: ViewData["msg"]%></p>
    <% } %>

 

こんな感じのページになります。

img1

 

コード部分はHttpPostedFileBaseクラスから、アップロードされたファイルを取得し保存するだけで完了です。

    public class HomeController : Controller
    {
        [HttpPost]
        public ActionResult Index(HttpPostedFileBase[] fileUpload)
        {
            foreach (var f in fileUpload)
            {
                if (f != null)
                {
                    string filePath = Path.Combine(
                        HttpContext.Server.MapPath("~/App_Data/Uploaded/"),
                        Path.GetFileName(f.FileName));
                    f.SaveAs(filePath);
                }
            }

            ViewData["msg"] = "アップロードが完了しました。";
            return View();
        }

    }

VS2008 の ASP.NET MVC 1 を ASP.NET MVC 2 に移行したときのメモです。

 

VS2008のASP.NET MVC 2へ移行

VS2008で作ったASP.NET MVC 1 を  VS2008 の ASP.NET MVC 2 に移行する場合は、下記ページにあります Converter を使用します。

Migrating ASP.NET MVC 1.0 applications to ASP.NET MVC 2 RTM

使い方は簡単で、

1.ダウンロードしたファイルを展開し起動
2.「Browse...」をクリックしてASP.NET MVC 1のソリューションファイルを指定
3.「Convert」ボタンをクリック

するだけです。

※VS2008 で 変換したソリューションファイルを開くには ASP.NET MVC 2 のインストールが必要です。

ASP.NET MVC 2 RTM - AspNetMVC2_VS2008.exe

 

 VS2010のASP.NET MVC 2へ移行

VS2010の場合は、ウィザードで自動的に変換します。

VS2010を起動して、VS2008で作ったASP.NET MVC 1 のソリューション(プロジェクト)ファイルを開けば、「Visual Studio 変換ウィザード」が起動しますので、そのまま自動的にASP.NET MVC 1 から ASP.NET MVC 2 に移行できます。

 

その他

ASP.NET MVC 2では、ヘルパーが stringから MvcHtmlString を返すよう変更されているので、replece 使ったり、三項演算子(条件演算子「? :」)を使ってる部分などは修正が必要です。

また、サーバーに ASP.NET MVC 2 をインストールされていない環境でも、参照設定にある下記のローカルコピーをTrueに設定し、サーバーにコピーするように設定すれば動きます。

System.Web.Mvc
System.Web.Routing
System.Web.Abstractions

先日、WordPress 3.0 をIIS7.5にインストールしたので、新機能であるマルチサイトの設定を行います。

今回は、日本語版をインストール済みの環境で作業しています。また、プラグインなどは全て無効の状態です。

 

■準備

URL Rewrite を使用しますのでインストールします。

URL Rewrite
http://www.iis.net/download/urlrewrite

 

■設定

1.wp-config.php に下記の1行を追加します。

define('WP_ALLOW_MULTISITE', true);

※「/* 編集が必要なのはここまでです ! WordPress でブログをお楽しみください。 */」より上に書く必要があります。

 

2.ログインすると、「ツール」メニューの下に「ネットワーク」が表示されますので、クリックします。

wp03-001

 

3.「WordPress サイトのネットワークを作成」で複数サイトを管理するための設定を行い「インストール」をクリックします。

 wp03-002
※今回はディレクトリの中にインストールしてあるため、サブドメインは選択できない状態です。

 

4.次に行うべき操作が表示されますので、操作を実行します。

4.1. /wordpress/wp-content の中に blogs.dir  ディレクトリを作成して、IUSRに「変更」の権限を与えます。

4.2. wp-config.php に記載されているコードを追加します。

4.3. URL Rewriteがインストールされていると、web.config の設定が表示されますので、/wordpress/ に web.configファイルを作成し、記載されている内容をコピーします。

 

5.管理画面にログインし直すと、「特権管理者」が表示されて設定完了です。特権管理者メニューからサイトの作成などを行うことができます。

wp03-003

Windows Azure Table で PartitionKey と RowKey を指定して、テーブルが見つからない場合は、デフォルトだと ResourceNotFound が返ってきて、例外(DataServiceQueryException) が発生します。

例外を発生させたくない場合は、TableServiceContext の IgnoreResourceNotFoundException を True に設定にします。

また、IgnoreResourceNotFoundException の設定をせずに、例外を発生させて ResourceNotFound を処理する場合は、StatusCodeを見て判断することが可能です。

サンプルコード

        protected void Page_Load(object sender, EventArgs e)
        {
            CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("StorageConnectionString");

            CloudTableClient tableClient = account.CreateCloudTableClient();
            tableClient.RetryPolicy = RetryPolicies.Retry(
                2,
                TimeSpan.FromMilliseconds(100));

            try
            {
                TableServiceContext svc = tableClient.GetDataServiceContext();
                var q = from t in svc.CreateQuery<Table1>("SampleTable")
                        where (t.PartitionKey == "Sample") && (t.RowKey == "key")
                        select t;

                return q.FirstOrDefault();

            }
            catch (DataServiceQueryException ex)
            {
                if (((OperationResponse)ex.Response).StatusCode == (int)HttpStatusCode.NotFound)
                {
                    // 何か処理;
                    return null;
                }
                throw;
            }
        }

        private class Table1 : TableServiceEntity
        {
            public Table1(string name)
            {
                base.PartitionKey = "Sample";
                base.RowKey = name;
            }

            public Table1() : base() { }
        }