喜帳面の日記

50歳越えおやじのASP.NET MVC への挑戦日記です。

ASP.NET MVC Razor をやってみた。 IgniteUI 編 その1 igGridのロードオンデマンドについて(1/2)

 

ASP.NET MVC 周辺の記事を書きたいなと思います。ここしばらくは、私が運営している [喜帳面.net]でも使ってる、お気に入りの開発ツール「IgniteUI」の周辺について [喜帳面.net]での事例などを織り交ぜながら、メモを残しておきます。

IgniteUIでどんなことができるかは、以下のURLを参考にしてください。

http://jp.infragistics.com/products/aspnet-mvc

 ヘルプやAPIドキュメントは以下のページの「jQuery/HTML5」を参照してください。

jp.infragistics.com

 この記事記載時の最新のバージョンは2015 Volume 1 ですがこの記事は、2013 Volume 2 ベースでの情報です。

 

さて、「IgniteUI」といえばまず試してみたくなるのがGridですね。

igGridはあまりにも機能が多くて最初は戸惑ってしまいますよね。今回は「ロードオンデマンド」機能について思うところを記載します。

igGridを試してみようと各種サンプルやドキュメントを参照すると、View(cshtml)にGridのさまざまな定義を記述する事例を目にすると思います。で、そのサンプルを真似てコードを起こすと意外なほど簡単に高機能なGridが実装できます。「そうか、こんな感じでいいんだ了解!」っとGridの量産に入る前に、是非「ロードオンデマンド機能」を検討してみてください。Gridを沢山開発する予定がある場合「ロードオンデマンド機能」を使えば、汎用性の高いGridをより効率よく実装できる可能性があります。

 ロードオンデマンド (igHierarchicalGrid) - Ignite UI™ ヘルプ

ロード オン デマンド サンプル - Hierarchical Grid コントロールの ロード オン デマンド - Ignite UI™

 上記は、ヘルプとサンプルへのリンクで、igHierarchicalGrid(階層を持つGrid)の

説明のように感じる位置に配置されています。解説では親子の2階層でできているGridの子のデータの取得を、オンデマンドつまり親行の左端にある[+]アイコンをクリックして子の行を展開する時点で行う例が記載されています。ちなみに、ロードオンデマンド機能を使用しない階層型のGridの場合は、最初のデータ取得時に「親子の階層を持ったModelのデータ」を一括で受け取ります。 

これだけ見ると、「ロードオンデマンド機能って階層型Gridの場合の、子階層のデータを親行の展開時に取得する機能」と思ってしまうかもしれませんが、それだけではありません。ロードオンデマンドは、階層を持たないGridでも有効です。私はこの機能の最大の特徴は、「Gridの定義を、View(.cshtml)ではなくController(.cs)やModel(.cs)に記述する」ことにあると思ってます。Controller(.cs)やModel(.cs)で記述することで、View(.cshtml)に記述する場合よりも、もっと柔軟なGrid定義が可能になります。

Gridの定義をデータベースに保存しておいて、Model(.cs)で読み取り、その情報に従ってView上のGridを表示する、そんなことも可能になりますよ。

 

手前味噌になりますが、拙作[喜帳面.net]では、「取引伝票の発行」という処理でロードオンデマンド機能を使用しています。この処理のGridで一般的な手法ではなく、ロードオンデマンド機能を採用するに至った背景などをちょっと説明させてください。

この処理では、伝票を発行するにあたって、発行対象とする伝票の一覧を階層型Gridに表示し、伝票に表示する備考等を伝票毎に登録することが可能になっています。

備考等は10項目以上あり、ログインユーザーが各項目の使用有無を事前に設定可能になっています。で、ユーザーが使用しないと設定した項目については、伝票一覧Grid上にも表示されないようにしたかった訳です。

以下の画像で出来上がりの雰囲気をつかんで下さい。

f:id:SannomiyaNotes:20150714105853p:plain

 子階層行には明細行の内容を表示しています。横方向にスクロールしてGrid上の「備考等」の内容が確認できます。
各行には編集アイコンが配置されており、このアイコンのクリックで編集ダイアログが開き、「備考等」の項目が入力可能になります。
ダイアログを閉じると、編集内容がGridに格納されます。

