KCP+携帯でASP.net1.1モバイルフォームで文字化け

昨日の続き → http://d.hatena.ne.jp/twisted0517/20100114/1263457826

結局のところ問題はxhtmlに対応してるKCP+端末にもwmlを投げてるって事なので、Docomoに投げてるのと同じようにhtmlベースで返してやれば問題解決すんじゃね?的な発想で進めてみる。

バイス振り分けの仕組み

MSDNの記事に詳しく出てた。


バイス プロファイリングにより、どのようなモバイル デバイスの機能も判断できるようになり、ASP.NET モバイル コントロールを拡張してサポートすることが可能となります。ASP.NET モバイル コントロール (以前は Microsoft Mobile Internet Toolkit) は 200 以上のサポートを提供しており、マイクロソフトはここのデバイス アップデート ウェブサイトからダウンロードできる、定期的なデバイス アップデートを提供することで、新規デバイスに対する継続的なサポートを行っています。ASP.NET モバイル コントロールを拡張して、デバイス アップデートからまだサポートされていないデバイスを使用する必要がある場合、このツールを使用してデバイスをプロファイルできます。

要するにmachine.configかweb.configのbrowserCapsで対象のブラウザの属性を設定してると。
実行時はその設定を元にうまいことそのデバイスが受け取れる文書に整形して送ってるっつーことか。

ざっくりとbrowserCapsを変更してみる

今稼働中の.netFrameworkはv1.1.4322で、そのMachine.configのKCP+携帯のbrowsercapsはどうなってるかっつーとPhone.com携帯互換として動作してるようなのでこのへん

<case
	match="(UP\.Browser)|(UP/)">
	browser = "Phone.com"
	inputType = "telephoneKeypad"
	canInitiateVoiceCall = "true"
	canSendMail = "false"
	cookies = "true"
	preferredRenderingType = "wml11"
	preferredRenderingMime = "text/vnd.wap.wml"
	rendersWmlDoAcceptsInline = "false"
	rendersWmlSelectsAsMenuCards = "true"
	rendersBreakBeforeWmlSelectAndInput = "true"
	supportsRedirectWithCookie = "false"

	optimumPageWeight = "700"
	isMobileDevice="true"

	<!-- Phone.com 3.x, 4.x and 5.x -->
	<filter>
		<case
			match="((?'deviceID'\S*) UP/\S* UP\.Browser/(?'version'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*)/\S* UP(\.Browser)*/(?'version'\S*))|(UP\.Browser/(?'version'\S*)-(?'deviceID'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*) UP\.Browser/(?'version'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*)/(?'DeviceVersion'\S*) UP/(?'version'\S*))|((?'deviceID'\S*)/(?'DeviceVersion'\S*) UP.Browser/(?'version'\S*))">
			<filter
				with="${version}"
				match="(?'browserMajorVersion'\d*)(?'browserMinorVersion'\.\d*).*">
				majorVersion = ${browserMajorVersion}
				minorVersion = ${browserMinorVersion}
			</filter>
			<filter>
				<case
					match="[45]"
					with="%{majorVersion}">
					type = "Phone.com %{majorVersion}.x Browser"
					preferredImageMime = "image/vnd.wap.wbmp"
					requiresUniqueFilePathSuffix = "true"
				</case>
				<case
					match="3"
					with="%{majorVersion}">
					type = "Phone.com 3.x Browser"
					preferredImageMime = "image/bmp"
					requiresUrlEncodedPostfieldValues = "true"
					requiresUniqueFilePathSuffix = "true"
					canRenderInputAndSelectElementsTogether = "false"
				</case>
			</filter>

			version = %{majorVersion}%{minorVersion}

			<filter
				with="${gatewayVersion}"
				match="(?'gatewayMajorVersion'\d*)(?'gatewayMinorVersion'\.\d*).*">
				gatewayVersion = UP.Link/${gatewayVersion}
				gatewayMajorVersion = ${gatewayMajorVersion}
				gatewayMinorVersion = ${gatewayMinorVersion}
			</filter>
			<filter>
				<case
					match="Alcatel-BE4"
					with="${deviceID}">
					mobileDeviceManufacturer = "Alcatel"
					mobileDeviceModel = "301"
				</case>

Up\.Browserにマッチしたら無条件でpreferredRenderingTypeが"wml11"になっとるな。

つまりはAUに限らずUp.Browser使ってる携帯だったら種類を問わずにwmlで返す仕様になっとると。
ならこれをweb.configで上書きしてやりゃokかな。

web.configで上書き

KDDIのページを見る限り

■WAP2.0ブラウザ搭載端末の場合

au W21SA であれば

HTTP_USER_AGENT=KDDI-SA31 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0

と表示されます。
これは、

という構成になります。

※ WAP2.0ブラウザ搭載端末用に (i-mode用などの) HTMLで記述したページを表示させる場合、User_Agent中の「KDDI」の文字列の有無により判定することが可能です。
KDDI」有り:HTMLコンテンツを配信
KDDI」無し:HDMLコンテンツを配信

となっているので、KDDIにマッチさせてxhtmlを返すようにweb.configにbrowserCapsを追加。

<browserCaps>
<use var="HTTP_USER_AGENT" />
<case match="(KDDI)">
    preferredRenderingType = "html32"
    preferredRenderingMime = "text/html"
</case>

が、うまくHTMLが出力されない。なーぜだー。
デバッグからMobileCapabilityをチェックしてみるもMobileCapability.PreferredRenderingType="html32"になっててハンドリングは出来ているらしい。

何か根本的に間違えてるのかもしれない

と、思って"browserCaps AU"あたりでぐぐってみるとなんかあった。

