powerdee.com
Google
 
このサイト内 Web
 
カウンタ

ASP.NETのTIPS

アプリ固有の文字列管理

例)DB接続文字列の管理

(Web.config)

<appSettings>
    <add key="ConnectionString"
        value="Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;" />
</appSettings>

ページの遷移について

以下の3種類を使い分ける
例)Aform.aspx -> Bform.aspxへ

1. htmlのリンクタグ(<a href?)による遷移

2. リダイレクト

(Aform.aspxの内容)

Response.Redirect("Bform.aspx?goodsId=" + this.labelGoodsId.Text);

(Bform.aspxの内容)

// クエリ文字列による値の取り出し
this.LabelGoodsId.Text = Request.QueryString["goodsId"];

3. サーバ内のリダイレクト
2通りのコーディング方法がある。

その1…HttpContext.Items

(Aform.aspxの内容)

Context.Items.Add("GoodsId", this.labelGoodsId.Text);
Context.Items.Add("GoodsName", this.labelGoodsName.Text);
Server.Transfer("Bform.aspx");

(Bform.aspxの内容)

this.labelGoodsId.Text = (string)Context.Items["GoodsId"];
this.labelGoodsName.Text = (string)Context.Items["GoodsName"];

その2…HttpContext.Handler

(Aform.aspxの内容)

public string getGoodsId {
    get { return this.labelGoodsId.Text; }
}

Server.Transfer("Bform.aspx");

(Bform.aspxの内容)

AForm a = (AForm)Context.Handler;
// ゲッターメソッドによる値の取り出し
this.labelGoodsId.Text = AForm.getGoodsId;

セキュリティについて

フォーム認証の設定

- Web.configファイルによる設定。
以下は簡単な例として、未認証ユーザはProtectedPage.aspxを開けずLogin.aspxに移動される。

<authentication mode="Forms">
    <forms loginUrl="Login.aspx" />
</authentication>

<location path="ProtectedPage.aspx">
    <system.web>
        <authorization>
            <deny users="?" />
        </authorization>
    </system.web>
</location>

- 認証チケットの発行
ID、パスワード等によるフォーム認証後、認証されたユーザへ下記の要領で認証チケットを発行する。

// 認証チケット発行
FormsAuthentication.SetAuthCookie(会員番号等, false);
// GetRedirectUrl によって、元のページ(ProtectedPage.aspx)を取得できる
Response.Redirect(FormsAuthentication.GetRedirectUrl(会員番号等, false));

- 認証チケットの破棄(LogOutボタンをクリックしたとき等)

FormsAuthentication.SignOut();

※ 認証チケットについて

デフォルトの設定は、Cookieに暗号化された値が保存される。SetAuthCookieの第2引数がfalseの場合は、一時的なCookieとしてブラウザ側のメモリ内に保存されブラウザを終了もしくはタイムアウト(既定では30分)を過ぎると破棄される。Cookieの値をハッシュによる検証を行い改ざんを防止している為、安全性は高い。

XSS(クロスサイトスクリプティング対策)について

.NET Framework1.1では、既定でクロスサイトスクリプティング対策が施されている。
内容は、クエリ文字列の中で「<」を検出すると、「HttpRequestValidationException」例外が発生する。

- この例外を発生させたくない場合は、Webフォームの「@Page」ディレクティブで以下のように設定する。

<%@ Page ValidateRequest="false" …

- また手動でHTMLエンコードをしたい場合は、Server.HtmlEncodeで行う。

Label1.Text = Server.HtmlEncode(Request.QueryString["x"]);

ボタン2度押し対策

Session変数へボタンをクリックしたという情報を保存しておく。
これは、ボタンのCleckイベントハンドラへ次のように記述する。

if (Session["click"] == null) {
  Session["click"] = "on";
  // 成功、この後の処理を継続
}
else {
  // 二度押しを通知
}

また、成功時の処理に「Button1.Enabled=false」を追加すれば、ボタンをグレーアウトしてクリックできないようにすることもできる。

セッションステート

セッションの利用方法

・セッションの設定

Session["名前"] = 値;

・セッションから値を取得

string value = Session["名前"];

・セッションIDは SessionIDプロパティから取得できる。

string id = Session.SessionID;

・クッキーレスセッションステート及びタイムアウト値はWeb.configの<sessionState>要素を以下のように設定する。

<sessionState 
        cookieless="true" 
        timeout="20" 
/>

cookieless="true"にすると、セッションIDはCookieを使用せずにURLで渡される。
timeout="20"はセッションのタイムアウトを20分に設定する。

※Sessionのセキュリティに関して
Cookieを利用しないSession変数のSessionIdはURLの一部なので、Refererによって流出してしまう。このようにして容易にセッションハイジャックされてしまうため、基本的にはCookieを使用する。また、Session変数の有効期限を短めにしたり、Session変数が不要になったら、Session.Abandonメソッドを使って破棄させる。

セッションステートの格納場所について

・インプロセスセッションステート …ASP.NETプロセス(Aspnet_wp.exe内に格納)

Web.configの<sessionState>要素に"mode"属性を以下のように設定する。

<sessionState 
        mode="InProc"
/>

・ステートサーバーセッションステート …外部ステートサーバ上に格納

コマンドラインからステートサーバを起動する。

> net start aspnet_state

Web.configの <sessionState>要素に"mode"と"stateConnectionString"属性を以下のように設定する。

<sessionState 
        mode="StateServer"
        stateConnectionString="tcpip=127.0.0.1:42424"
/>

※stateConnectionStringのtcpipはステートサーバプロセスが起動されているマシンのIPアドレスを指定する。
メリットとして、ステートサーバセッションステートだと、IISを再起動してもセッションが保持されたままになる。

アプリケーションステート

アプリケーションステートは旧式のASPとの互換性の為にある。そのため、ASP.NETでは、後述するアプリケーションキャッシュを使用する。

以下はアプリケーションステートに値を格納する。
[]は既に指定されたキーを持つ項目が既に存在する場合は追加しない。Addは追加する。

Application["hoge"] = 10.00m;
Application.Add("hoge", 10.00m);

アプリケーションステートから値を取り出す。Object型からキャストが必要。

decimal hoge = (decimal) Application["hoge"];

アプリケーションキャッシュ

アプリケーションステートと同じようにアプリケーション単位で有効なキャッシュメカニズムであり、全てのインスタンスを格納できる。

アプリケーションキャッシュに値を格納する。Global.asaxファイルに記述する場合は、Contextを使用。

Context.Cache["hoge"] = Object

aspxファイルはContextを使用しない。以下[]、Insert共に既存キーが存在する場合には、置き換える。

Cache["hoge"] = Object
Cache.Insert("hoge", Object);

Cache.Addメソッドを呼び出して追加することも可能。この場合は、引数に各種のパラメータを設定する必要がある。
(パラメータの詳細についてはMSDNライブラリの「Cache.Add メソッド」を参照

次のコード例は、CategoryListという名称のGetCategoryList()メソッド(DataTable)をアプリケーションキャッシュに挿入し、現在から1時間後にキャッシュから削除される。

if (base.Cache["CategoryList"] == null) {
    Cache.Add("CategoryList", 
        goods.GetCategoryList(), 
        null, 
        DateTime.Now.AddHours(DateTime.Now.Hour + 1), 
        TimeSpan.Zero, 
        CacheItemPriority.Normal, 
        null);
}

【補足】
Cache.NoSlidingExpirationフィールドにTimeSpan.Zeroと指定している為、相対時間(キャッシュへのアクセスがなくなってから何分後にキャッシュを破棄するか)によるポリシーは無効としている。

ビューステート

主な例として、画面初期表示時に一旦ビューステートに値を保存しておき、ボタンクリック時(ポストバック)にビューステートから値を取得する。
(ポストバック時には新たな画面用のインスタンスが生成され元の画面の値を参照することが出来ない為)

private void Page_Load(object sender, System.EventArgs e) {
    // 画面の初期表示時
    if (!IsPostBack) {
        // ViewStateに格納。
        ViewState["save"] = "この値を保存します。";
    }
}

private void btn_Click(object sender, System.EventArgs e) {
    // ViewStateより値を取得。
    Label1.Text = ViewState["save"].ToString();
}

【補足】
ViewStateは非常に長い文字列となります。その為、ViewStateに保存される情報が増えれば増えるほど、それに比例してネットワークトラフィックも増加します。
また、ViewStateはその使用の有無を「ページ単位」「コントロール単位」で設定することができます。
パフォーマンスを考慮したアプリケーション構築を行うには不必要なViewStateを使用しないことが有効です。
PageクラスおよびControlクラスの EnableViewState プロパティに true/false の値を設定します。


おすすめ書籍


Visual Studio 2005 ASP.NET 2.0 Webアプリケーション開発 Programming Technique

著者:PROJECT KySS
出版社:メディアテック出版(2006-10)
価格:¥3,864(税込)
ASP.NETでいってみよう (DB Magazine SELECTION)

著者:松本 美穂、百田 昌馬
出版社:翔泳社(2005-03-23)
価格:¥2,730(税込)


ページTopへ / ▲Homeへ