アーカイブ

Archive for 2012年5月

ASP.NET WebFormでjQueryMobileを利用すると、jQuery.Validationと相性が悪すぎる。

ASP.NET WebFormでjQuery Mobileのページを作っていて、ハマったのでメモを残しておきます。

runat=”server”なFormを作らない=コードビハインド作れない=Postback使えない

いきなりWebFormを否定しています。jQuery Validationはformに対して設定するわけだけれど、MasterPageなんかでContentPlaceHolderをrunat=”server”なFormで囲われていると、ページごとにValidationが設定できなくて困っちゃうんですよね。

まずMasterPaceからformを消してしまいます。この時点で、コードビハインドが使えなくなるので、サーバーコントロールはもとより、PostBackやViewStateといったWebFormのプログラミングモデルはほとんど使えなくなります。実際スクリプトやCSSの参照にMasterPageを使いたいだけで、それがなかったらクライアント側はASPXでなくHTMLでもいいんですよね。サーバー側コードを動かす場合はすべてJavascript経由でWebサービスに頼ることになります。

<body>
<!-- <form runat="server" id="form1"> –>
<div>
<asp:ContentPlaceHolder ID="Contents" runat="server">
</asp:ContentPlaceHolder>
</div>
<!-- </form> –>
</body>
 
 

Formはdata-role=”page”の下に、データバインドはuniqueNameを追加する。

jQUeryValidationを動作させるにはform要素が必要になるんだけれど、jQueryMobileのページ遷移の特性上、data-role=”page”以下に配置された要素でないと、2ページ目以降は無視されてしまいます。なので、コンテンツページ側では、data-role=”page”以下に何もしないValidationのためのダミーFormを追加します。input要素にはclassにjQuery Validationの検証属性を設定します。

ここで注意したい点として、knockoutを併用する場合はデータバインド時にuniqueNameバインディングを追加してあげる事です。jQuery Validationは対象要素のidを必要とするので、このバインディングがないとエラーの表示時に混乱してしまうようです。

(あっ、、、あれ???uniqueNameバインディングは、複数ページに渡ってユニークな名前にしてくれるのかな???すべての検証が必要なコントロールに名前を付けなきゃいけないんだとしたら嫌だな。)

<asp:Content ID="Content1" ContentPlaceHolderID="Contents" runat="server">
<div data-role="page" id="FindCustomerView">
<form action="" id="FindCustomerViewForm">
<header data-role="header" data-position="fixed">
<h1>検証のテスト</h1>
</header>
<div data-role="content">
<div><label>名前</label>
<input type="text" class="required"
data-bind="text: name, uniqueName: true"/></div>
<div><label>メールアドレス</label>
<input type="email" class="required email"
data-bind="text: email, uniqueName: true"/></div>
<div><label>年齢</label>
<input type="number" class="number"
data-bind="text: age, uniqueName: true"/></div>
<input type="button" value="確定"/>
</div>
</form>
</div>
</asp:Content>

Javascript側では、viewModelを適応させるついでに、pageinitのタイミングで先程追加したFormに対してValidationを追加してあげます。
(function ($) {
karua.viewModel.topViewModel = function () {
this.name = ko.observable("");
this.email = ko.observable("");
this.age = ko.observable(0);
this.find = function () {
};
};
var viewModel;
$(document).on("pageinit", "#FindCustomerView", function (e) {
viewModel = new karua.viewModel.topViewModel();
ko.applyBindings(viewModel, document.getElementById("FindCustomerView"));
$("#FindCustomerViewForm").validate({ onsubmit: false });
});
})($);

そもそも

まぁモバイルでの値検証を、単純にデスクトップを想定した場合と同じUXでやっていいのか?という議論はまずあるだろうけれどね。

VMWare ESXi でホストしているVMのIPアドレスの一覧を取得する。

僕が管理しているESXiが、気づいたらすでに7台になっています。いつの間にこんなに増えたのやら。

どのESXiにどんな用途のサーバーを置いているか管理はしているものの、新しいVMが欲しくなった時なんかは、実際に配置されているVMの一覧や、各VMのCPUやハードディスクの割り当て状況、IPアドレスがいくつかを一気に確認したくなるわけです。

