しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET MVC 5 で追加された属性ベースのルーティングを使ってモデルバインダ絡みのエラーを回避する

ASP.NET MVC を利用した開発を行っている人は、下のエラー画面を 1 度は見たことがあるかと思います。

f:id:shiba-yan:20140826173411p:plain

MVC では URL ルーティングで定義されたパラメータやクエリ文字列を、モデルバインダが適切な型へ変換してアクションの引数へバインドする仕組みになっています。この時にアクションの引数の型が int なのに null が渡されたり、アルファベットなどが指定された場合は変換に失敗しエラーとなります。

具体的に以下のアクションを例に見ていきます。

public class ArticleController : Controller
{
    public ActionResult Details(int id)
    {
        return View();
    }
}

この場合 Details アクションは int 型の id という名前の引数を取るので、アクセスする URL としては /article/details/123 という形式である必要があります。

しかし /article/details/ や /article/details/abc といったような URL でアクセスされた場合には int への変換が不可能なので、モデルバインダから例外が投げられ HTTP エラーになるという仕組みです。URL ルーティングの定義を変更し、id というパラメータが数字のみ受け付けるように正規表現で制約をかけることも出来ますが、アクションが多い場合には非常に手間がかかります。

routes.MapRoute(
    "Article",
    "article/details/{id}",
    new { controller = "Article", action = "Index" },
    new { id = @"^[0-9]+$"}
);

このようなルーティング定義をアクションごとに手動で定義していくのはとても大変ですし、間違いも多くなってしまいそうですね。しかしアクション側としては必要な型やフォーマットが決まっているので、不正な URL の場合には 404 として扱ってほしいです。

なので、もっと楽に盤石な URL ルーティングを定義するためにも、MVC 5 から追加された属性ベースのルーティングを使って定義していきたいと思います。既に MSDN ブログでとても詳細な使い方が紹介されているので、まずはこの記事を一通り読んでおいてください。

Attribute Routing in ASP.NET MVC 5 - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

割と今更感のある MVC 5 ネタですが、仕事でこのエラーがちょいちょい発生してとてもイラついたのでブログを書くことにしました。

属性ベースのルーティングは標準の URL ルーティングよりも引数へ簡単に制約をつけることが出来ます。以下の例で使っているように {articleId:int} と書くと int しか受け付けなくなります。

[RoutePrefix("article")]
public class ArticleController : Controller
{
    [Route("{articleId:int}")]
    public ActionResult Details(int articleId)
    {
        return View();
    }

    [Route]
    public ActionResult Add()
    {
        return View();
    }

    [Route("{articleId:int}/edit")]
    public ActionResult Edit(int articleId)
    {
        return View();
    }

    [HttpPost]
    [Route("{articleId:int}/edit")]
    public ActionResult Edit(int articleId, FormCollection collection)
    {
        return View();
    }
}

注意点としては、出来るだけ id といった同じ名前のパラメータを使いまわさないことと、GET と POST で同じアクション名のメソッドを定義している場合には、両方ともに Route 属性を付ける必要がある点です。属性ベースのルーティングでは、内部的に ActionDescriptor を保持しているので、同じ URL テンプレートだからと言って使い回しが効くわけではありません。

このルーティング定義で以下のような URL が有効になります。そして、それ以外の URL でアクセスされた場合には 404 になります。

  • /article/123
  • /article/add
  • /article/123/edit

試しに int が必要なパラメータをアルファベットに変更してアクセスしてみます。

f:id:shiba-yan:20140826224459p:plain

アプリケーションエラーとならずに、意図したとおり 404 として正常に処理が完了しました。

先ほどの例では、全てのアクションに Route 属性を付けていましたが、特別な URL テンプレートの指定が必要ない場合にはコントローラレベルで属性を付けることで省略が可能です。

[Route("{action}"), RoutePrefix("admin")]
public class AdminController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

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

属性ベースのルーティングは自動的に URL ルーティングを組み立てているだけなので、Route 属性の URL テンプレートを空にしてしまうとアクション全てへアクセスできなくなるので注意。

ASP.NET MVC 5.2 で Facebook アプリテンプレートが使えない問題と対応法

Visual Studio 2013 Update 1 でも ASP.NET プロジェクトを作成する時に、Facebook を選択すると Facebook アプリのテンプレートが作られます。

