by WebSurfer
2010年10月31日 19:32
ListView の InsertItemTemplate に DropDownList を配置し、DropDownList.SelectedValue を DB に挿入するにはどのようにすればよいかという話です。ただし、.NET 4 では問題なく、.NET 3.5 に限った話です。
何故かは不明ですが、InsertItemTemplate に DropDownList を配置した場合は、DropDownList の SelectedValue プロパティを以下のように設定してもうまくいきません。「Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データバインドされたコントロールのコンテキストでのみ使用することができます。」というエラーになります。
<InsertItemTemplate>
<tr style="">
・・・中略・・・
<td>
<asp:SqlDataSource ID="SqlDataSource1" ・・・
・・・中略・・・
<asp:DropDownList ID="DropDownList1"
runat="server"
DataSourceID="SqlDataSource1"
DataTextField="CategoryName"
DataValueField="CategoryName"
AppendDataBoundItems="True"
SelectedValue='<%# Bind("memo") %>'>
<asp:ListItem Value="">空白</asp:ListItem>
</asp:DropDownList>
</td>
</tr>
</InsertItemTemplate>
なお、上記と同様な形で EditItemTemplate に配置した場合は問題なく、DB は SelectedValue でちゃんと更新されます。
この問題の回避策は、以下のように SqlDataSource.Inserting イベントハンドラで処置することです。
protected void SqlDataSource1_Inserting(object sender,
SqlDataSourceCommandEventArgs e)
{
DropDownList ddl =
(DropDownList)ListView1.InsertItem.FindControl("DropDownList1");
e.Command.Parameters["@memo"].Value = ddl.SelectedValue;
}
何故、InsertItemTemplate に DropDownList を配置した場合ダメなのかが分からなかったし、もっとスマートな解決策があるのではないか(ひょっとして、とんでもなく間抜けなのことしているのではないか)ということが気になっていましたが、どうやら .NET 3.5 のバグらしいということで、安心(?)しています。(笑)
by WebSurfer
2010年10月19日 21:02
MSDN フォーラムで、名前などの入力項目に携帯の絵文字を入力させないように、以下のステップで対応したいという話がありました。
-
ユーザーのキャリアを判定
-
キャリア別に入力の絵文字をチェック
-
絵文字が含まれていればエラー表示
フォーラムでは、このうち 2 番目のステップについて議論があり、自分が提案した方法でうまくいったそうですので、その内容を書いておきます。
ASP.NET の Web アプリのサーバー側のプログラムでは文字列は Unicode で扱われるので、絵文字に該当する Unicode 文字が分かれば、正規表現を使ってチェックできるはずです。
Wikipedia のページ 携帯電話の絵文字 によると、各キャリアの絵文字の Unicode 表現は以下のとおりとのことです。
-
au: E468-E5DF, EA80-EB88
-
DoCoMo: E63E-E6A5, E6AC-E6AE, E6B1-E6BA, E6CE-E757
-
SoftBank: E001-E05A, E101-E15A, E201-E253, E301-E34D, E401-E44C, E501-E537
-
emobile: E63E-E6A5, E6AC-E6AE, E6B1-E6BA, E6CE-E757, E600-E619
ユーザーが TextBox などに入力して POST した文字列をサーバー側で取得したとき、絵文字は上記の Unicode 文字になるはずです。
キャリア別に処置する必要がなければ、ちょっと乱暴かもしれませんが、外字全部(U+E000〜U+F8FF)を対象としてもいいかもしれません。
i-mode 絵文字入りの Shift_JIS コードを String 型の文字列 (Unicode) に変換し、正規表現を使って絵文字の有無のチェックおよび除去するサンプルを、C# のコンソールアプリで作って検証してみました。
ドコモが提供している絵文字入力ソフト「i絵文字」で、テキストファイルに簡単に i-mode 絵文字を挿入して試験できるのでお試しください。
全部の i-mode 絵文字を試したわけではありませんが、自分が試した限りでは i-mode 絵文字の有無のチェックおよび除去は以下のサンプルで可能でした。
au, Softbank, emobile も、上に紹介した「携帯電話の絵文字」のページの Unicode で pattern を作れば、チェックや除去は可能だと思います。
なお、ドコモ以外は検証していませんし、保証はできませんので、参考にするならご自分で十分検証してくださいね。
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace EmojiCheck
{
class Program
{
static void Main(string[] args)
{
// testfile.txt は試験用の Shift_JIS のテキストファイル。
string path = "testfile.txt";
if (File.Exists(path))
{
string text = string.Empty;
using (FileStream fs = File.Open(path, FileMode.Open))
{
byte[] b = new byte[(int)fs.Length];
Encoding enc = Encoding.GetEncoding("shift_jis");
fs.Read(b, 0, b.Length);
text = enc.GetString(b);
}
Console.WriteLine(text);
Console.WriteLine("----------------------------");
// i-mode 絵文字の Unicode 表現
string pattern =
@"[\uE63E-\uE6A5]|[\uE6AC-\uE6AE]|[\uE6B1-\uE6BA]|[\uE6CE-\uE757]";
if (Regex.IsMatch(text, pattern))
{
Console.WriteLine("i-mode 絵文字があります。");
}
else
{
Console.WriteLine("i-mode 絵文字はありません。");
}
Console.WriteLine("----------------------------");
// 絵文字を除去した文字列を取得
Regex rgx = new Regex(pattern);
string outputStr = rgx.Replace(text, "");
Console.WriteLine(outputStr);
}
}
}
}
d6b4a2f1-a56d-4add-971e-330b79be8628|0|.0
Tags: 絵文字
ASP.NET
by WebSurfer
2010年9月28日 14:07
ASP.NET には、アプリケーションルートに配置した web.sitemap ファイル 1 箇所にサイトナビゲーションデータをまとめて格納しておき、SiteMapPath, TreeView, Menu コントロールを利用してサイト構造の表示や移動を行う機能が用意されています。
詳しい解説は MSDN ライブラリの「ASP.NET サイト ナビゲーションの概要」に述べられています。
このライブラリの最後の方に書いてある SiteMap オブジェクトの取得について、忘れないように書いておきます。
これは自分で XmlSiteMapProvider などを初期化して取得するのではなく、ASP.NET によって自動的に生成されるサイトのナビゲーション構造のインメモリ表現であり、単純に SiteMap として参照が取得できます。
例えば、あるページの Title タグに、web.sitemap の当該項目の title を表示する場合、以下のようにできます。SiteMap の初期化を自分で行う必要はありません。
protected void Page_Load(object sender, EventArgs e)
{
Page.Title = SiteMap.CurrentNode.Title;
}
それを知らなかったので、昔は以下のようにしていたのですが、そんな無駄なことをする必要は全くなかったようです。無知でした。(恥) MSDN ライブラリの解説からは読めなかったんです。
protected void Page_Load(object sender, EventArgs e)
{
XmlSiteMapProvider provider = new XmlSiteMapProvider();
NameValueCollection attributes = new NameValueCollection(1);
attributes.Add("siteMapFile", "web.sitemap");
provider.Initialize("testProvider", attributes);
provider.BuildSiteMap();
SiteMapNode node = provider.CurrentNode;
Page.Title = node.Title;
}