複数の環境を統合管理できるvCenterなんかを使っていれば簡単なのかもしれないけれど、使えるのはESXiだけということでスクリプトを作ってみました。PowerShellで。$hostListと$use,$passwordは環境に応じて変えてもらえば動く。。。のかな?

#Add-PSSnapin VMware.VimAutomation.Core

$hostList = @("192.168.0.10", "192.168.0.12", "192.168.0.13")
$user = "root"
$password = "*********"
$csvFile = "C:\temp\vmlist.csv"

function Main() {
"VM情報の取得を開始します。"
$report = @()
foreach ($vmHost in $hostList) {
$vmHost + "を調査中"
$report += Get-VmList $vmHost
}
$report | sort Host,IPAddress | epcsv $csvFile -Encoding Default
$csvFile + "に出力しました。"
}

function Get-VmList($vmHost) {
$server = Connect-VIServer -Server $vmHost -User $user -Password $password
$vmReport = @()
$vms = get-vm -server $server;
foreach ($vm in $vms) {
$vmReport += Get-VmInfo($vm)
}
Disconnect-VIServer -server $server -Confirm:$FALSE
return $vmReport
}

function Get-VmInfo($vm) {
$addresses = @()
foreach ($nic in $vm.Guest.Nics) {
$addresses += $nic.IPAddress
}
$addressList = [string]::join(",", $addresses)

$report = New-Object -typename System.Object
$report | Add-Member -MemberType noteProperty -name Host -value $vm.Host
$report | Add-Member -MemberType noteProperty -name Name -value $vm.Name
$report | Add-Member -MemberType noteProperty -name NumCpu -value $vm.NumCpu
$report | Add-Member -MemberType noteProperty -name Memory -value $vm.MemoryMB
$report | Add-Member -MemberType noteProperty -name UsedSpaceGB -value $vm.UsedSpaceGB
$report | Add-Member -MemberType noteProperty -name Powerstate -value $vm.Powerstate
$report | Add-Member -MemberType noteProperty -name IPAddress -value $addressList
return $report
}

カテゴリー:インフラ, PowerShell タグ: ,

GitHub for Windowsを入れてみる。

2012年5月22日 1件のコメント

GitHubのWindows向けクライアントが公開されたということで、とりあえずものは試しとインストールしてみました。とりあえずさわりだけ。