f:id:shiba-yan:20140729185324p:plain

しかし、このテンプレートに対して MVC 5.2 などにアップデートしようとすると、Microsoft.AspNet.Mvc.Facebook の依存関係によってアップデートに失敗してしまいます。

f:id:shiba-yan:20140729185350p:plain

ぶっちゃけパッケージメタデータだけの問題で、互換性には問題ないはずなので対応が行われると思っていましたが、ちょっと前に以下のような記事が投稿されました。

Updating the MVC Facebook API - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

要約すると Facebook の Graph API 2.0 対応を行うためのアップデートが行われたようです。Graph API 2.0 に対応した関係上、今までのアプリケーションとは互換性が無くなっています。

ASP.NET Facebook を使う

残念ながら Microsoft.AspNet.Mvc.Facebook は更新が行われないようなので、Graph API 2.0 で問題ない場合には Microsoft ASP.NET Facebook こと Microsoft.AspNet.Facebook という新しいパッケージを使うようにして対応しましょう。

NuGet で以下のコマンドを打ち込めば、新しいパッケージをインストールすることが出来ます。

Uninstall-Package Microsoft.AspNet.Mvc.Facebook.ja
Uninstall-Package Microsoft.AspNet.Mvc.Facebook

Install-Package Microsoft.AspNet.Facebook

新しいパッケージは今までとは異なり、バージョンが 1.0.0 となっているので少しだけ注意。

f:id:shiba-yan:20140729185411p:plain

あと、名前空間が新しくなっているので、そのままビルドするとエラーになります。

f:id:shiba-yan:20140729185418p:plain

名前空間の変更点は Mvc が無くなっただけなので、一括置換などで対応が可能だと思います。

//using Microsoft.AspNet.Mvc.Facebook;
using Microsoft.AspNet.Facebook;

これで問題ない気がしますが、これからは Graph API の仕様変更と戦う必要があります。例えば 2.0 では友達リストを取得するためには user_friends 権限を追加する必要があるので、アクションの修正を行います。

// user_friends を追加する
[FacebookAuthorize("email", "user_photos", "user_friends")]
public async Task<ActionResult> Index(FacebookContext context)
{
    if (ModelState.IsValid)
    {
        var user = await context.Client.GetCurrentUserAsync<MyAppUser>();
        return View(user);
    }

    return View("Error");
}

とりあえずはこれでユーザーの情報や写真が取れるようになります。

f:id:shiba-yan:20140729231210p:plain

しかし、友達一覧が出ていないのでアプリとして破綻気味ですね。残念なことに Graph API 2.0 では、このアプリに参加している友達の情報しか取れなくなったようなので空っぽになっています。

ASP.NET Facebook パッケージよりも Graph API 2.0 の変更内容の方が致命的なので、既存のアプリケーションは MVC 5.2 にアップデートするのは困難な気がしました。*1

*1:メタデータ弄って依存関係を変えてしまうという裏技は有り

ASP.NET Web Pages 3.2.1 のベータ版がリリースされました

最近は ASP.NET MVC 5.2 / Web API 2.2 / Web Pages 3.2 がリリースされました - しばやん雑記 でも書いたように Web Pages の更新がほぼ無いので、このまま vNext に進むのかと思っていたら 3.2.1 のベータで久しぶりに大きなアップデートが行われたみたいです。

知ったきっかけは中の人のツイートです。

そして ASP.NET 公式サイトに投稿された情報が以下の URL にあります。

What's New in ASP.NET Web Pages 3.2.1 Beta | The ASP.NET Site

要約すると Razor で大規模なコンテンツをレンダリングする時に LOH を圧迫していたのを、MSN チームと連携して改善したという話のようです。内容としては Gen 2 GC が大幅に削減されたことで、GC による停止時間が少なくなり、パフォーマンスが改善されたという流れですね。

Razor が LOH を沢山使う問題に関しては 2 年前から指摘されていたようです。

ASP.NET MVC / Web API / Web Pages - View Issue #585: Large responses end up on LOH when using Razor engine

この時は .NET 4.5 で GC 周り改善されるということで一旦閉じられたようですが、今月になって根本的な対応が CodePlex にコミットされました。

https://aspnetwebstack.codeplex.com/SourceControl/changeset/3fe0d348f00864e4f1eeaefbd027ea965787b892

コードを見てみると、今まではレンダリング結果が入っている TextWriter を ToString して中身を取り出していたようですが、コンテンツ次第では 85000 バイトを軽々超えてしまうことも考えられますね。そこで、今回は StringWriter の拡張メソッドとして CopyTo を追加し、内部では 1KB ごとに出力先の TextWriter へ書きこむように変更したようです。*1

とりあえず、実際に動いているサービスに 3.2.1-beta を入れてマルチバイト周りなどで問題が無いか見ていますが、今のところ特に問題なく使えています。

*1:char[1024] って 1KB ではない気もするけど

ASP.NET と IIS の HTTP エラー処理を理解する

以下のような ASP.NET アプリケーションのエラー画面を見たことない人は、ASP.NET 開発者にはいないと思います。この画面を本番環境では出すわけに行かないので普通はカスタマイズしますよね。

f:id:shiba-yan:20140703233722p:plain

しかし、ASP.NET では 404 をアプリケーション的に返しているのに、IIS のデフォルト 404 ページが表示されてしまい、悩まされた経験がある人も多いかと思います。これは ASP.NET と IIS で扱いが異なっているのが原因で、設定も別々に存在しているのでまとめておきたいと思います。

ASP.NET

ASP.NET では Web.config の system.web 要素内に customError 要素を追加して、ステータスコード別にリダイレクト先の URL を設定できるようになります。

customErrors 要素 (ASP.NET 設定スキーマ)

例えば 404 ページをカスタマイズしたい場合には、以下のような定義を追加します。

<system.web>
  <customErrors mode="On">
    <error statusCode="404" redirect="/home/error"/>
  </customErrors>
</system.web>

これで 404 エラーの場合には /home/error にリダイレクトされますが、この customError 要素での設定が有効になるのは ASP.NET のパイプライン内部だけです。

f:id:shiba-yan:20140703233922p:plain

ASP.NET MVC などルーティングを使っている場合には、静的ファイルを除く全てのアクセスが ASP.NET のパイプラインで処理されるので問題ないですが、ASP.NET 内で 404 を返した場合には意図したとおりに動作しなくなります。

例えば、以下のようにアクション内で HttpNotFound メソッドを使った場合ですね。

public ActionResult NotFound()
{
    return HttpNotFound();
}

この場合は ASP.NET パイプラインの最後で 404 にセットされるので、customError 要素での設定が無効になってしまいます。なので、IIS 側の設定も同時に行っておく必要があります。

IIS

当然ですが IIS はルーティングが使われていない、静的なコンテンツを扱う場合にリクエストされたファイルが存在しなければ 404 を返します。この挙動をカスタマイズするための機能がもちろん用意されています。

それが IIS 7 から追加された system.webServer 要素に定義できる httpErrors 要素です。

HTTP Errors <httpErrors> : The Official Microsoft IIS Site

errorMode を Custom にすることで自由に HTTP ステータスコード毎の挙動をカスタマイズできます。例えば、先ほどの ASP.NET と同じように 404 を返した時に /home/error へリダイレクトさせる設定は以下のようになります。

<system.webServer>
  <httpErrors errorMode="Custom">
    <remove statusCode="404" />
    <error statusCode="404" path="/home/error" responseMode="Redirect" />
  </httpErrors>
</system.webServer>

error 要素を追加する前に remove 要素を使って、デフォルトの設定を一応削除しておきます。設定自体は殆ど同じですが、responseMode を ExecuteURL にすることで現在の URL から移動せずにエラーページを表示することも出来ます。

ASP.NET アプリケーションで HTTP エラー画面をカスタマイズする場合には、この 2 つの設定を同時にしておくのが安全ですね。

おまけ:TaaS メソッド

実は IIS の httpErrors を知ったきっかけは、田口さんの ARR を使って 3 秒ぐらいでレスポンスを返すというテクニックでした。

Azure で ARR を使って3秒程度でレスポンスを返す | たんたか

この方法を使うと、リバースプロキシ側がタイムアウトした時に 502 が返ってしまうのですが、httpErrors を使って 502 に対応する設定を用意しておけば、どんな時でも 200 を返すことが出来るらしいです。

なので、この ARR のタイムアウトと httpErrors を使う方法を TaaS メソッドと呼んでます。

