none
Shift-JISサイトでUnicode文字を出力するとき、実体参照で出力させる方法 RRS feed

  • 質問

  • ASP.NET2.0 / Visual Studio2008 / C#

    (PC向け)Shift-JISのサイトを構築しています。
    PC向けなので実体参照を使えばUnicode文字も表示してもらうことは期待できるのですが、ASP.NETではどうすれば実現できるでしょう?

    <asp:Button Text="&#x2611;" />
    などとやってみても、コントロールのプロパティ値として取り込まれた時点で文字列"☑"となってしまい、それをShift-JISで出力しようとした時点で
    <input type="submit" value="?" />
    と変換を拒否されてしまいます。

    <input type="submit" value="&#x2611;" />
    と出力されるようになる方法はないでしょうか。

    2009年8月13日 4:57

回答

  • > Shift-JISサイトであっても、
    > <input type="submit" value="&#x2611;" />
    > と出力することで問題なく実現できるはずなのですが、asp:Buttonはそれをやってくれないのかなという質問です。

    できないようですね。サーバーで処置されるときに文字化けしてしまうようです。

    <input type="submit" value="&#x2611;" /> で OK でも、それに runat="server" を追加すると化けてしまいます。

    PC 向けなら Shift_JIS にこだわらないで、問題のページだけでも UTF-8 にすれば何の問題もなくなるのでは? 

    • 回答としてマーク miuras_net 2009年8月17日 7:42
    2009年8月13日 13:50
  • ControlAdapter を使い asp:Button の出力の Unicode->Shift-JIS へのエンコード処理を置き換える必要があるでしょう。

    標準では HttpResponse の Write では EncoderReplacementFallbackBuffer http://msdn.microsoft.com/ja-jp/library/system.text.encoderreplacementfallbackbuffer(VS.80).aspx が利用される為、Shift-JIS表現が不可能な文字が置き換えされます。
    この置き換え処理を独自の EncoderFallbackBuffer を実装する事で HTML実体参照での置き換えを実行できるようにし、これを使ってレスポンス出力を変換するように ControlAdapter http://msdn.microsoft.com/ja-jp/library/system.web.ui.mobilecontrols.adapters.controladapter.aspx を作成して HttpResponse オブジェクトと Buttonオブジェクトの間に割り込むという手順で実現できるでしょう。

    ( ControlAdapterはMobileControls名前空間にありますが別に携帯向けというわけではありません、通常のコントロールを携帯対応させるための汎用的な割り込み機構ですのでPC向けとしても利用できます)
    Kazuhiko Kikuchi
    • 回答としてマーク miuras_net 2009年8月17日 7:42
    2009年8月14日 0:49