ちなみに、興味だけでアカウントは持っていたのですが、コミットするのも今回が初めてです(汗。

Big Skyさんのページがとてもわかりやすいです。

GitHub が Windows 向けクライアントを公開!

インストールと初期設定

http://windows.github.com/ にアクセスして、右上の「download 1.0 」からセットアップモジュールをダウンロードしてインストールします。セットアップモジュールを実行すると、ClickOnceのインストールが始まります。

image

インストールが終了すると、メトロアプリっぽいUIのクライアントが起動するので、GitHubのアカウントをサインアップするか、すでに持っているGitHubアカウントでログインします。

image image

image

リポジトリの追加

とりあえず何か突っ込んでみましょう。+addをクリックして新たにリポジトリーを作成するか、すでに作成済みのリポジトリーをエクスプローラーからGit for Windowsにドロップするとリポジトリーが追加されます。

+addボタンをクリックして、ファイルを追加してみましょう。

image

リポジトリー名を日本語にしたら、「repository name cannot have special characters」と怒られてしまったので、とりあえず英語で作成しておきます。

image image

リポジトリーが作成できると、ダッシュボードに表示されます。対象のリポジトリーの上でコンテキストメニューを開くと、エクスプローラーやWebブラウザーでリポジトリの場所を開いたり、Gitを操作するシェルを開いたり、リポジトリーの詳細を表示することができます。なんとシェルはPowreShell(posh-git)を使えます!!

imageimage

利用するShellの変更は、ダッシュボードの設定から、「option」画面に移動して設定することができます。この画面では、「SCAN FOR REPOSITORIES」ボタンをクリックすることで、実行中のコンピューターにあるローカルリポジトリを検索することもできるみたいです。

imageimage

初めてのコミット

作成したリポジトリーをエクスプローラーで開き、ファイルを追加すると自動的にGit for Windows側にも表示されるので、Commitしたい場合は、コメントを入力してCOMMITボタンをクリックするだけです。

image

続いて、GitHubにpublishしてみましょう。同じく「publish」ボタンをクリックすると、GitHub側に公開されます。

プロキシサーバーの設定

もしProxyサーバー経由の場合は、PowreShellからプロキシサーバーの設定を行います。ダッシュボードのコンテキストメニューから「open a shell here」を選択するか、プログラムメニューから「Git Shell」を起動して次のコマンドで設定できます。

> git config http.proxy http://proxyserver:port

ソリューション作成とライブラリの追加(knockout,jQuery,jQueryMobile)

2012年5月21日 3件のコメント

WebFormでJavascript主体なスマートフォン向けサイトを作ろう その2

と言うことで、まずはWebフォームのプロジェクトを作って、もろもろのプラグインたちを参照するマスターページを作りましょう。

プロジェクトの作成

まずは新規プロジェクトで、空のWebアプリケーションを作成します。名前はMobileTestとかにしておきましょうか。

image

必要なスクリプトの追加

次にjQueryやjQuery Mobile、Knockoutといったスクリプトたちをダウンロードして追加していきます。

Visual StudioのPackage Manager Consoleを開いてNugetからプロジェクトに追加します。

PM> install-package jquery
PM> install-package jquery.mobile
PM> install-package knockoutjs

マスターページの追加

jQuery Mobileでは、ユーザーが最初に開いたエントリーページ以降は、ページ遷移時にヘッダータグを読み飛ばすので、すべてのページには同じヘッダータグを記述して、スクリプトやCSSの読み込み漏れが起こらないようにします。

ASP.NET WebFormでは、マスターページを利用すると簡単です。

image

先程追加した、Javascriptファイルたちをマスターページに追加していきます。

<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site.master.vb" Inherits="MobileTest.Site" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title></title>    <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1"/>
    <link type="text/css" rel="stylesheet" href="~/Content/jquery.mobile-1.1.0.min.css"/>
    <script src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.2.min.js") %>' type="text/javascript" ></script>
    <script src='<%= ResolveClientUrl("~/Scripts/knockout-2.1.0.js") %>' type="text/javascript" ></script>
    <script src='<%= ResolveClientUrl("~/Scripts/jquery.mobile-1.1.0.min.js") %>' type="text/javascript" ></script> 
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

トップページの追加

次に最初に表示する画面(Top.aspx)を追加します。最初に表示する画面は、必要なスクリプト等を読み込んだSite.Masterをマスターページとして利用します。

image image

<%@ Page Title="" AutoEventWireup="false" MasterPageFile="~/Site.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div data-role="page" id="FindCustomerView">
        <header data-role="header" data-position="fixed">
            <h1>顧客検索</h1>
        </header>
        <div data-role="content">
            <input type="text"/>
            <input type="button" value="検索" />
        </div>
    </div>
</asp:Content>

画面の表示

とりあえずVisual Studioのデバック実行で画面を表示してみましょう。

こんなふうに表示されましたか?

image

現在のソリューションの状況

こんな感じです。

image

次回はViewModelの追加です。

jQuery Mobileでトースト通知

jQueryMobileでシステムからのメッセージを表示する場合に、ダイアログ表示ではなくトースト通知っぽい表示をしたかったのでこんな関数を作ります。

karua.ui.message.showToast = function (message) {
var box = $("<div class='ui-loader ui-overlay-shadow ui-body-a ui-corner-all'>"
+ message + "</div>")
.css({
"padding": "7px 25px 7px 25px",
"display": "block",
"opacity": 0.8
})
.appendTo($.mobile.pageContainer);

var left = Math.floor(($(window).width() – box.width()) / 2);
box.css({
"top": $(window).scrollTop() + 100,
"left": left
})
.delay(1500)
.fadeOut(400, function () {
$(this).remove();
});
};

ViewModel側でメッセージを表示するの良くない。とかはとりあえずおいておいて、こんなふうに呼び出せば。

karua.viewModel.topViewModel = function () {
this.keyword = ko.observable("");
this.find = function () {
if (this.keyword() == "") {
karua.ui.message.showToast("検索キーワードが空だよ");
return;
}
};
};

こんな感じで表示される。うーん。微妙に右によってますね。。。

image

「jQuery Mobile toast」「jQuery Mobile トースト」 とかだとあんまり引っかからなかったけれど、「jQuery Mobile メッセージ」「jQuery Mobile ポップアップ」とかだと同じ事やっている人結構引っかかるのね。トースト通知ってあんまりメジャーな言い方じゃないのかな。

プラグインになってないのかなーと思ったら、nugetにjquery.mobile.messageという名前で、トースト通知を行うjQueryのプラグインがすでに登録されてた。はぅー。

https://packages.nuget.org/packages/jQuery.Mobile.Message/1.6.9

特定期間の電源投入、電源断、スリープをイベントログから抽出する

とある事情で、特定期間(特定月)の電源投入、電源断、スリープに入った時間を調べたくて、使っているスクリプトを公開してみる。本当は日付ごとのTimeGeneratedの最小、最大をとりたかったんだけれど、GroupとMeasure-objectの使い方がいまいちわからずExcelにお願いしてます。

$targetYear = 2012
$targetMonth = 5
$csvFile = "C:\temp\log.csv"

write "$targetYear 年 $targetMonth 月の電源投入、電源断、スリープ状況を、$csvFile に出力します。"
$dayFrom = New-Object DateTime($targetYear, $targetMonth, 1)
$log = Get-EventLog System |
where { $_.TimeGenerated -ge $dayFrom} |
where { ($_.EventId -eq 1074) -or ($_.EventId -eq 42) -or ($_.EventId -eq 1) } |
select Index, TimeGenerated, Message
sort Index

$log | select
$log | epcsv $csvFile -Encoding Default
write "出力が終わりました。"

この頃ちゃんとつけているか、管理職の抜き打ち検査が多くて。。。
 
#PowerShell関連のエントリーが増えてきたのでカテゴリを追加しました。
カテゴリー:インフラ, PowerShell タグ:

dotPeekの正式版が出たらしいので入れてみた。

2012年5月11日 1件のコメント

.NETのアセンブリを確認する場合は、.NET Reflectorってのが定番だったんだけれど、Reflector 7が有料化後は、幾つかのベンダーは代替えツールの開発を進めていました。

で、ReSharperでおなじみjetbrains製のdotPeekが1.0になったらしいので、ちょこっと触ってみました。

インストール

インストーラーはZIP版とMSI版の2つがあり、下記のURLからダウンロードできます。

http://www.jetbrains.com/decompiler/download/index.html

起動すると、こんなスプラッシュウインドウが表示されます。

image

初めてのデコンパイル

こんなコードを記述した、VBのアセンブリを表示してみましょう。無駄にラムダ式入れています。

Module Module1

Sub Main()
Console.WriteLine((Function() DateTime.Now.ToString())())
End Sub

End Module

メイン画面にアセンブリをドロップするか、Fileメニューからアセンブリを参照し、でコンパイルする対象をDecompile Sourceからデコンパイルすると、こんな感じに表示されます。

image

デフォルトでは左側に読み込まれたアセンブリの一覧と、そのアセンブリに含まれるクラス、リソース、参照するアセンブリがツリー上に表示されます。このあたりはReflectorと変わりませんね。表示されているソースコードは、、、C#ですね。VBのソースはどうやって表示するんだろう。。。

コンパイラーが生成したコード

ラムダ式や匿名デリゲートを利用すると、コンパイラーがコンパイル時に自動的にクラスを作成します。こういったクラスたちを表示する場合は、Show Compiler-generated codeをクリックしてあげると、こんな感じに表示されます。

image

ラムダ式が_Lambda\u0024__1()というメソッドに置き換わり、VB$AnonymouseDelegate_0<TResult>デリゲートが作成されているのを確認できます。

ソースコードの参照

PDBファイルがある場合は逆アセンブリされたソースではなく、ローカルのソースコードか、公開されているソースサーバーから該当のソースコードをマッピングして表示することができます。

image

ソースコードがあれば、VBのソースが表示されます。(PDBとソースコードがある環境でわざわざこれを使うことがあるのか?)

image

Tips

キーボードショートカットの一覧が公開されています。

ReShaperを利用している場合は、