ラベル ASP.NET の投稿を表示しています。 すべての投稿を表示
ラベル ASP.NET の投稿を表示しています。 すべての投稿を表示

2012年4月21日

今ならASP.NET MVC, Code First, HTML5, jQueryを学べる動画が1ヶ月間無料!

ScottさんのBlogにこんなお得情報があったので転載。
Great Free Course on Building ASP.NET MVC Apps With EF Code First, HTML5 and jQuery - ScottGu's Blog

コースの内容はこちらで確認出来る。
Building ASP.NET MVC Apps with EF Code First, HTML5, and jQuery


全部で約5時間程度の動画の様だ。

この Pluralsight というサイトの動画は以前にも観た事があるけど、英語も比較的分かりやすくて良かったのを覚えている。

リスニングの練習もしながら最新の開発スキルも習得出来るのだから、これは利用しない手はない。



無料で視聴するには、まずTwitterで@pluralsightのアカウントをフォローする。


その後、申し込み用のサイトから自分のTwitter IDを入力する。


後はTwitterのプライベートメッセージでアクセスコードが送られてくるのを待つだけ。

申込み期間は4月27日までだそうなので、お早めに!







.

2012年3月24日

「n件目からm件だけを取り出したい」場合のSQLクエリの書き方

Webアプリケーションで何らかのデータの一覧を表示する際に、ページング処理(Pagenation)を行うのはほとんど当たり前の事になっている。

EntityFrameworkでLINQを使って「100件スキップしてから20件だけ取得する」というクエリーを書きたい場合は、例えば下の様な書き方になると思う。

var list = db.Books
.OrderBy(itm => itm.id)
.Skip(100)
.Take(20);

これを実行すると実際にはどのようなSQLに変換されているのかを調べてみたい。

*ただし、以下の内容はMicrosoft SQLサーバーやOracleなど、分析関数が使用可能なデータベースサーバーを使っている場合に限られた話になると思う。


Microsoft SQLサーバーを使っている場合は、クライアントとデータベースの間でやりとりされているデータの内容を確認するには、「SQL Server Profiler」を使うのが便利だ。
「SQL Server Profiler」でキャプチャを開始する前の設定画面

キャプチャされたSQLの内容

実際にデータベースに送られたSQL文を少し読み易く書き直すと、下の様な感じになる。

SELECT TOP 20 *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY [bs_id] ASC) AS [row_number]
FROM [dbo].[Bookshelves]
) AS e
WHERE e.[row_number] > 100
ORDER BY e.[bs_id] ASC

なるほど、ROW_NUMBER() という関数を使って一旦全レコードに行番号を付けて、そこから100行目以降の20件だけを取り出すというロジックになっているのか。。。


多分、この様にサブクエリを使って書くとSQLサーバーの内部で最適化が行われて、実際には全件アクセスはせずに最小のコストで必要な部分だけを返す事が出来るのではないだろうか。

この書き方は自分でSQLを書くときにも使えそうだ。一つのひな型として覚えておこうと思う。








.

2012年3月1日

ASP.NET MVC4 が面白い!

今、ASP.NET MVC 4 が面白い。まだBetaだけど、正式リリースが待ち遠しくなって来た。

ASP.NET MVC 4 Beta 関連ドキュメント

特に興味を引かれるのは、「Web API」と「Single Page Application (SPA)」だ。

Web APIについてはこの動画と次の説明を見ればほぼ概要がつかめる様になっている。
http://www.asp.net/web-api/videos

ASP.NET Web API を使ってみよう: MVC 4 新機能シリーズ - THE TRUTH IS OUT THERE


出来ればいつかはこういう解説が出来るぐらいには詳しくなりたいものだ。
ControllerとApiController - 無聊を託つ



SPAについてはこのサンプルをチェックして次の説明を読めばなんとなく分かった気になれる。
SPA Samples: The Official Microsoft ASP.NET Site

Single Page Application (SPA) を使ってみよう: MVC 4 新機能シリーズ - THE TRUTH IS OUT THERE

SPAの標準テンプレートではクライアント側のJavascriptライブラリとして「Knockout.js」と「Upshot.js」などが使われている模様。またまた憶える事が増えたなぁ。。。


