by WebSurfer
2013年7月24日 17:42
IIS に設定した ASP.NET Web サイトに、aspnet_client というフォルダが自動的に(勝手に)作られていると思いますが、これは何かという話です。
C:\inetpub\wwwroot 直下だけでなく、IIS でサイトに設定したフォルダには aspnet_client フォルダがあるはずです。(サイトではないアプリケーションルートにはないはず)
このフォルダの目的は、簡単に言うと、ASP.NET 1.1 以前で、サーバーコントロールから送られてくるクライアントスクリプトを保持するためのものだそうです。
(2016/6/1 追記:ASP.NET 3.5 まではグローバルテーマを保持するフォルダとしても利用されているそうです。詳しくは、この記事の一番下にリンクを張った Stackoverflow の記事、MSDN の「方法 : ASP.NET ページ テーマを定義する」の中の「グローバル テーマの作成」のセクションを見てください)
サーバーコントロールは、RegisterStartupScript メソッド等を使用してスクリプトを送信することもできますが、これは (1) ページのサイズが増大する可能性がある、(2) スクリプトをブラウザがキャッシュできなくなるという問題があります。
この問題に対処するために、ASP.NET 1.1 以前では aspnet_client という名前のフォルダが使用されています。このあたりの詳細説明は、MSDN ライブラリの ASP.NET 2.0 でのクライアント ファイルの処理 を見てください。
ASP.NET 2.0 以降については、サーバーコントロールのアセンブリにスクリプトファイル等のリソースを埋め込み、HTTP ハンドラ (WebResource.axd) を使って取得するようになっているので(参考: リソース埋め込みカスタムコントロール)、aspnet_client フォルダは使われません。
上記の MSDN ライブラリにも ASP.NET 2.0 のリソース埋め込みに関する説明があります。ただし、パラメータの説明などがちょっと古いようですので注意してください。
以上のようなわけで、ASP.NET 2.0 以降であれば aspnet_client フォルダは使わないので、削除しても問題なさそうです。
ただし、Stack Overflow の What is the aspnet_client folder for under the IIS structure? に説明がありますように、Windows Update などで復活することもあるそうです。なので、削除してもあまり意味はないかもしれません。
なお、.NET Framework 4 をインストールすると、aspnet_client フォルダの中に system_web\4_0_3031 というフォルダができるはずですが、これは ASP.NET 4 で aspnet_client フォルダの使用が復活したというわけではなく、もともとそういうフォルダができる仕様になっているそうです。
詳しくは、Stack Overflow の Why did the aspnet_client folder come back in ASP.NET 4? を見てください。
by WebSurfer
2013年7月12日 17:47
下の画像のように、GridView や ListView 上で日付を「昭和」とか「平成」といった和暦で表示するにはどうしたらよいかという話です。
単純に Text='<%# Bind("OrderDate", "{0:ggy年M月d日}") %>' としただけではダメです。それだけでは、たとえ CurrentCulture が "ja-JP" でも、表示は「西暦XX年Y月Z日」となってしまいます。
何故かと言えば、カルチャが "ja-JP" のとき、デフォルトで使用されるカレンダーの表示は「西暦XX」になっているからだそうです。ちなみにカルチャが "en-US" のときは「A.D.XX」となります。
これを「昭和」とか「平成」といった和暦で表示するには、デフォルトのカレンダーを、JapaneseCalendar クラス のオブジェクトを生成して、それに差し替えてやります。
以下のコードの Page_Load メソッドの中のコードのような感じです。
<%@ Page Language="C#" Culture="auto" UICulture="auto" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Threading" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Label2.Text = "CurrentCulture: " +
Thread.CurrentThread.CurrentCulture.ToString();
CultureInfo culture = new CultureInfo("ja-JP");
culture.DateTimeFormat.Calendar =
new JapaneseCalendar();
Thread.CurrentThread.CurrentCulture = culture;
}
protected void GridView1_RowUpdating(
object sender, GridViewUpdateEventArgs e)
{
string newOrderDate = (string)e.NewValues["OrderDate"];
}
protected void SqlDataSource1_Updating(
object sender, SqlDataSourceCommandEventArgs e)
{
DateTime newOrderDate =
(DateTime)e.Command.Parameters["@OrderDate"].Value;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label2" runat="server"></asp:Label>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT TOP 10
[OrderID], [CustomerID], [OrderDate] FROM [Orders]"
UpdateCommand="UPDATE [Orders]
SET [CustomerID] = @CustomerID, [OrderDate] = @OrderDate
WHERE [OrderID] = @OrderID"
OnUpdating="SqlDataSource1_Updating">
<UpdateParameters>
<asp:Parameter Name="CustomerID" Type="String" />
<asp:Parameter Name="OrderDate" Type="DateTime" />
<asp:Parameter Name="OrderID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:GridView ID="GridView1"
runat="server"
AutoGenerateColumns="False"
DataKeyNames="OrderID"
DataSourceID="SqlDataSource1"
OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="OrderID"
HeaderText="OrderID"
InsertVisible="False"
ReadOnly="True"
SortExpression="OrderID" />
<asp:BoundField DataField="CustomerID"
HeaderText="CustomerID"
SortExpression="CustomerID" />
<asp:TemplateField HeaderText="OrderDate"
SortExpression="OrderDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox1"
runat="server"
Text='<%# Bind("OrderDate", "{0:ggy年M月d日}") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("OrderDate", "{0:ggy年M月d日}") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
なお、更新する際には、和暦 ⇒ 西暦のパースをしなくても大丈夫です。
MSDN ライブラリの JapaneseCalendar クラス の説明には、"アプリケーションで JapaneseCalendar クラスを使用している場合、DateTime.Parse は年の前に表記される時代 (年号) の省略形を認識します。この省略名は、大文字と小文字を区別しないローマ字 1 文字の省略形または漢字 1 文字の省略形のいずれかです。" とあります。
もちろん省略しないで「平成」「昭和」などとしても認識します。
実際に上のコードで試してみましたが、例えば、TextBox に "H8年8月8日" と入力して[更新]をかけると、GridViewUpdateEventArgs ではそのままの文字列になっているものの、SqlDataSourceCommandEventArgs では正しく DateTime 型にパースされます。結果、DB も正しく更新されます。
ただし、当然ですが、あり得ない日付のパースはできませんので、DropDownList などを利用して入力制限した方がよさそうです。
by WebSurfer
2013年6月29日 20:13
クラッシック ASP の場合は分かりませんが、ASP.NET の場合は、セッションの「タイムアウト」状態とフォーム認証の「ログアウト」状態は違います。
ASP.NET の場合「セッションタイムアウト」というと、MSDN ライブラリの セッション タイムアウトを構成する (IIS 7) によれば、sessionState 構成要素の timeout 属性に設定した時間が過ぎたことを言います。
セッションタイムアウトすると、サーバーに保存されていた SessionState 情報が破棄されます。しかし、それ以外の影響はありません。少なくともフォーム認証には無関係です。
また、SessionState 情報、SessionID、セッション Cookie のいずれからもフォーム認証のチケットに関する情報は取得できません。
なお、SessionState 情報を格納しない場合(Session["Data"] = xxxx; というようなコードが存在しない場合)、サーバーはセッション Cookie を発行しません。(2014/7/26 追記:Global.asax に Session_Start ハンドラを追加すると話が違ってきます。詳しくは、Session_Start ハンドラの影響 を参照ください)
SessionState 情報が格納される場合に限り、SeesionID を含むセッション Cookie が発行されます。なお、セッションタイムアウトしても SessionID は書き換えられず、同じ ID が使用され続けます。即ち、Session["Data"] に保存したデータは破棄されても、ブラウザは要求のたび同じセッション Cookie を送り続けます。
一方、フォーム認証の「ログアウト」状態とは認証チケットを持っていない、もしくは認証チケットは持っていても期限切れという状態です。セッションがタイムアウトしていても認証チケットは有効と言うことは当然あります。その逆もあります。
従って、フォーム認証チケットの有無もしくは期限切れと、セッションタイムアウトとは関係なく、セッションの「タイムアウト」状態 = フォーム認証の「ログアウト」状態にはならないです。
なお、Windows 認証、統合 Windows 認証は、フォーム認証とは全くメカニズムが異なっていて、セッションもクッキーも関係ないです。