f:id:SannomiyaNotes:20150714110428p:plain

発行対象の伝票のチェックボックスにチェックを入れて、「PDF作成」ボタンクリックすると、Grid内の伝票発行に必要な情報がAjaxでpostされた後サーバー側でPDFを作成しクライアントにダウンロードされます。

 

「備考等」の項目は、「伝票マスタの保守」で事前に使用有無の設定ができるようになっています。

f:id:SannomiyaNotes:20150714110659p:plain

見出し部が空白になっている項目は、使用しない項目として扱い、一覧のグリッド上および編集ダイアログ上にも表示されなくなります。

この処理の開発当初、私はロードオンデマンド機能を知らなかった為、使用しない設定項目をGridの描画完了時に「隠してしまう方法」をとっていました。

現在は、 ロードオンデマンド機能を利用して、使用しない設定項目については「定義しない方法」を採用しています。

 「隠してしまう方法」ですが、javascriptで hideColumnしてました。

こんな感じです。 

     
//伝票一覧 全データ レコードが描画された時、使用しない列(headerTextがnullか"")は隠す
$(document).on("iggriddatarendered", "#gridList", function (evt, ui) {
    var gridName = "#"+this.id;
    var columnslength = ui.owner.options.columns.length;
    for (i = 1; i < columnslength; i = i + 1) {                     //全列ループ
        if (ui.owner.options.columns[i].hidden == false) {
            var headerText = ui.owner.options.columns[i].headerText;//見出し取得
            if((headerText == null)||(headerText == "")){
                var key = ui.owner.options.columns[i].key;           //key取得
                $(gridName).igGrid("hideColumn", key);               //列を隠す
            }
        }
    }
});

 この方法だと、グリッドの描画中に表示されるぐるぐる画像が途中でぴたっと停止し、しばらく(ほんの数秒ですが)経過した後でGrid操作が可能になります。列を隠す処理は思ってた以上に負荷がかかっているようです。親階層の行数や子階層の行数に影響を受けるのか否かは確認できていませんが、隠す列数の増加は影響していそうです。

ほんの数秒のことなのですがちょっと気になったので、資料をいろいろ見ていて、ロードオンデマンド機能に行き当たりました。前述したように、私はこの機能って単に

子データの取得を親行の展開時に行うだけと思い込んでいました。ちゃんと読んでみると、そんなんじゃなくて、Gridの定義を.cshtlmではなく、ControllerやModel classで定義できることが解ったわけです。そう、ロードオンデマンド機能を使えば、サーバー側で、列を隠すとか、そもそも列自体無いものにしてしまう、また、列の順や見出しのテキストなど、おおよそcshtmlに記述していた内容を制御できてしまいます。

見出しのテキスト1つとっても、今までは@ViewBagを使ったり、javascriptで書き換えるとか、記述が複数個所に存在し、ちょっと面倒でした。

そこで、思い切ってロードオンデマンド機能にチェレンジしてみました。その内容は次回にアップします。

今回は以上です。

 

Visual Studio Express 2012 for Web でいってみる 32.3年経過しました

久しぶりのBlog更新です。

2012年7月よりこのブログ始めて3年が経過しました。

今回は、フリーのプログラマになりたい!!と思い立って勉強をはじめて3年経過した現状の報告です。

さて、2012年9月頃ASP.NET MVCでいってみようと決心をし、以来こつこつとシステム開発に 取組んできました。

この3年で「喜帳面.net」というサイトを作成しました。

kichoumen ホーム ページ [kichoumen フリーランスの方向け 帳簿と家計簿 喜帳面]

 無料で公開中です。是非、遊びにきてみてください。

次回からは、ASP.NET MVC周辺ねたで記事をアップする予定です。

Visual Studio Express 2012 for Web でいってみる 31.OAuth/OpenId認証(その3)MVC4でGoogle+ 認証を使う

Visual Studio Express 2012やらMVC4と今となっては化石ネタかもしれませんが、久しぶりの更新です。

さて、今般MVC4のテスト用に借りていたレンタルサーバーでは、頻繁に

