ASP.NET MVC4とTwitter Bootstrapを組み合わせる(Twitter.Bootstrap.MVC4を使ってみた)

0.前置き

以前、「HTML・CSSデザインフレームワークを使ってみた」というポストを書きました。
こういったデザインフレームワークをWebアプリケーションフレームワークと組み合わせるときに、
少しだけですけど面倒な時があります。
ASP.NET MVC4でも同じです。テンプレートページを作るのとか…。

1.Twitter.Bootstrap.MVC4の紹介

今回紹介するTwitter.Bootstrap.MVC4は、ASP.NET MVC4とTwitter Bootstrapを組み合わせる機能(ツール、テンプレートなど)を提供します。
作者による紹介ページは、「Twitter.Bootstrap.MVC4; the Bootstrap package for ASP.Net MVC4」です。
Githubのサイトはこちらです。

2.インストール

Visual Studioのプロジェクトを作成するところから順に説明します。

  1. 「新しいプロジェクト」から「ASP.NET MVC 4 Webアプリケーション」を選択する。
  2. プロジェクトテンプレートでは、「空」を選択する。
  3. パッケージマネージャーコンソールを起動する。
  4. 「PM > Install-Package twitter.bootstrap.mvc4」を実行する。
  5. 「PM > Install-Package twitter.bootstrap.mvc4.sample」を実行する。

これでOK。

3.実際に使ってみる

何がどうなっているかいくつか確認して見ます。

デフォルトビュー
/Views/sharedの配下に、レイアウトファイルがいくつかと、
「Create.cshtml」、「Details.cshtml」、「Index.cshtml」が用意されています。
Controllerだけ実装すれば、上記のアクションに該当するビューを各コントローラごとに作る必要はありません。
#要件に対して柔軟ではないですが、さくっと作れますね。

トップメニューの作成補助
Bootstrap上のトップメニューの作成補助機能です。

header

NavigationExtensions.csとして提供されています。
実装は以下のような感じです。

public class ExampleLayoutsRouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapNavigationRoute<ExampleLayoutsController>("Example Layouts", c => c.Starter())
                .AddChildRoute<ExampleLayoutsController>("Marketing", c => c.Marketing())
                .AddChildRoute<ExampleLayoutsController>("Fluid", c => c.Fluid())
                .AddChildRoute<ExampleLayoutsController>("Sign In", c => c.SignIn());
    }
}

アラート出力
BootstrapBaseControllerを継承してコントローラを作成すれば、TempDataを用いたアラート出力が可能になります。
こんな感じです。メッセージの出力については、_alerts.cshtmlでよしなにやってくれます。この実装方法いいかも。

/[HttpPost/]
public ActionResult Create(HomeInputModel model)
{
    if (ModelState.IsValid)
    {
        // ...
        Success("Your information was saved!");
        return RedirectToAction("Index");
    }
    Error("there were some errors in your form.");
    return View(model);
}

出力は以下の感じです。

message1

4.サンプルを書いてみての補足

普段あまりASP.NET MVCのコード書かないので、このコードは参考になりました。
アラートってあんな方法で出すとか。

5.サンプルコード

今回は大したサンプルを書かなかったので、載せません。
作者が提供しているtwitter.bootstrap.mvc4.sampleをご利用ください。

6.最後に

実はビューのテンプレートも現在鋭意作成中らしいです。
twitter.bootstrap.mvc4.template
コード自体はもう存在するので完成が待ち遠しいです。

と…思ったら、MvcScaffolding4TwitterBootstrapMvc←こんなコードもありました。
twitter.bootstrap.mvc4用のスキャッフォールディングらしいです。
インストールして触ってみたけど、なぜかコード生成するときにVisual Studioがフリーズする。
また今度調べてみよ。

広告

DotNetZipとASP.NET MVC

0.前置き

Webアプリを作るときにサーバーサイドで複数のファイルをZip化させるにはどんな手段があるのかなってことを調べてました。
.NET標準のクラスでZip化するもの(System.IO.Compression.GZipStream, System.IO.Packaging.ZipPackage)
もあるのですが、複数ファイルをまとめる(アーカイブする)機能を実現するのはちょっとめんどくさそうです。
そこで今回はDotNetZipというライブラリーを使ってみることにしました。
サンプルはASP.NET MVCでWebアプリケーンションにしました。