ASP.NET MVC 5.2 / Web API 2.2 / Web Pages 3.2 がリリースされました

個人的には ASP.NET vNext のほうが気になって仕方ないですが、ひっそりと ASP.NET MVC 5.2 や Web API 2.2 がリリースされてました。

NuGet Gallery | Microsoft ASP.NET MVC 5.2.0
NuGet Gallery | Microsoft ASP.NET Web API 2.2 5.2.0
NuGet Gallery | Microsoft ASP.NET Web Pages 3.2.0

Visual Studio 2013 Update 1 をインストール済みの環境であれば、NuGet でパッケージを一括更新するだけで問題ないはずです。最近はあまり更新がありませんが、一つずつ見ていくことにしましょう。

MVC 5.2

What’s New in ASP.NET MVC 5.2 | The ASP.NET Site

リリースノートは最近あまり書かず、殆どは CodePlex の Issue を見てくれと言うスタンスのようです。

気になる修正を挙げると、Knockout.js と ASP.NET MVC の組み合わせ時にモデルバインディングが腐る件 - しばやん雑記 で書いた jQuery のシリアライズ形式を MVC のモデルバインダが受け付けてくれないという件は、この 5.2 で修正されたみたいです。

ASP.NET MVC / Web API / Web Pages - View Issue #1564: FormValueProvider does not recognize array item members from jQuery posts

他にも SelectList / DropDownList 周りでグループや無効化への対応が追加されていたりしてます。

f:id:shiba-yan:20140702175128p:plain

SelectList のオーバーロードが倍ぐらいに増えています。

public class Master
{
    public static readonly List<Prefecture> Prefectures = new List<Prefecture>
    {
        new Prefecture { Id = 1, Name = "青森", Region = "東北" },
        new Prefecture { Id = 2, Name = "東京", Region = "関東" },
        new Prefecture { Id = 3, Name = "愛知", Region = "中部" },
        new Prefecture { Id = 4, Name = "大阪", Region = "関西" },
        new Prefecture { Id = 5, Name = "愛媛", Region = "四国" },
        new Prefecture { Id = 6, Name = "福岡", Region = "九州" },
    };

    public static readonly SelectList PrefectureList = new SelectList(Prefectures, "Id", "Name", "Region", (object)null);

    public class Prefecture
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Region { get; set; }
    }
}

こんなモデルを用意して、普通に DropDownList/DropDownListFor で使うと optgroup を使った形でレンダリングが行われます。

f:id:shiba-yan:20140702182021p:plain

あと、Remote 属性を特定のエリア内で使った場合、ルートに用意されたアクションを実行出来ない件も修正されました。