アプリケーションプールのリサイクルが発生するほどWebアプリがでっかくなってしまったので、新しいサーバーに引っ越ししました。ついでにSSLにも対応してみました。そこでURLが変更になったので,「Microsoft」「Twitter」「Facebook」、「Google」を使っての外部認証ログインのURL設定を変更する必要があります。「Microsoft」「Twitter」「Facebook」については単に登録しているリダイレクト用のURLを変更するだけで対応できたのですが、Googleで躓いてしまいました。最初の設定では一番単純で何の記述も不要だったGoogleでログインすると、「OpenID auth request contains an unregistered domain.」とログインさせてくれません。あわててググってみると、どうやら従来の手法での認証は2015年4月20日には使えなくなって、新たな認証は既に停止してますみたいな情報に行き当たりました。以下を参照ください。

Migrating to Google+ Sign-In - Google+ Platform — Google Developers

どうやら、GooglePlusでの認証に切り替えればいけそうな記述なので、再度調査。

でも見つかる情報はMVC5以降のOWINを使った事例ばかりで、MVC4の事例が見つからずあきらめかけていたところ、以下のページに行き当たりました。感謝!、感謝!

Google+ Signin for ASP.NET MVC 4 | Be a Big Rockstar

このページの最後にGithubへのリンクがあります。そのリンクに従ってGithubから

「GooglePlusOAuthLogin」ZIPをダウンロードして展開するとMVC4のプロジェクトが取得できます。

 

私がやった手順は以下の通りです。

1.Google API Consoleへ行ってアプリケーションを登録する

ここんところは、以下のページを参照しました。感謝!

Using Google+ authentication in ASP.NET MVC | Be a Big Rockstar

ASP.NET MVC 5 で OAuth 2.0 を使用して Google 認証を行う方法: ある SE のつぶやき

2.Githubから「GooglePlusOAuthLogin」プロジェクトを取得

以下このプロジェクトと自分のプロジェクトを見比べながら変更しました。

3.自分のプロジェクトの「App_Start」フォルダに「GooglePlusOAuthLogin」プロジェクトから「GooglePlusClient.cs」をコピーして追加。(そのまま使用)

4.「App_Start」フォルダ内の「AuthConfig.cs」内のOAuthWebSecurity.RegisterGoogleClient();をコメントアウトし、代わりに

OAuthWebSecurity.RegisterClient(new GooglePlusClient
("1で取得したクライアントID", "1で取得したクライアントシークレット"
), "Google+", null);

を追加。

5.「Controllers」フォルダの「AccountController.cs」については、

using GooglePlusOAuthLogin; を追加

ExternalLoginCallbackメソッド

GooglePlusClient.RewriteRequest();を追加。

6.「Views」-「Account」フォルダの「_ExternalLoginsListPartial.cshtml」内のgoogleでログインボタンのvalue部分を「value="google"」から「value="GooglePlus"」に変更。

 

今のところ以上の改定作業で「GooglePlus」でのログインで自プロジェクトへのログインができるようになりました。

今後ともこれでいいのか若干不安がのこりますが、皆さんの参考になれば幸いです。

 

 

 

Visual Studio Express 2012 for Web でいってみる 30.LinqでViewからレコードを取得する際の注意

ブログにあげるか悩んでましたが、備忘として載せときます。

Linqでデータベース(SQLServer)からデータを取得する場合の注意点です。

当方Linqに不慣れなので、ちょっとややこしいデータの取得について、View側に記述していました。

ところがどうやら、View内にCROSS JOIN やUNIONがあると意図しないレコードを取得してしまう場合があります。

レコードの件数によっては、ちゃんと取得できているように見えるので、厄介です。


対応策としては、Viewをやめてストアドプロシジャにすれば良いのですが、今回は、そのままViewを使用したかったのでアドホックSQL文を発行する方法で回避しました。

<<改定前の記述>>

 var dbdata = from s in db.Viewhoge
              where   s.HogeID == hogeID
              && s.HogeName == hogeName
              select s;
 foreach (var s in dbdata)
 {..割愛..}

<<改定後の記述>>

 string sql = " SELECT * FROM Viewhoge "
            + " WHERE HogeID  = {0} "
            + " AND   HogeName = {1} ";
 var dbdata =db.Database.SqlQuery<ViewhogeClass>(sql, hogeID, hogeName);
 foreach (var s in dbdata)
 {..割愛..}