すべての返信

  • PC向けなので実体参照を使えばUnicode文字も表示してもらうことは期待できるのですが、ASP.NETではどうすれば実現できるでしょう?

    Shift-JISで表示している画面の一部分をUnicode文字で表示するという意味でしょうか?
    AAAAAAAABBBCCCCCCC ←ここのBBBだけUnicodeを渡して文字表示させる?

    なんか無理な気がするんです。



    http://blogs.wankuma.com/hatsune/
    2009年8月13日 6:31
  • AAABBBCCCという例の意味があまり理解できないのですが、

    <input type="submit" value="☑" />
    <input type="submit" value="☑" />

    と出力したいと捉えてください。(asp:Buttonでです)

    Shift-JISサイトであっても、
    <input type="submit" value="&#x2611;" />
    と出力することで問題なく実現できるはずなのですが、asp:Buttonはそれをやってくれないのかなという質問です。
    2009年8月13日 7:08
  • > Shift-JISサイトであっても、
    > <input type="submit" value="&#x2611;" />
    > と出力することで問題なく実現できるはずなのですが、asp:Buttonはそれをやってくれないのかなという質問です。

    できないようですね。サーバーで処置されるときに文字化けしてしまうようです。

    <input type="submit" value="&#x2611;" /> で OK でも、それに runat="server" を追加すると化けてしまいます。

    PC 向けなら Shift_JIS にこだわらないで、問題のページだけでも UTF-8 にすれば何の問題もなくなるのでは? 

    • 回答としてマーク miuras_net 2009年8月17日 7:42
    2009年8月13日 13:50
  • ControlAdapter を使い asp:Button の出力の Unicode->Shift-JIS へのエンコード処理を置き換える必要があるでしょう。

    標準では HttpResponse の Write では EncoderReplacementFallbackBuffer http://msdn.microsoft.com/ja-jp/library/system.text.encoderreplacementfallbackbuffer(VS.80).aspx が利用される為、Shift-JIS表現が不可能な文字が置き換えされます。
    この置き換え処理を独自の EncoderFallbackBuffer を実装する事で HTML実体参照での置き換えを実行できるようにし、これを使ってレスポンス出力を変換するように ControlAdapter http://msdn.microsoft.com/ja-jp/library/system.web.ui.mobilecontrols.adapters.controladapter.aspx を作成して HttpResponse オブジェクトと Buttonオブジェクトの間に割り込むという手順で実現できるでしょう。

    ( ControlAdapterはMobileControls名前空間にありますが別に携帯向けというわけではありません、通常のコントロールを携帯対応させるための汎用的な割り込み機構ですのでPC向けとしても利用できます)
    Kazuhiko Kikuchi
    • 回答としてマーク miuras_net 2009年8月17日 7:42
    2009年8月14日 0:49
  • こういう方法が絶対にあるはずだと思い探していたのですが見つからなかったのです。ありがとうございました。

    自前で実装したコントロールアダプタを、App_Browsers/.browsers に登録するという手順でよいのですよね。
    2009年8月17日 7:38
  • 素直にUTF-8がもちろん最もいいのですが、旧システムのしがらみがいろいろと…。
    ただ、当該ページだけでもというのは可能かもしれないので、そちらも模索してみることにします。
    2009年8月17日 7:41
  • > 素直にUTF-8がもちろん最もいいのですが、旧システムのしがらみがいろいろと…。

    事情は分かりませんが、どうしても Shift_JIS で、かつサーバーコントロールを使う必要があるのでしょうか?

    そうであれば、WebControl を継承したカスタムコントロールを作る手はあります。例えば以下のような感じ。決して
    スマートな方法とは言えませんけど・・・

    public class MyButton : WebControl
    {
        public string Text
        {
            get
            {
                string s = (string)ViewState["Text"];
                return (s == null) ? "&#x2611;" : s;
            }
            set
            {
                ViewState["Text"] = value;
            }
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Input;
            }
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
            writer.AddAttribute(HtmlTextWriterAttribute.Value, Text, false);
        }
    }

     なお、Button を継承するのは、Text プロパティを override または隠蔽できないので、ダメそうです。

    > 自前で実装したコントロールアダプタを、App_Browsers/.browsers に登録するという手順でよいのですよね。

    それはかなり大変そうです。それに、本来の目的とは違うような気がします。

    以下のサイトから、独自の .browser ファイルを定義し、ControlAdapter を使って Menu や GridView などの既
    存のコンロトールを書き換えているソースコードを入手できますので、参考にしてみてください。

    ASP.NET 2.0 CSS Friendly Control Adapters 1.0
    http://www.asp.net/cssadapters/

    kazku さんが意図されている解決方法は、自分が思っているものと違って、もっとスマートなものかもしれませんが・・・
    2009年8月18日 14:02
  • >もっとスマートなものかもしれませんが・・・

    たいして変わらないはずです。
    SurferOnWwwさんの案との違いは、これまでに ASP.NET アプリケーションに貼ったすべての asp:Button コントロールに対して同じ要件を
    アプリケーションの個別部分に対しては一切の書き換えをなく実装できるという事だけです。

    ・派生/カスタムコントロールを実装したら使う側の対応が必要
    ・ControlAdapterを使う場合インストールすればアプリケーション内での使う側としての対応は不要

    1か所だけ対応するのであれば派生/カスタムコントロールを作る方が良いかもしれませんが、asp:Buttonを何回も何ページもで使っていて同一要件に
    基づいて変更する必要があるのであれば ControlAdapter が選択肢に上がってくるって事ですね。

    んで

    ・Shift-JISで表現できないUnicode文字を実体参照させる

    という要件はドメイン(業務要件)依存性が全くないに近くShift-JISで表現できないUnicode文字を使うアプリケーション一般で結構必要になってきますのでカスタムコントロールで作るよりは ControlAdapter向きだと思います。特に他のアプリケーションで必要になったら AppBrowsersに入れれば良いだけという特性からアプリケーションでの対応は不要で、実体参照化するだけであれば悪い副作用が出る可能性もほぼ無いという特性を期待できるのでコード資産としての価値も高いでしょう。

    取り急ぎでやっつけ対応ならカスタムコントロールないし派生コントロールで対応。自分の持ってるコード資産に入れるつもりならControlAdapterが良いと思います。


    Kazuhiko Kikuchi
    2009年8月19日 3:59
  • 質問者です。
    その後スレッドをフォローしておらずお返事が遅れました。

    カスタムコントロールとコントロールアダプタの使い分けについてお示しの方針、とても明確で参考になりました。

    自分があえてカスタムコントロールでなくasp:Buttonでやれたらいいと感じていた理由はこれだったのかというところです。
    2009年9月7日 1:05