public class FormModel
{
    // /AreaName/User/Exists を見に行く
    [Remote("Exists", "User")
    public string UserId1 { get; set; }

    // /User/Exists を見に行く
    [Remote("Exists", "User", AreaReference.UseRoot)
    public string UserId2 { get; set; }
}

Remote 属性のプロパティして AreaReference という enum が追加されたので、これを使って現在のエリアかルートなのかを指定できます。

Web API 2.2

What's New in ASP.NET Web API 2.2 | The ASP.NET Site

Web API 2.2 では OData v4 の対応とクライアントライブラリの Windows Phone 8.1 対応が目玉っぽいです。

いつも通りですが Web API は関連する Issue が多すぎるので、詳しい人に任せたいと思います。

ASP.NET MVC / Web API / Web Pages - Issues

元々、自分はあまり Web API には詳しくないので(

Web Pages 3.2

What's New in ASP.NET Web Pages 3.2 | The ASP.NET Site

Web Pages に関しては、特に目立った更新内容が無さそうです。強いてあげれば、エラーメッセージが一部わかりやすくなったみたいですね。

ASP.NET MVC / Web API / Web Pages - View Issue #1838: Razor - Cannot trigger content mode/need better error message

Knockout.js と ASP.NET MVC の組み合わせ時にモデルバインディングが腐る件

今日も Knockout.js を使って ASP.NET MVC に POST するようなコードを書いていたのですが、モデルバインダが意図したとおりに値をバインドしてくれない時がありました。

まずは ASP.NET MVC 側のコードを見ていきましょう。難しいことはしてません。

public class ChildFormModel
{
    public string Name { get; set; }
}

public class FormModel
{
    public string Name { get; set; }
    public List<ChildFormModel> Items { get; set; }
}

[HttpPost]
public ActionResult Post(FormModel model)
{
    return Json(true);
}

簡単にコードを紹介すると、親のモデルがさらにクラスのリストを持っている形です。

それでは次は Knockout.js 側のコードを見ていきます。

var viewModel = {
    Name: ko.observable("foo"),
    Items: ko.observableArray([
        { Name: ko.observable("bar") }
    ])
};

function saveChange() {
    $.ajax({
        type: "POST",
        url: "/Home/Post",
        data: ko.toJS(viewModel)
    });
}

めんどくさかったので初期データを横着しました。ちなみに Knockout.js の Observable なモデルを普通の JavaScript オブジェクトにするためには ko.toJS メソッドを使います。

これで実際に saveChange メソッドを実行すると、Visual Studio 側でネストされた ChildFormModel の Name プロパティに値がセットされていないことがわかります。

f:id:shiba-yan:20140625211118p:plain

何故動作しないかを調べたら、POST されたデータが以下のようになっていました。

Name:foo
Items[0][Name]:bar

ASP.NET MVC のモデルバインダは Items[0].Name という形式でないと正しくバインディング出来ないようになっているので、jQuery が内部的に変換するために使っているメソッドが原因といえます。

どうやって回避するかですが、わざわざ application/x-www-form-urlencoded 形式でエンコードしなくても、ASP.NET MVC は JSON からもバインディング出来るので、難しく考えずに JSON で送ってしまいます。

var viewModel = {
    Name: ko.observable("foo"),
    Items: ko.observableArray([
        { Name: ko.observable("bar") }
    ])
};

function saveChange() {
    $.ajax({
        type: "POST",
        url: "/Home/Post",
        contentType: "application/json",
        data: ko.toJSON(viewModel)
    });
}

Knockout.js には ko.toJSON という Observable なモデルを JSON にしてくれるメソッドがあるので、簡単に JSON を送るように変更できます。

f:id:shiba-yan:20140625212624p:plain

実際に動かしてみると、今度はちゃんと値がセットされていることがわかります。モデルが複雑な場合には JSON を使うのが無難ですね。

ASP.NET MVC でページャーやパンくずリストを作るときには部分ビューなどを使うと便利

Twitter で酢酸先生が ASP.NET MVC でのビューの使い回しについて悩んでいたので、久しぶりに ASP.NET についてブログを書きます。

こういったケースの場合、ASP.NET MVC では部分ビューや子アクション、そして Razor のセクションを使うと便利に書けます。それぞれ微妙に機能が異なるので分けて説明します。

Partial / RenderPartial

別ファイルとして用意されたビューを指定された位置にレンダリングします。MvcHtmlString を返すか、直接レスポンスのストリームに書きこむかの違いで 2 種類のメソッドが存在しています。

@* MvcHtmlString を返すので @ が必須 *@
@Html.Partial("_Pager", Model.PagingList)

@{
    // コードブロックでのみ可能
    Html.RenderPartial("_Pager", Model.PagingList)
}

そして読み込まれるビューは現在のビューと同じディレクトリか、Shared ディレクトリ内に置いておくとそれが利用されます。

<!-- 本当はここで Model の値を元にページャーを組み立てる -->
<div>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>

ちなみに優先順位は当然ながら現在と同じディレクトリ > Shared ディレクトリになります。ページングで使う場合には部分ビュー側でモデルとして組み立てるのに必要な情報を、親のビューから渡す方法が普通かなと思います。

Action / RenderAction

別のアクションを実行し、その結果として返される HTML を指定された位置にレンダリングします。これも Partial / RenderPartial と同じように MvcHtmlString を返すか、直接レスポンスのストリームに書きこむかの違いで 2 種類のメソッドが存在しています。

@* 10 件分バナーを取得 *@
@Html.Action("Index", "Banner", new { count = 10 })

@{
    // コードブロックでのみ可能
    Html.RenderAction("Index", "Banner", new { count = 10 })
}

そして呼び出されるアクションは普通のアクションと何ら変わりませんが、PartialView を返すのと ChildActionOnly 属性を付けておいた方が良いぐらいですね。

public class BannerController : Controller
{
    [ChildActionOnly]
    public ActionResult Index(int count = 5)
    {
        var context = new ApplicationContext();

        var model = context.Banners.Take(count).ToList();

        return PartialView(model);
    }
}

PartialView を返すとレイアウトを無視してくれるので、部分ビューを作成した場合にはこれを使う用にした方が良いです。あと、ChildActionOnly 属性は名前の通り、子アクションからしか呼び出せないアクションであることを指定します。

何らかの処理が絡む場合には子アクションを使う場合が多い気がします。

@section / RenderSection

これは ASP.NET MVC の機能ではなく Razor 側の機能です。今までは親のビューが別のビューを読み込むといった形でしたが、セクションの場合は親のビューに子側から出力したい情報を制御する形になります。

一度は見たことがあると思うのが JavaScript の読み込みコードです。ページごとに異なる JavaScript を埋め込む必要がある場合には、親であるレイアウトに RenderSection メソッドの呼び出しだけを追加し、内容に関しては子ビューに任せる形になります。

<head>
    <script src="jquery.min.js"></script>
    @RenderSection("Scripts", false)
</head>

親では RenderSection メソッドを "Scripts" という引数で呼び出しているので、子側でも同じ名前でセクションを定義します。

@section Scripts
{
    <script>
        $(function() {
            // 何かする
        });
    </script>
}

これで実行時には jQuery の読み込みのすぐ下で script タグが埋め込まれ、ページごとの動作を実現できるようになります。あと、パンくずリストを機械的に出力できない場合には、セクションを使って実装するケースが多かったです。

RenderPage

これも ASP.NET MVC の機能ではなく Razor 側の機能です。機能としては Partial / RenderPartial に近いですが、Shared ディレクトリを認識しない点が大きな違いです。

@RenderPage("~/Views/Home/Common.cshtml")

特徴としては呼び出し時にパラメータを渡せることでしょうか。

@RenderPage("~/Views/Home/Common.cshtml", 1, 2, 3)

このように RenderPage メソッドの 2 つ目以降にパラメータを追加すると、読み込まれるビューの PageData プロパティから値を取得できます。

@* 1 - 2 - 3 と出力される *@
@PageData[0] - @PageData[1] - @PageData[2]

まあ、これは Web Pages を使った開発の時に使う機能だと思ってもらえれば問題ないと思います。

おまけ

昔に近いことをブログに書いてました。もうちょい実際に使う時向けな内容なので一緒にどうぞ。

セクションと子アクションを使って高度なレイアウトを実現する - しばやん雑記

ちなみに子アクションと OutputCache を組み合わせて使う場合には、ASP.NET MVC 5.1 以上で行った方がバグに悩まされずに済みます。

ASP.NET MVC 5.1.2、Katana 3.0.0-beta1、Helios 1.0.0-alpha1 などがリリースされていました

タイトルからわかるように過去形です。気が付いていたけど書いていなかった、もしくは完全に気が付いていなかった内容が含まれています。

Microsoft Azure が楽しすぎるのが悪いということにしてください。それではまとめます。

ASP.NET MVC 5.1.2 / Web Pages 3.1.2 / Web API 2.1 (5.1.2)

基本的に ASP.NET MVC / Web Pages / Web API は同じタイミングでバージョンが上がります。

NuGet Gallery | Microsoft ASP.NET MVC 5.1.2

NuGet Gallery | Microsoft ASP.NET Web Pages 3.1.2

NuGet Gallery | Microsoft ASP.NET Web API 2.1 5.1.2

Visual Studio 2013 Update 2 RC と同時にリリースという感じですかね。修正内容ですが、基本的にはバグ修正がメインとなっているみたいです。

ASP.NET and Web Tools 2013.2 for Visual Studio 2013 Release Notes : The Official Microsoft ASP.NET Site

CodePlex の Issue を見ていると、そろそろ 5.2 が出るんじゃないかなぁと思います。おそらくは TechEd NA 2014 のタイミングじゃないでしょうか。

ASP.NET Identity 2.0.0

割と開発ペースが Katana 並に速い ASP.NET Identity も 2.0.0 の正式版がリリースされています。

NuGet Gallery | Microsoft ASP.NET Identity Core 2.0.0

多要素認証やロックアウトなどをサポートして、普通のアプリケーションに認証を組み込む場合には非常に便利に使えそうではありますね。

Announcing RTM of ASP.NET Identity 2.0.0 - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

自分で作る必要がある場合は OWIN Security Components を使って最低限の処理を、ASP.NET Identity で要件を満たせる場合はそのまま使ってしまえば良いのかなぁと思います。

まずは SignalR の時みたいにサンプルで動作を確認してみるのが良いと思うのですが、このサンプルコードがベータのままになっていて手抜き感が漂ってます。

NuGet Gallery | Microsoft ASP.NET Identity Samples 2.0.0-beta2

正直、ちょっと先行きが不安なフレームワークです。2.0.0 でも未だにオープンソースになってないし。

ASP.NET Identity - Home

そろそろ公開してくれるんですよね、多分。

Entity Framework 6.1

特にベータの時から大きくは変わっていないですが、正式版になったので安心して使うことが出来ますね。

NuGet Gallery | EntityFramework 6.1.0

個人的には Interceptor は割と使いどころがあるんじゃないかと思ってます。

EF6.1.0 RTM Available - ADO.NET Blog - Site Home - MSDN Blogs

Index 属性は待っていた人が多そうな機能ですね。正直 Entity Framework の今後の発展がいまいち見えていないので心配ではあります。パフォーマンスもどこまで改善できるか未知数ですし。*1

Katana 3.0.0-beta1

相変わらず Katana は開発ペースが早いですね。既に 3.0.0-bata1 までリリースされています。

NuGet Gallery | Microsoft.Owin 2.1.0

といっても、特に 3.0.0 での更新内容は多いわけではなく、WS-Federation 対応の Security ミドルウェア追加と .NET 4.0 がサポート対象外になることぐらいみたいですね。

Katana Project - Home

もうちょっと基本的な機能のミドルウェアが欲しいですね。スロットリングよりもセッションとかキャッシュのが必要なケース多いと思うんですが。

Helios 1.0.0-alpha1

リリースは先月というアンテナの低さを発揮してしまいましたが、Helios もついに 1.0.0-alpha1 まで開発が進んでいるようです。

NuGet Gallery | Microsoft.Owin.Host.IIS 1.0.0-alpha1

大きな変更点は今までは IIS 8.5 と .NET Framework 4.5.1 が必須だったのが、IIS 7.5 / 8 がサポートされるようになったところでしょうか。.NET Framework 4.5.1 が必要なのは今まで通りです。

そしてこれも完全に見落としていましたが、Helios の更新履歴が Gist 上ですが公開されていました。

やはりネイティブコード部分に依存するせいか ASLR サポートとか IIS 巻き込んでのクラッシュを修正とか、内容は激しい感じがしますね。

ASP.NET "Project Helios" Changelog

信頼性とパフォーマンスの改善などリリースノートには記載されていないですが、それぞれのバージョンで色々と改善されているみたいです。夏までには正式版がリリースされるのではないかと予想しています。

*1:Roslyn 絡めてきたりしそうな気はしないこともない

Build 2014 と Windows Azure SDK 2.3 の話

Build 2014 の 2 日目が Azure の日だったので @kamebuchi こと抱かれたい男 No.1 がいつも通りまとめてくれています。概要をサクッと知りたい場合はこれで問題無いでしょう。

//build/ 2014 Day 2 Keynote (Azure成分多め) « ブチザッキ

既に Channel 9 ではほとんどのセッション動画とスライドが公開されているので要チェックですね。

Build 2014 | Channel 9

今回は ASP.NET に関する新しい話がなかったので残念ですが、とりあえず個人的におススメなセッションを紹介しておきます。

2 つめのセッションは Web サイトと Traffic Manager を使って膨大なリクエスト裁いてやるぜーとか、実際にどのくらいの RPS なのか情報が出てたり面白かったです。

Traffic Manager が Web サイトに対応したので、東日本と西日本を含めたプロファイル作成すれば、最大で 20 インスタンスまでは確保できそうな気がしますね。*1

そして Build 2014 と同時に Windows Azure SDK 2.3 が Web PI で公開されていました。見た感じ Visual Studio 2013 Update 2 で紹介されていた Azure 周りの新機能は SDK 2.3 を入れるだけで使えそうです。

f:id:shiba-yan:20140406132818p:plain

サーバーエクスプローラーは通知ハブとモバイルサービスが増えた気がしますね。モバイルサービスは .NET バックエンドが出てから初めての SDK 更新なので、Web サイトと同様に右クリックでリモートデバッグが出来るようになっていたりいい感じです。

f:id:shiba-yan:20140406133043p:plain

そして ASP.NET の新規プロジェクト作成ダイアログでは同時に Web サイトか仮想マシンを作成可能になりました。クラウドサービスはマジ空気ですね。

f:id:shiba-yan:20140406133414p:plain

プロジェクトと同時に作成しなかった場合でも、発行ダイアログから同様に Web サイトや仮想マシンの作成が出来るようになりました。

f:id:shiba-yan:20140406133639p:plain

仮想マシンを選んだ場合には IIS と Web 配置の設定までしてくれるのはかなり便利じゃないかと。

Web 配置の設定は割とめんどくさいはずだったので、Web サイトでは賄いきれないほどのスケールの場合は仮想マシンを使うということが簡単に出来るようになりましたね。

*1:実際には SQL DB の扱いとかいろいろあるけどな!!

ASP.NET 関係で最近アップデートが行われたパッケージまとめ

最近は Windows Azure Web サイトばかり弄っていたので ASP.NET 周りが疎かになってました。

先日 ASP.NET MVC のマイナーアップデートが行われていたことに気が付かなかったのがショックだったので、関係しそうなパッケージのアップデートをまとめてみます。

ASP.NET MVC 5.1.1 / Web Pages 3.1.1 / Web API 2.1 (5.1.1)

今年の頭に 5.1 がリリースされたばかりですが、約 1 か月後には 5.1.1 というマイナーアップデート版がリリースされていました。

NuGet Gallery | Microsoft ASP.NET MVC 5.1.1

NuGet Gallery | Microsoft ASP.NET Web Pages 3.1.1

NuGet Gallery | Microsoft ASP.NET Web API 2.1 5.1.1

特にリリースノートも見つからなかったので多少のバグ修正といったところでしょう。それにしても Web API の 2.1 (5.1.1) という表記はどうにももにょりますね。

Helios 0.1.5-pre

Light weight な OWIN ホストである Helios こと Microsoft.Owin.Host.IIS もひっそりとアップデートが続けられており、今では 0.1.5-pre までリリースされています。

NuGet Gallery | Microsoft.Owin.Host.IIS 0.1.5-pre

Helios と言えば先日 .NET Web Development and Tools Blog - Site Home - MSDN Blogs で初めて正式な紹介記事が公開されました。

Introducing ASP.NET Project “Helios” - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

ちょっとディープな内容に関して、補足記事も同時に公開されているので読んでおくといいと思います。

Supplemental to ASP.NET Project “Helios” - .NET Web Development and Tools Blog - Site Home - MSDN Blogs

メモリのオーバーヘッドが System.Web と Helios を比較すると、Helios の方が 96.4% 削減出来て、高密度にサイトを詰め込むことが出来るぜヒャッハー!みたいなことが書いてあります。

GC の発生頻度も抑えられるのがパフォーマンスに効いてきそうな感じです。

Entity Framework 6.1.0-beta1

他のライブラリがラピッドリリースに全力なのに対して、マイペースに開発が進められているのが Entity Framework という気がしないこともないですが、ようやく 6.1 のベータがリリースされました。

NuGet Gallery | EntityFramework 6.1.0-beta1

ちゃんと ADO.NET Team のブログで新機能とか変更点に関してまとまっています。

EF 6.1.0 Beta 1 Available - ADO.NET Blog - Site Home - MSDN Blogs

やっと Index 属性が入ったかという気分です。あとはインターセプターを使って DB のログを取りやすくなったのは喜ばしいですね。

細かいところでは LINQ で Flags 付 Enum の扱い対応と string.Concat と ToString を処理できるようになった点にも注目しておきたいです。パフォーマンスも多少は向上しているようです。

Nancy 0.22.2

最近はちょいちょい破壊的変更を入れるようになった Nancy も 0.22.2 までアップデートされました。

NuGet Gallery | Nancy 0.22.2

0.22.1 でのバグを修正したマイナーアップデートですが、0.22.0 ではそれなりに大きな修正が入っているので仕方ないという感じですね。

Nancy.Owin と Helios を組み合わせて Windows Azure Web サイトで API を公開していたりしますが、特に不具合なく運用できています。