早速実際に試してみた方の記事も非常に参考になる。
ASP.NET MVC 4 Beta で追加された Web API プロジェクトを試す - まめしば雑記
ASP.NET MVC 4 Beta で追加された Single Page Application を試す - まめしば雑記


現時点の感触としては、Web APIとSPAの組み合わせで、プラグイン無しでクライアントサイドで動く操作性の良いアプリケーションが作れて、かつValidationなどはサーバーサイドのロジック(というより宣言的な記述)としっかり同期させられて、とっても良い感じ! という印象だ。

早速何か作って色々試してみたい。



(こちらはMVC 3ベースのWeb APIの例。実際にDBからデータを取得する部分などはこちらも参考になりそうだ。)
WCF Web API, WCF Data Servicesとはまた違うREST APIライブラリ | OPC Diary










2012年1月4日

ASP.NETのセキュリティパッチ適用でエラー「Operation is not valid...」が発生する場合の対処

年末にこの記事を読んで、早速WindowsのWebサーバーにパッチを適用しておいた。
ASP.NET Security Update Shipping Thursday, Dec 29th - ScottGu's Blog

対処されている脆弱性の詳細な説明はこちら。
徳丸浩の日記: Webアプリケーションに対する広範なDoS攻撃手法(hashdos)の影響と対策


ところが今日になってある業務アプリケーションで「エラーが起きる」との連絡があった。

エラーの内容は、


Operation is not valid due to the current state of the object
「The URL-encoded form data is not valid.」

というもの。

いろいろテストして見ると、どうやら年末に適用したセキュリティパッチが原因らしい。

ASP.NET MS11-100: how can I change the limit on the maximum number of posted form values? - Stack Overflow

An ASP.NET request that has lots of form keys, files, or JSON payload fails with an exception and returns a 500 HTTP status code

上のページに解決方法が書かれていたので、何とかエラーは解消した。

web.config の appSettings セクション内に次の設定を追加すれば良い。
    <!-- Post Backで処理可能な最大フィールド数(Defaultは1000) -->
    <add key="aspnet:MaxHttpCollectionKeys" value="5000"/>

設定する値が大きくなるほどPostBackで処理出来るフィールド数に余裕が出来る。

でも、増やしすぎるとセキュリティパッチの意味が無くなるのであまり良くないと思う。


そもそも1000以上ものフィールドをPostBackする様な画面を作るのがおかしい。

とは思うけれども、とりあえず以前動いていたものは動く様にしないと行けないので、当面はこれで回避するしかなさそうだ。

ちなみにエラーが起きたページは、GridViewの各行の中にCheckboxやDropdownが複数配置されていて、ボタンが押された時にグリッド内の全行に対して何らかの処理をするという作りになっていた。それで大体250行以上表示している場合に1000フィールドの制限に引っかかっていた模様。

もちろんページングして一度に表示される行数を少なくしておけば問題は起きないのだけれど、「1トランザクションで全データを対象に処理する」という要件があったためにあえてページングしない様になっていたらしい。

ASP.NETだと一つのFormタグの中に全部の画面要素が入るので、何も考えずに一昔前のVBの延長的な感覚で作ってしまうとすぐにこんな事になってしまう、という良くない例だ。

でも、クライアント・サーバー型システムから移植した様な業務アプリケーションでこういうケースって、実際には結構あるんだろうなあ。











2011年12月17日

次期ASP.NETのBundling and Minification機能が良さそうだ

次のASP.NET(4.5)には「Bundling and Minification」機能というものがあるそうだ。

New Bundling and Minification Support (ASP.NET 4.5 Series) - ScottGu's Blog

サーバー側で、複数のスタイルシートやJavaScriptを一つにまとめてさらに「Minification」までして返してくれるという機能らしい。

通常だとファイルが例えば3つに分かれていればクライアントのブラウザからは3回のHTTPリクエストが発生する。でもこの機能を使うと「〇〇フォルダのCSSファイルを全部取って来て」という指定をするとサーバー側でそのフォルダ内のCSSファイルを一つにまとめてからクライアントに返してくれるそうだ。