モバイルデバイスの機種情報について

モバイルデバイスのブラウザ情報は、 ASP.NET 1.1まで、 Microsoft の DeviceUpdate により提供されていた。
http://www.microsoft.com/japan/msdn/vstudio/device/ASPNET_MCDU4_eula.aspx

((http://download.microsoft.com/download/D/1/E/D1E5C5F3-FAAB-4548-BC9B-970870680837/offline_082707.pdf (PDF)))

('A`)うそーん。

ASP.NET 1.1の DeviceUpdateをインストール

上のリンクは404だったのでInternetArchiveから拾ってくる。
http://web.archive.org/web/20080417193111/http://www.microsoft.com/japan/msdn/vstudio/device/ASPNET_MCDU4_eula.aspx

ダウンロードして実行すればさくっと終了。一応IISのワーカープロセスも再起動。

何事もなかったようにXHTMLが表示されるようになった

_| ̄|○ l|i!l 俺の数日間は一体・・・

悔しいので何がアップデートされてるのか確認

Machine.configがアップデートされるようなので中身*1を確認。
deviceupdate.config、deviceupdate3.config、deviceupdate4.configの3種類のファイルが追加されて、machine.configのタイムスタンプが変わってた。

Machine.configの変更部分
<add assembly="System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />

Assemplyになにやらアダプタが追加されてた。
他のassemblyはSystem.webみたいな当たり前のが多いのでちょっとどんな追加かわからん。

<add
    verb="*"
    path="*/xhtmlCss.axd"
    type="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlCssHandler,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />

XhtmlAdaptersとか。なんか核心ぽい。

<device
    name="XhtmlDeviceAdapters"
    predicateClass="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPageAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral"
    predicateMethod="DeviceQualifies"
    pageAdapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPageAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral">
    <control
        name="System.Web.UI.MobileControls.Panel"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPanelAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Form"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlFormAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.TextBox"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlTextBoxAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Label"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlLabelAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.LiteralText"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlLiteralTextAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Link"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlLinkAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Command"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlCommandAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.PhoneCall"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlPhoneCallAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.List"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlListAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.SelectionList"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlSelectionListAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.ObjectList"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlObjectListAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Image"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlImageAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.ValidationSummary"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlValidationSummaryAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.Calendar"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlCalendarAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.TextView"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlTextViewAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.MobileControl"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlControlAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
    <control
        name="System.Web.UI.MobileControls.BaseValidator"
        adapter="System.Web.UI.MobileControls.Adapters.XhtmlAdapters.XhtmlValidatorAdapter,System.Web.UI.MobileControls.Adapters,Version=1.0.0.0,PublicKeyToken=b03f5f7f11d50a3a,Culture=neutral" />
</device>
<device
    name="AlternateHtmlDeviceAdapters"
    inheritsFrom="HtmlDeviceAdapters"
    predicateClass="System.Web.UI.MobileControls.Adapters.DeviceUpdateAdapters.AlternateHtmlPageAdapter, System.Web.UI.MobileControls.Adapters, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"
    predicateMethod="DeviceQualifies"
    pageAdapter="System.Web.UI.MobileControls.Adapters.DeviceUpdateAdapters.AlternateHtmlPageAdapter, System.Web.UI.MobileControls.Adapters, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null">
</device>
<device
    name="AlternateChtmlDeviceAdapters"
    inheritsFrom="ChtmlDeviceAdapters"
    predicateClass="System.Web.UI.MobileControls.Adapters.DeviceUpdateAdapters.AlternateChtmlPageAdapter, System.Web.UI.MobileControls.Adapters, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"
    predicateMethod="DeviceQualifies"
    pageAdapter="System.Web.UI.MobileControls.Adapters.DeviceUpdateAdapters.AlternateChtmlPageAdapter, System.Web.UI.MobileControls.Adapters, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null">
</device>

('A`) xhtml出力の実働部やん

要するにこの部分が追加されないとbrowsercapsをどれだけ弄ってもxhtmlじゃ出力されないってことか。
そりゃそうだよなぁ。

browserCapsの変更点

debiceupdate3.configで発見。

<!-- OpenWave Browsers -->
<case
	match="(UP\.Browser)|(UP/)">
	<!-- Phone.com 3.x to 6.x -->
	<filter>
		<case
			match="((?'deviceID'\S*) UP/\S* UP\.Browser/(?'version'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*)/\S* UP(\.Browser)*/(?'version'\S*))|(UP\.Browser/(?'version'\S*)-(?'deviceID'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*) UP\.Browser/(?'version'\S*) UP\.Link/(?'gatewayVersion'\S*))|((?'deviceID'\S*)/(?'DeviceVersion'\S*) UP/(?'version'\S*))|((?'deviceID'\S*)/(?'DeviceVersion'\S*) UP.Browser/(?'version'\S*))|((?'deviceID'\S*) UP.Browser/(?'version'\S*))">
			<filter
				with="${version}"
				match="(?'browserMajorVersion'\d*)(?'browserMinorVersion'\.\d*).*">
				majorVersion = ${browserMajorVersion}
				minorVersion = ${browserMinorVersion}
			</filter>

			<filter 
				match="6"
				with="%{majorVersion}">
				<case
					match="^\.[^0]"
					with="%{minorVersion}">
					preferredRenderingMime = "application/xhtml+xml"
				</case>
			</filter>

UAにUp.Browserのver6の記述があったらpreferredRenderingMime = "application/xhtml+xml"と。
UAリストみてもこの判定で問題なさそう。

ぬーん。

結局

携帯ページとか大嫌いになりました。

*1:C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG