WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

reCaptcha の実装

by WebSurfer 2010年5月25日 22:18
reCaptcha の実装

BlogEngine 1.6.1 で新機能として追加された reCaptcha を実装しました。

データのストアが DB で(XML ではなく)、かつ、reCaptcha の Logging を有効にしていると現れるバグがあって、解決に手間取りましたので、そのあたりのことを備忘録として書いておきます。

匿名ユーザーがコメントを書き込もうとすると "Sorry, the following error occurred while processing your comment: コールバックでエラーが発生しました" というメッセージが出て書き込めないことでこの問題に気がつきました。

ググって調べてみると、CodePlex のサイトの Dicsussion のページで同じ問題の報告があって、バグがあることが分かりました。

問題は、以下の 2 つのファイルの中での LoadFromDataStore メソッドの戻り値の処置です。

  • \admin\Pages\RecaptchaLogViewer.aspx.cs
  • \App_Code\Extensions\Recaptcha\RecaptchaControl.cs

ストアが DB の場合は String 型、XML の場合は Stream 型として処置すべきところ、いずれも以下のように Stream 型として処置しているので、DB をストアに使用した場合にエラーとなります。

Stream s = (Stream)BlogService.LoadFromDataStore(BlogEngine.Core.DataStore.ExtensionType.Extension, "RecaptchaLog"); List<RecaptchaLogItem> log = new List<RecaptchaLogItem>(); if (s != null) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List)); log = (List<RecaptchaLogItem>)serializer.Deserialize(s); s.Close(); }

これを以下のように修正しました(CodePlex に出ていたコードと同じ内容です)。

string s = (string)BlogService.LoadFromDataStore(BlogEngine.Core.DataStore.ExtensionType.Extension, "RecaptchaLog"); List<RecaptchaLogItem> log = new List<RecaptchaLogItem>(); if (!String.IsNullOrEmpty(s)) { using (StringReader reader = new StringReader(s)) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<RecaptchaLogItem>)); log = (List<RecaptchaLogItem>)serializer.Deserialize(reader); } }

BlogEngine.Core の中にある LoadFromDataStore メソッドの方を修正する手もありそうですが、それは止めた方がよさそうです。何故なら、旧版 (1.5) では MemoryStream に変換して return するようにしているのに 1.6.1 で意図的に止めているところを見ると、何らかの理由がありそうなので。

あと、何故、認証されたユーザーなら書き込めるかも調べてみました。理由は、デフォルトの設定では、認証ユーザーの場合 reCaptcha の Logging がスキップされるので、問題のコードに処理が飛ばないためでした。

上記の修正後は CodePlex の Documentation に書いてあったとおりの手順で簡単にインストールでき、とりあえず今のところ問題なく動いています。

でも、ただでさえメールアドレスの入力が面倒なのに、これでさらに面倒になって誰もコメントしてくれなくなってしまうかもしれませんね。(汗)

追伸1
reCaptcha の Key の取得で、登録したドメインでのみ有効するのと、Global Key といってドメインに関係させない 2 つのオプションがあります。取得できる Key の数に制限はないので、自分は、本番用に前者を、開発用に後者を取得して使っています。

追伸2
コントロールパネルで Status の Enabled/Disabled の切り替えを行うと、web.config を書き換えに行くように見えます。これはファイルの中身を書き換えているのではなく、単に timestamp を変更するだけで、その理由はアプリケーションをリサイクルするためだそうです。(最初、これが原因かと思いましたがそうではなかったです。)

Tags:

BlogEngine.NET

カレンダーの表示

by WebSurfer 2010年5月23日 21:56
修正前のウィジェットのカレンダー

ウィジェットのカレンダーは、デフォルトでは左の写真のように、(1) 月曜日から始まる、(2) 曜日が二文字になる、(3) タイトルが "5月 2010" のようになります。

日本人にはあまりなじみのない表示で、イマイチ気に入らないので、修正してみました。

修正した結果がウィジェット(左サイドのパネル)の中に表示されているカレンダーです。

上記 (1) および (2) の原因は、\widgets\Calendar\widget.ascx で PostCalendar(Calendar コントロールを継承したカスタムコントロール)の FirstDayOfWeek, DayNameFormat プロパティがそれぞれ Monday, FirstTwoLetters となっているからです。

それを直接書き換えて、Sunday, FirstLetter とすれば (1), (2) の問題は解決します。 でも、国際化対応を考えて(笑)、ブラウザの言語設定が ja-JP または ja の時のみ対応するようにしました。