1.DotNetZipの紹介

DotNetZipは、Ms-PLで公開されているZipを扱うライブラリーです。
とにかくなんでもできるとCodePlexでは言っておられます。
CodePlexのサイトはこちら

2.インストール

Nugetでインストールできます。
CodePlexからはサンプルアプリケーションが一緒に入っているソースコードをダウンロードすることができます。
サンプルがたくさん入っていますし、ドキュメントも大量にあるので使うことに不自由しません。

3.実際に使ってみる

ASP.NET MVCでサンプルを作ってみました。主要な部分のみ抜き出し記載します。
(今回はASP.NET MVC4とVisualStudio2011を使っています。)

HomeController#Downloadの実装部分
Home/IndexのビューにDownloadアクションを呼び出すアクションリンクを配置してあります。
呼び出させれるDownloadアクションは以下の通りです。

public class HomeController : Controller
{
    public ZipFileResult Download()
    {
        var filePathList = new List<string>{
            Server.MapPath(@"~/Content\files\ファイル1.txt"),
            Server.MapPath(@"~/Content\files\ファイル2.txt"),
            Server.MapPath(@"~/Content\files\ファイル3.txt"),
            Server.MapPath(@"~/Content\files\ファイル4.txt"),
            Server.MapPath(@"~/Content\files\ファイル5.txt"),
            Server.MapPath(@"~/Content\files\file6.txt")
        };

        var zipFileName = "ZippedFile.zip";

        using (var zipFile = new ZipFile(Encoding.GetEncoding("shift_jis")))
        {
            zipFile.AddFiles(filePathList, "");
            return new ZipFileResult(zipFile, zipFileName);
        }
    }
}

複数ファイルも、zipFile.AddFiles(filePathList, “”) としてあげればいっきにアーカイブ化できます。
1つ目の引数がZip化するファイルのパス、2つめの引数でZip化後のフォルダー内でのファイルの場所を指定します。
詰め込んだZipFileのオブジェクトをZipFileResultというカスタムActionResultに渡します。

ZipFileResultの実装部分
ExecuteResultでHttpContext.ResponseにZipFileオブジェクトを書きだしてあげます。
こちらを参考にしました。)

public class ZipFileResult : ActionResult
{
    public ZipFile zip { get; set; }
    public string fileName { get; set; }

    public ZipFileResult(ZipFile zip, string fileName)
    {
        this.zip = zip;
        this.fileName = fileName;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = "application/zip";
        response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
        zip.Save(response.OutputStream);
        response.End();
    }
}

4.サンプルを書いてみての補足

このライブラリーも便利ですね。
ファイルの追加とか圧縮とか、属性をもろもろつけるとか簡単にできるそうです。
唯一の注意点は日本語のファイル名のファイルをアーカイブ対象にする場合には、
ZipFileのコンストラクタでエンコーディング方式を指定する必要があるということです。

5.サンプルコード

サンプルコードはgithubにホスティングしてあります。
DotNetZipのサンプルWebアプリケーション

6.最後に

最近、だんだん手をつける範囲が広くなってきた気がします。
深堀はできないけど、薄く広く学んだことを書き留めていこうと思います。
参考にしたサイト
astel-labs.net : C#でZip圧縮形式ファイルの操作

AutoMapperを動かしてみる

0.前置き

仕事でAutoMapperを触る機会がありました。
覚書のために、その記録を残しておきます。

1.AutoMapperとは

規約ベースで利用するオブジェクト-オブジェクトマッパーです。
(A convention-based object-object mapper. )
英語の訳をそのまま。。。

DTOからEntityやViewModelにデータを詰め直す時に使います。
詰め替えるコードをえんえんと書かなくてもOKというわけです。例えば以下のようなコードがあるとします。

 // 変換元を
SrcEmployee srcEmployee = ...;

