正直、ASP.NETとその周辺はどうなのよ


ASP.NETで開発する場合、Expression Web2をデザインツールとして使っている方も結構といるだろう。


これはASP.NETと連携性が良いからである。簡単に言えば、ASP.NETの独自タグ(asp:XXXX で始まるタグ)を解釈して表示してくれるのである。まあ、これは、Dreamweaverのほうでも一応解釈してくれるのだが。


私はMicrosoft MVPという立場上、あまりMicrosoft社の製品をボロクソ言うことは憚れるのだが、それでもExpression Web2は正直まだ作りかけという感じがプンプンする。


例えば、市販のコンポーネントを配置したページを表示しようとすると、これがうまく表示できない。自分で.NETのGACに登録すれば表示できるらしいのだが、「ユーザーにそんなことさせるか?」という気がする。


あと、ASP.NET標準ではないaspタグがあると開いた瞬間クラッシュ(不正終了)する。いまどきエラー内容も表示せずクラッシュしちゃまずいでしょ、クラッシュ。おまけに市販のカスタムコントロールを配置したページを開くと、 とか大量に勝手に挿入してくれたり、カスタムコントロールをドラッグ移動するときにソースに空行を大量に挿入してくれたりする。


カスタムコントロールを配置したページを編集するなら無償で使えるVisual Web Developerのほうが断然マシである。ASP.NET標準コンポーネントは出来が悪いので市販のコンポーネントの出来が良いので、ASP.NETならば市販のコンポーネントを使って開発するのが普通だと思うが、これではExpression Web2は使えない。早くサービスパックが出て欲しい。良くは知らないけど、これでもExpression Web2だと言うのだから驚きで、完成度的には1か、1.0αぐらいの出来だと思う。無償のVisual Web Developerより出来の悪いものを販売しちゃまずいでしょ、販売しちゃあ。


じゃあ、ユーザーコントロールなら満足に編集できるのかと言うと、これまた微妙。先日、「ちょっとサイトでも作ったるかい!」と思って、Expression Web2でユーザーコントロールのデザインなんかをやっていたのだが、Expression Web2の上では、きちんと表示できているのに、実際にVisual Studioから実行して表示させてみたらうまく表示されない。原因を調べていると、あるCSS classが適用されていない。Expression Web2でもVisual Studioでもユーザーコントロールの編集画面ではきちんと表示されているのにいざそれを実際に表示させるとうまく表示されないのだ。


さらに原因を調べていくと、CSSクラス名で、"titledBox"と書かなければならないところ、"titledbox"と小文字を指定しまっていた。言うまでもなくASP.NETはディフォルトで


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
のようなタグを出力するが、XHTML 1.0ではCSS class名はcase sensitiveである。だもんで大文字と小文字を間違えると別名扱いされて、そのstyleが反映されない。ところが、Expression Web2やVisual Studioのデザイン画面では、コントロールを編集しているものだから、上の宣言が無く、case insensitiveである。だもんでうまく表示されるのだ。全然WYSIWYGじゃない。警告ぐらい出してくれても良さそうなものなのに、と思う。こういう原因を調べようとしたとき、テキストエディタ片手にブラウザで見たほうがよっぽど早い。


あと、ASP.NET3.5らしいが、これまた作りかけという匂いがプンプンする。配置しているコントロールの変数名を変えようとリファクタで変数名の変更をしてもaspxのほうには反映されず、手作業で編集していかなければならない。これは正直ひどい。どう見ても作りかけである。


LINQ to Entitiesも世間で思われているほどお利口じゃない。あるレコードの値を1加算したかったので、Linqでレコードを取ってきて、インクリメントして、SaveChangesで書き戻したら、SQLのSELECT文とUPDATE文が二回にわけて発行されているようだった。1足したいだけなのに!これでは、atomicで無くなってしまう。