サーバー側でまとめる時に、当然順序が正しくないとおかしな事になる。そこで、基本的にはアルファベット順になるけれども、JavaScript なら jQuery、スタイルシートなら reset.css など一般的に最初に読み込んだ方が良さそうなものはちゃんと最初に持って来てくれる。

またBundle処理の詳細やMinificationの詳細な動きを自分で制御したい場合は、それなりのクラスを継承したクラスを書いてコードから呼び出せば可能だそうだ。

ASP.NET 4.5、この他にも多くの新機能があってなかなか面白そうだ。
ASP.NET 4.5 Series - ScottGu's Blog









2011年12月9日

App Engineで課金を出来るだけ少なくする方法

下のブログを見て、ほぉーと思ったのでメモ。
 Google Developer Day 2011 Japan: 「App Engine 最新機能」 | Google Japan Developer Relations Blog 

48分もある動画だったので、飛ばしながら観ていたらGoogleの松尾さんが「このセッションで最も重要な事」と言われている部分(20:00辺り)があった。

「App Engineで課金額を気にする人は今すぐこの設定をして下さい。」と言われているので、早速やっておいた。

管理画面に入って、「Application Settings」を開くと下の2つのスライダーがある。


  • 「Max Idle Instances」を最小(1)にする。 
  • 「Min Pending Latency」を最大(15s)にする。 


これで課金が最小になるとの事。

その後それぞれのスライダーの意味の説明を聞いて、確かになるほどなと思った。 

ただし、プロダクションで使っている重要なアプリケーションの場合はこの設定を適用するのは慎重にした方が良いらしい。

趣味で作っているサイトであればこれで特に問題は無いだろうと思う。











2011年11月5日

IIS 6.0でASP.NET MVCアプリケーションを動かす方法

ASP.NET MVCのアプリケーションでは基本的にURLは拡張子無しになる。

http://www.example.com/myapplication/Home/

ところが、AS.NET MVCアプリケーションをただサーバーにデプロイしただけだとIIS6では上のURLは404エラーになってしまう。

そこで、IISの設定を少し変更する必要がある。

Deploying ASP.NET MVC to IIS 6
 http://blog.stevensanderson.com/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/

このブログには4つの方法があると書かれている。

方法1.aspnet_isapi.dllへのワイルドカードマッピングを追加する。

方法2.全てのURLに.aspxの拡張子を付け、ルーティングで制御する。

方法3.全てのURLに独自の拡張子を付け、ルーティングで制御する。

方法4.URLリライトを行う。



2と3はURLが格好悪くなるので避けたい。4の方法はちょっと設定が面倒そうだ。という事で1の方法を使う事にした。

ただし1の方法だと画像など静的なファイルも全てASP.NETが処理してしまうので、パフォーマンス的に不利になるとの事。

そこで次の対策も必要になる。
Overriding IIS6 wildcard maps on individual directories
http://blog.codeville.net/2008/07/07/overriding-iis6-wildcard-maps-on-individual-directories/
ここに書かれてある方法でサブディレクトリ単位でワイルドカードマッピングを適用しない様に設定出来るとの事。

これでとりあえずやって見ようと思う。


最後におまけで方法5も載っていた。

それは、

「Windows Server 2008に移行してII7を使う。」

確かに、それが一番!(笑)












2011年1月12日

IIS7.5 + ASP.NETで拡張子htmlのファイルを動的に処理する方法

1. Internet Infomation Service Managerで該当のサイトを選択し、「Handler Mappings」をクリック。


2. *.aspxを「PageHandlerFactory-ISAPI-4.0(または-2.0)」もしくは「PageHandlerFactory-Integrated」にマッピングしている設定の行を探して 「Edit」 をクリックし、「Executable」の内容をコピーしておく。

こんな感じか、もしくは
こんな感じになっているはず。

3. 右側の Actions から「Add Script Map...」もしくは「Add Managed Handler...」をクリックし、*.htmlに対するマッピングを追加する。Executable には上でコピーしておいたものをペーストする。

「Script Map」の場合

「Managed Handler」の場合

4. web.configの設定。

今回は下のページに書いてあった、Global.asax内のイベントで自前で変換する方法を使ったので、web.configの設定は特に無し。

Tip/Trick: Url Rewriting with ASP.NET
http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx

5. Global.asax.vb内での処理。

Private Sub Global_asax_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.BeginRequest
 Dim fullOrigionalpath As String = Request.Url.ToString()
 If fullOrigionalpath.ToLower().EndsWith(".html") Then
  Dim sUrl As String = fullOrigionalpath.Substring(0, fullOrigionalpath.Length - 4) & "aspx" '拡張子をaspxに変更。
  sUrl = sUrl.Substring(sUrl.IndexOf("//") + 2) '最初のhttp://までを除去
  sUrl = sUrl.Substring(sUrl.IndexOf("/")) '次のwww.yourdomainname.comまでを除去
  Context.RewritePath(sUrl)
 End If
End Sub


Private Sub Global_asax_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.BeginRequest
    Dim fullOrigionalpath As String = Request.Url.ToString()
    Dim array() As String = Split(fullOrigionalpath, "?")

    If array(0).ToLower().EndsWith(".html") Then
        Dim sUrl As String = array(0).Substring(0, array(0).Length - 4)
        sUrl &= "aspx"                                      '拡張子をaspxに変更。

        sUrl = sUrl.Substring(sUrl.IndexOf("//") + 2)       '最初のhttp://までを除去
        sUrl = sUrl.Substring(sUrl.IndexOf("/"))            '次のwww.hostname.comまでを除去

        If array.Length > 1 Then
            sUrl &= "?" & array(1)            'クエリーストリングがあれば最後に付加
        End If
 
        Context.RewritePath(sUrl)
    End If
End Sub


以上で取りあえず拡張子.htmlのファイルへのリクエストが.aspxへのリクエストに置き換えられて処理される様になった。


---
追記 1:
BeginRequestハンドラのコードでクエリーストリングがある場合に正しく処理されない問題があったので、上記の様に修正した。


---
追記 2:
「Managed Handler」の場合はIISの管理画面を使わずに web.configの<system.webServer>内の<handlers>タグの中に下記の一行を追加するだけでもOK。

      <add name="HTML is handled by ASP.NET" path="*.html" verb="*" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" preCondition="integratedMode" />







.

2011年1月8日

IIS6 + ASP.NETで拡張子htmlのファイルを動的に処理する方法

SEO的な理由から、ASP.NETで拡張子htmlのファイルを動的に処理したいという要望があったので、設定して見た。今まで出来るとは知っていたけど実際にやってみた事は無かったので、次回の為にまとめておこう。

ちなみに拡張子をaspxよりもhtmlにした方がSEO的に有利なのかどうかについては、未確認だ。実際のところどうなんだろうか。

1. IISの設定 (IIS6の場合)

Webサイトもしくはアプリケーションのプロパティで「Home Directory」タブ内の「Configuration」を開く。

開いたら、Application extensionsの内、.aspxの設定を開いて確認し、実行パスをコピーしておく。
次に「Add」ボタンを押して追加し、aspxの設定と同じ内容を入力し、拡張子をhtmlに変えて「OK」を押す。
この時に「Verify that file exists」のチェックを外すのを忘れない様に。



2. web.configの設定 (ASP.NET 2.0の場合)

次に、拡張子が.htmlのファイルに対してリクエストが来た場合に実際には.aspxのファイルが呼び出される様に、web.configの <system.web> セクション内に urlMappings の設定を追加する。

 
<system.web>
  (省略)
  <urlMappings enabled="true">
   <add url="~/index.html" mappedUrl="~/index.aspx" />
   <add url="~/detail.html" mappedUrl="~/detail.aspx" />
   <add url="~/about.html" mappedUrl="~/about.aspx" />
   <add url="~/help.html" mappedUrl="~/help.aspx" />
  (など)
  </urlMappings>
</system.web>


この方法の難点は、ワイルドカードや正規表現が使えないので全てのページについてaddタグを個別に設定する必要がある事だ。
IIS7だともっと柔軟に設定出来るらしいが、IIS6ではサードパーティのISAPIフィルタを使わない限りはこれで我慢するしかなさそうだ。


追加の説明はこちら。
[ASP.NET]複雑なURLを別のURLにリマッピングするには?[2.0のみ、C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/503aspurlmapping/aspurlmapping.html






.