// 変換先に、詰め直す!
var destEmp = new DestEmployee
                {
                    Name = srcEmp.Name,
                    Age = Convert.ToInt32(srcEmp.Age),
                    Status = EmployeeStatusResolver(srcEmp.Status),
                    HireDate = CustomDateTimeConverter(srcEmp.Status)
                };

規約に従えって、AutoMapperを利用すればこんな感じになります。(もろもろ省いています)

Mapper.CreateMap<SrcEmployee, DestEmployee>();
var destEmp = Mapper.Map<SrcEmployee, DestEmployee>(srcEmp);

2.インストール

AutoMapperのインストールはnugetでできます。とても簡単。

3.実際に使ってみる

課題を作って、実際に変換処理を書いて見ます。

3-1.(課題)変換元と変換先のクラス

SrcEmployeeからDestEmployeeにデータの詰め替えを行います。
(プロパティ名の対応関係の規約は、説明が煩雑になりそうなので省きます。)

/// <summary>
/// 変換元のクラス
/// </summary>
public class SrcEmployee
{
    public string Name { get; set; }
    public string Age { get; set; }
    public string Status { get; set; }
    public DateTime HireDate { get; set; }
}

/// <summary>
/// 変換先のクラス
/// </summary>
public class DestEmployee
{
    public string Name { get; set; }
    public int Age { get; set; }
    public EmployeeStatus Status { get; set; }
    public string HireDate { get; set; }
}

この課題に対して、型変換や、値の変換等、変換ルールが必要なところをマッピング定義に書いていきます。

3-2.グローバルな変換規則を作る

どのマッピングでも使うような変換規則を作ります。
今回は主に2つ。

  • stringをintに変換:Convet.ToInt32()を利用
  • DateTimeをstringに変換:独自のコンバーターを利用

作った独自のコンバーターはこんな感じ。

public class CustomDateTimeConverter : TypeConverter<DateTime, string>
{
    protected override string ConvertCore(DateTime source)
    {
        return source.ToString("yyyy年MM月dd日");
    }
}

3-3.変換元のクラスと変換先のクラスに依存する変換規則を作る

今回の例ですと、Statusというプロパティになります。
stringから、enumのEmployeeStatusに変換しています。今度は独自のリゾルバーを作ります。

public class EmployeeStatusResolver : ValueResolver<SrcEmployee, EmployeeStatus>
{
    protected override EmployeeStatus ResolveCore(SrcEmployee source)
    {
        switch (source.Status)
        {
            case "在職":
                return EmployeeStatus.Stay;
            case "退職":
                return EmployeeStatus.Exit;
            case "長期休暇中":
                return EmployeeStatus.LongHoliday;
            default:
                throw new UnKnowonEmployeeStatusException();
        }
    }
}

3-4.変換定義をする

今まで考えた変換定義をコードにおこします。

// 2-2用のルール
Mapper.CreateMap<string, int>().ConvertUsing(Convert.ToInt32);
Mapper.CreateMap<DateTime, string>().ConvertUsing<CustomDateTimeConverter>();

// SrcEmployeeからDestEmployeeの変換定義と、2-3用のルール
Mapper.CreateMap<SrcEmployee, DestEmployee>()
    .ForMember(dest => dest.Status, opt => opt.ResolveUsing<EmployeeStatusResolver>());

3-5.マッピング

最後にマッピング!!これだけで、データの詰め直しが完了します。

var destEmp = Mapper.Map<SrcEmployee, DestEmployee>(srcEmp);

4.サンプルを書いてみての補足

最初にマッピングルールをいろいろ作らなきゃいけないのは面倒です。
ただかなりの確率で使いまわせることができるので、一回作ってしまえば良いです。

ASP.NET MVCで使うと便利だよ~って、マイコミジャーナルの記事でも言ってますので
興味のある方は、参考資料のほうをチェックしてみてください。

5.サンプルコード

サンプルコードはgithubにホスティングしてあります。
AutoMapperのサンプル
コード本体
※実は、初github!

6.参考資料

本家のページは以下です。CodePlexや、Google Groupsや、githubに情報が散らばってますけど、とりあえずここから行けばよし。
AutoMapperの本家のページ
マイコミジャーナルにも記事があったので載せておきます。
AutoMapperでオブジェクト間のデータコピーを行う