「じゃあ、よく使うので、せっかくなのでストアドで書いとこかい!」と思ったら、ストアドの編集画面でIntelliSenseが働かない。ストアドでIntelliSenseが使いたければ、SQLPrompt( http://www.red-gate.com/products/sql_prompt/index.htm )という製品を買わないといけないらしい。$195である。たかがストアドのIntelliSenseのためだけに、である。


ストアドを使う気力がすっかり萎えた。そんな時は、SqlDataSourceである。これを貼り付けて、Update文をクエリビルダで編集すると次のようなタグが挿入されて、






これに対して


SqlDataSource1.UpdateParameters["番号"].DefaultValue = number.ToString();
var update = SqlDataSource1.Update();

こんな感じでパラメータを渡して使えるのだが、DefaultValueはstring型である。DbTypeでInt32を指定しているのに数字をわざわざstringに変換して渡す必要がある。どうも設計がおかしい。ついでに言えばSelectのほうは、


var select = SqlDataSource1.Select(DataSourceSelectArguments.Empty);

引数が必須である。これは、何の気まぐれなのだろうか?なぜそれをpropertyにしないのか私にはわからない。


話を少し戻そう。LINQ to Entitiesの参照系のクエリオプティマイザは大変利口なのだが、更新系はかなりひどい。最適化らしきものはほとんどされない。あとなんだか設計がおかしい。SaveChangesにしても、例えばPK(Primary Key)が重複していると、UpdateExceptionが飛んでくる。それはいいのだが、これを検知する手段が、次のようになる。


try
{
db.SaveChanges();
}
catch (UpdateException e)
{
System.Data.SqlClient.SqlException sqlException
= e.InnerException as System.Data.SqlClient.SqlException;
if (sqlException != null)
{
if (sqlException.Number == 2627)
{
// Primaryキーの重複エラー?
return DBUpdateStatus.PK重複;
}
//else if (sqlException.Number == 2601)
//{
// // Primary以外のuniqueキーの重複エラー?
//}
}
throw;
}

こう書かないとPK重複でupdateできないことを検知できない。(ASP.NET使いのみなさんは、さらっと書けるのだろうか?)


まあ、これは百歩譲って仕方ないとして、SaveChangesで例外が飛んできた場合、そのあとAcceptAllChanges()を呼び出すまでずっとSaveChangesを呼び出すとこの例外が飛び続ける。この仕様、どうもおかしい気がしないでもない。あと、AcceptAllChangesも、名前が紛らわしい。変更をacceptしてるのではなく、変更をdiscardしているように思うのだが、この名前はいかがなものか。


あと、AcceptAllChanges()なんか呼び出さずに、DatabaseEntitiesは使い捨て(以下のように)にすべきと言われるかも知れない。


try {
using(var DB = new DatabaseEntities())
{

}
} catch {

しかし、この書き方だと、DatabaseEntitiesを生成するごとにDBに接続しに行くので、20ms程度かかるのだ。VisualStudio上だけかと思ったら、本番環境でもはやり20msほど時間を要する。DBのコネクションはpoolingしてあるんじゃなかったの?なんなの、これ。


だから、必然的にDBEntitiesはsingletonにしておいて、それを使い回すような書き方に私はしているのだが、そうなるとAcceptAllChangesのお世話にならざるを得ないのである。


まあ、私は「これを解決しようとして別の手段をとったら、それがまた別の問題を引き起こす」のを繰り返している状態なのだが、これでASP.NET 3.5なのだから驚く。この分じゃあ、ASP.NET7.0ぐらいにならないと満足なものにならないのではないかと思う。


いろいろASP.NETの欠点ばかりを書いたが、ASP.NETでの生産性は非常に高い。ASP.NETにはカスタムコントロールという仕組みが用意されており、この仕組みが良く出来ているので、ASP.NETでは商用コンポーネント市場が活発なのである。


昔は、GUIのコンポーネント市場と一口に言っても
・描画手段がMFCなのかDirectXなのかOpenGLなのかメモリイメージなのか
・言語はCなのかC++なのかVBなのかdelphiなのか
・提供バイナリはCOMなのかDLLなのかlibなのか
・コンポーネントとして綺麗に分離できるほど言語的に洗練されていなかった
などいろいろな問題を抱えていたのでそれほど成熟したものではなかった。


しかし、ASP.NETだとそういう問題がクリアされているし、ターゲットがブラウザなので非常に表現力豊かである。市販のカスタムコントロールを組み合わせてWebアプリを作れば、そんじょそこらのデスクトップアプリより見栄えやユーザーエクスペリエンスの上で良いものが作れるようになってきている。


また、自分が使いたいユーザーコントロールを大量に作っておけば、ASP.NETの再生産性は非常に高い。
慣れてくれば鼻歌まじりに部品をドラッグして、大半はマウス操作だけでサイトを作っていける。


是非、みなさんも3.5なのに作りかけくさいASP.NETの世界を体験していただきたい。