具体的には、\widgets\Calendar\widget.ascx.cs の LoadWidget メソッドに以下のコードを追加しました。

System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture; if (ci.Name == "ja-JP" || ci.Name == "ja") { this.PostCalendar1.DayNameFormat = DayNameFormat.FirstLetter; this.PostCalendar1.FirstDayOfWeek = FirstDayOfWeek.Sunday; }

そうすると、カレンダーの表示幅が狭くなってしまうので、\widgets\Calendar\widget.ascx で PostCalendar.Width プロパティを設定して調整しました。

上記 (3) の原因は、\App_Code\Controls\PostCalendar.cs でタイトル行をレンダリングする時 VisibleDate.ToString("MMMM yyyy") としているからです。

その部分を以下のように変更しました。

//writer.Write("</td><td style=\"text-align:center;width:100px\">" + // VisibleDate.ToString("MMMM yyyy") + // "</td><td align=\"right\">"); // 上記のコードを以下のように変更 System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture; if (ci.Name == "ja-JP" || ci.Name == "ja") { writer.Write("</td><td style=\"text-align:center;width:100px\">" + VisibleDate.ToString("yyyy年M月") + "</td><td align=\"right\">"); } else { writer.Write("</td><td style=\"text-align:center;width:100px\">" + VisibleDate.ToString("MMMM yyyy") + "</td><td align=\"right\">"); }

ウィジェットのカレンダーの中にある "View posts in large calendar" というリンクをクリックすると大きなカレンダーが表示されるのですが、 それには上記 (1), (2), (3) の問題はありません。

何故なら、FirstDayOfWeek, DayNameFormat プロパティはデフォルトになっており、 タイトル行は Calendar コントロール自体ものを表示(ShowTitle プロパティを true に設定)しているからです。

ウィジェットのカレンダーの方で、わざわざデフォルトを変更しているのは何か理由があって、それをいじると予期せぬ副作用があるかもしれませ��ので、しばらく注意して様子を見たいと思っています。

Tags:

BlogEngine.NET

日付表示の変更(2)

by WebSurfer 2010年5月21日 00:00

先の投稿 日付表示の変更(1) で、日付の表示について「"yyyy年MM月dd日 HH:mm" としなかったのは、国際化対応にこだわったからです。」などと書いたのですが、結局 "2010年5月1日 12:00" 形式にしました。

今までの形式 "2010/05/01 12:00" では、日本語表示としてはどうしてもイマイチに思えたものですから。(汗)

でも、国際対応にはまだこだわっていて(笑)、ブラウザの言語の設定が日本語(ja-JP または ja)の時のみ "2010年5月1日 12:00" 形式とし、それ以外のときは BlogEngine のデフォルトの "d. MMMM yyyy HH:mm" 形式になるようにしました。

具体的には、PostView.ascx, CommentView.ascx で以下のようにしています(下記は PostView.ascx の場合です)。

<script runat="server"> protected void Page_PreRender(object sender, EventArgs e) { System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture; if (ci.Name == "ja-JP" || ci.Name == "ja") { Label1.Text = Post.DateCreated.ToString("yyyy年M月d日 HH:mm"); } else { Label1.Text = Post.DateCreated.ToString("d. MMMM yyyy HH:mm"); } } </script> <div class="post xfolkentry" id="post<%=Index %>"> <h1> <a href="<%=Post.RelativeLink %>" class="taggedlink"> <%=Server.HtmlEncode(Post.Title) %> </a> </h1> <span class="author"> by <a href="<%=VirtualPathUtility.ToAbsolute("~/") + "author/" + BlogEngine.Core.Utils.RemoveIllegalCharacters(Post.Author) %>.aspx"> <%=Post.AuthorProfile != null ? Post.AuthorProfile.DisplayName : Post.Author %> </a> </span> <asp:Label ID="Label1" runat="server" CssClass="pubDate"></asp:Label> ・・・後略・・・

ブラウザで、言語の設定を変えると表示が変わります。IE8 ですと、[インターネットオプション]→[全般]タブ →[言語(L)]→[言語の優先順位]ダイアログで言語の設定を変えられますので、興味のある方はお試しください。

他に、カレンダーについても日本語の場合の表示を変更しました。その話は別途アップします。

Tags:

BlogEngine.NET

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2018年12月  >>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

View posts in large calendar