Foros: Open Discussion (Thread #19527)

リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-05 09:32 by Anónimo #38074)

リッチクライアントフレームワークで日本語メッセージを含むXMLを受信しようとしたところ、「サーバから受信したデータはXML電文ではありません」というエラーになります。(サーバ側にはフレームワークは使用せず、PHPで簡易的にテストを実施しています)
以下のようなXMLをレスポンスとして送信しています。
-----------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<GroupInfoFormDS xmlns="http://nttd-bb.com/terasoluna/framework/dotnet/client/TeraClientSample21/ViewData/">
<RegistResult>
<ResultCode>0</ResultCode>
<Message>おっぱーぴー!!</Message>
</RegistResult>
</GroupInfoFormDS>
-----------------------------------------
ReceiverBase.csのGetXmlFromResponseBodyメソッドでエラーがthrowされているようなのですが、
・Content-Typeがtext/xmlでないとそもそもエラーがthrowされます。
・Content-Typeがtext/xmlでは日本語部分のパースでエラーになります。
・Content-Type:application/octet-streamが許可されるようにすれば、正しく日本語が処理できます。
・日本語部分をbase64エンコードしてContent-Type:text/xmlで送受信することはもちろんできます。
どのように対応するのが正しいのでしょう?

Responder al #38074×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-05 10:00 by tatsumihr #38075)

日本語メッセージを含むXMLの送受信はできます。

ただし、ReceiverBase.csのGetXmlFromResponseBodyメソッドでは、Content-Typeがtext/xmlでないと、そもそもCommunicationExceptionをスローします。まずはContent-Typeをご確認ください。

また、それでも解決しない場合は、例外のスタックトレース、フレームワークから出力されるログをお教えください。よろしくお願いいたします。
Responder al #38074

Responder al #38075×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-07 14:25 by Anónimo #38145)

投稿者です。
質問の書き方が悪くて誤解されてしまったようなので補足いたします。
レスポンスデータはutf-8で作成しております。
Content-Typeがtext/xmlでは「サーバから受信したデータは、XML 電文ではありません」というエラーになるため、Content-Typeがtext/xmlでなくてもエラーにならないようにGetXmlFromResponseBodyメソッドを変更し(チェックをはずした)、application/octet-streamでレスポンスを返すと、ただしく日本語がパースできました。
Content-Typeがtext/xmlの際のフレームワークから出力されたログを以下に貼り付けました。
----------------------------------------------
Default Error: 0 : ERROR 2008-08-07 14:09:30,671 [9] (TERASOLUNA.Fw.Client.Communication.ReceiverBase) - サーバから受信したデータは、XML 電文ではありません。 <TERASOLUNA.Fw.Client.Communication.CommunicationException - サーバから受信したデータは、XML 電文ではありません。>
System.Xml.XmlException : '.' (16 進数値 0x00) は無効な文字です。 行 5、位置 14 です。
場所 System.Xml.XmlTextReaderImpl.Throw(Exception e)
場所 System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
場所 System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Int32 pos, Char invChar)
場所 System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
場所 System.Xml.XmlTextReaderImpl.ParseText()
場所 System.Xml.XmlTextReaderImpl.ParseElementContent()
場所 System.Xml.XmlTextReaderImpl.Read()
場所 System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
場所 System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
場所 System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
場所 System.Xml.XmlDocument.Load(XmlReader reader)
場所 System.Xml.XmlDocument.Load(Stream inStream)
場所 TERASOLUNA.Fw.Client.Communication.ReceiverBase.GetXmlFromResponseBody(WebResponse response, IProgressChangeReporter reporter)
Default Warning: 0 : WARN 2008-08-07 14:09:31,078 [9] (TERASOLUNA.Fw.Client.BLogic.CommunicateBLogicBase`1[[System.Data.DataSet, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]) - ビジネスロジックで発生した例外を捕捉しました。 <TERASOLUNA.Fw.Client.Communication.CommunicationException - サーバから受信したデータは、XML 電文ではありません。>
TERASOLUNA.Fw.Client.Communication.CommunicationException : サーバから受信したデータは、XML 電文ではありません。
場所 TERASOLUNA.Fw.Client.Communication.ReceiverBase.GetXmlFromResponseBody(WebResponse response, IProgressChangeReporter reporter)
場所 TERASOLUNA.Fw.Client.Communication.DataSetXmlReceiver`1.ReceiveResponse(HttpWebResponse response, IProgressChangeReporter reporter)
場所 TERASOLUNA.Fw.Client.Communication.ReceiverBase.Receive(HttpWebRequest request, IProgressChangeReporter reporter)
場所 TERASOLUNA.Fw.Client.Communication.CommunicatorBase`1.Receive(HttpWebRequest request)
場所 TERASOLUNA.Fw.Client.Communication.CommunicatorBase`1.Communicate(TParam paramData, IDictionary`2 requestHeaders)
場所 TERASOLUNA.Fw.Client.BLogic.DataSetXmlCommunicateBLogic`1.Communicate(BLogicParam communicateBlogicParam, IDictionary`2 requestHeaders)
場所 TERASOLUNA.Fw.Client.BLogic.CommunicateBLogicBase`1.Execute(BLogicParam blogicParam)
System.Xml.XmlException : '.' (16 進数値 0x00) は無効な文字です。 行 5、位置 14 です。
場所 System.Xml.XmlTextReaderImpl.Throw(Exception e)
場所 System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
場所 System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Int32 pos, Char invChar)
場所 System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
場所 System.Xml.XmlTextReaderImpl.ParseText()
場所 System.Xml.XmlTextReaderImpl.ParseElementContent()
場所 System.Xml.XmlTextReaderImpl.Read()
場所 System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
場所 System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
場所 System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
場所 System.Xml.XmlDocument.Load(XmlReader reader)
場所 System.Xml.XmlDocument.Load(Stream inStream)
場所 TERASOLUNA.Fw.Client.Communication.ReceiverBase.GetXmlFromResponseBody(WebResponse response, IProgressChangeReporter reporter)
Default Verbose: 0 : DEBUG 2008-08-07 14:09:31,093 [9] (TERASOLUNA.Fw.Client.Coordinator) - 型 "TERASOLUNA.Fw.Client.BLogic.DataSetXmlCommunicateBLogic`1[[TeraClientSample21.ViewData.GroupInfoFormDS, TeraClientSample21, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" のビジネスロジックを終了しました。
Default Verbose: 0 : TRACE 2008-08-07 14:09:31,093 [9] (TERASOLUNA.Fw.Client.Coordinator) - 型 "TERASOLUNA.Fw.Client.EventController" の "Items" プロパティには値が設定されていません。
Default Verbose: 0 : TRACE 2008-08-07 14:09:31,109 [9] (TERASOLUNA.Fw.Client.Forms.FormBase) - 結果文字列 "communicationException" として、エラーが発生しました。エラーメッセージ内容は以下の通りです。
Key="communicationException", Value="サーバから受信したデータは、XML 電文ではありません。"
Default Verbose: 0 : DEBUG 2008-08-07 14:09:32,312 [9] (TERASOLUNA.Fw.Client.EventController) - イベント処理機能(同期処理)を終了しました。
Responder al #38075

Responder al #38145×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-07 17:56 by tatsumihr #38154)

スタックトレースを見る限り、ReceiverBaseの335行目、System.Xml.XmlDocument.Load(Stream inStream)で例外が発生しているようです。

さらに、XmlExceptionでは「(16 進数値 0x00) は無効な文字です。行 5、位置 14 です。」とエラーメッセージが出ています。

このメッセージ通りに解釈すると、PHPサーバから送信しているXMLの5行目に0x00の文字列が入っていると推測できます。文字コードを確認するツールなどで、今一度、サーバから送信しているXMLをご確認ください。空白文字のどこかに、0x00が紛れ込んでいる可能性があります。

再現環境がないために推測ですが、ご了承ください。
Responder al #38145

Responder al #38154×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-08 10:30 by Anónimo #38169)

投稿者です。
フレームワークのGetXmlFromResponseBodyメソッドにトーレースログを入れて調べてみました。
Content-Typeがtext/xmlでなくてもExceptionはスローしないで通過させています。
結果を見ますと、Content-Typeによって「readSize = responseStream.Read」で得られたサイズが既に異なります。Content-Typeがtext/xmlの場合に発生する「(16 進数値 0x00) は無効な文字です。行 5、位置 14 です。」のメッセージが示す「0x00」は、バイナリダンプを見ますと<Message>タグの次、即ち日本語文字の先頭に存在していることが分かります。
どうもContent-Typeがtext/xmlの場合、responseから取り出したストーリームの読み込む時、既に文字化けしているものと思われます。
こちらでしか再現しないということなので、サーバ側にフレームワークを使った場合とそうでない場合の差異がContent-Type以外にあって、それが影響しているのでしょうか。サーバフレームワークと連携させて違いを調べてみようと思います。(お盆あけにでも)
---------------------------------------------
protected virtual XmlDocument GetXmlFromResponseBody(WebResponse response, IProgressChangeReporter reporter)
{
_log.Trace(">>> GetXmlFromResponseBody start!!");

// データがXMLでない(content-typeが"text/xml"でない)場合
string contentType = response.ContentType;
if (string.IsNullOrEmpty(contentType))
{
_log.Trace("trace-1");

CommunicationException exception
= new CommunicationException(Properties.Resources.E_COMMUNICATION_NOT_XML);
if (_log.IsErrorEnabled)
{
_log.Error(exception.Message, exception);
}
throw exception;
}

contentType = contentType.Split(';')[0];
if (string.Compare(TEXT_XML, contentType, true) != 0)
{
_log.Trace("trace-2:" + contentType);
/*CommunicationException exception
= new CommunicationException(Properties.Resources.E_COMMUNICATION_NOT_XML);
if (_log.IsErrorEnabled)
{
_log.Error(exception.Message, exception);
}
throw exception;*/
}
_log.Trace("trace-3");
int localBufferSize = BufferSize;
XmlDocument receiveXml = new XmlDocument();
byte[] buffer = new byte[localBufferSize];
using (Stream responseStream = response.GetResponseStream())
{
_log.Trace("trace-4");
int percentage = 0;
long receiveSize = 0L;
long totalSize = response.ContentLength;

using (MemoryStream stream = new MemoryStream())
{
_log.Trace("trace-5:" + totalSize);
int readSize = 0;

// バッファサイズ分受信する毎にイベント通知を行う
readSize = responseStream.Read(buffer, 0, localBufferSize);
while (readSize > 0)
{
stream.Write(buffer, 0, readSize);
receiveSize += readSize;

_log.Trace("trace-5-1:" + System.Text.Encoding.UTF8.GetString(buffer, 0, readSize));
_log.Trace("trace-5-2:" + BitConverter.ToString(buffer, 0, readSize));

// レポーターが存在していれば
if (reporter != null)
{
if (totalSize > 0)
{
percentage = CalcReceivePercentage(receiveSize, totalSize);
}
reporter.ReportProgressChanged(new ExecuteProgressChangedEventArgs(percentage));

}

readSize = responseStream.Read(buffer, 0, localBufferSize);
}

stream.Position = 0;

try
{
_log.Trace(">>> receiveXml.Load start!!");

receiveXml.Load(stream);
_log.Trace("<<< receiveXml.Load normal end.");
}
catch (XmlException e)
{
_log.Trace("trace-6");
CommunicationException exception
= new CommunicationException(Properties.Resources.E_COMMUNICATION_NOT_XML, e);
if (_log.IsErrorEnabled)
{
_log.Error(exception.Message, exception);
}
throw exception;
}
}
}
_log.Trace("trace-7");
return receiveXml;
}
---------------------------------
■結果
(1)Content-Type:application/octet-streamの場合
- >>> GetXmlFromResponseBody start!!
- trace-2:application/octet-stream
- trace-3
- trace-4
- trace-5:285
- trace-5-1:<?xml version="1.0" encoding="utf-8" ?>
<GroupInfoFormDS xmlns="http://nttd-bb.com/terasoluna/framework/dotnet/client/TeraClientSample21/ViewData/">
<RegistResult>
<ResultCode>0</ResultCode>
<Message>おっぱーぴー!!</Message>
</RegistResult>
</GroupInfoFormDS>
- trace-5-2:3C-3F-78-6D-6C-20-76-65-72-73-69-6F-6E-3D-22-31-2E-30-22-20-65-6E-63-6F-64-69-6E-67-3D-22-75-74-66-2D-38-22-20-3F-3E-0D-0A-3C-47-72-6F-75-70-49-6E-66-6F-46-6F-72-6D-44-53-20-78-6D-6C-6E-73-3D-22-68-74-74-70-3A-2F-2F-6E-74-74-64-2D-62-62-2E-63-6F-6D-2F-74-65-72-61-73-6F-6C-75-6E-61-2F-66-72-61-6D-65-77-6F-72-6B-2F-64-6F-74-6E-65-74-2F-63-6C-69-65-6E-74-2F-54-65-72-61-43-6C-69-65-6E-74-53-61-6D-70-6C-65-32-31-2F-56-69-65-77-44-61-74-61-2F-22-3E-0D-0A-20-20-3C-52-65-67-69-73-74-52-65-73-75-6C-74-3E-0D-0A-20-20-20-20-3C-52-65-73-75-6C-74-43-6F-64-65-3E-30-3C-2F-52-65-73-75-6C-74-43-6F-64-65-3E-0D-0A-20-20-20-20-3C-4D-65-73-73-61-67-65-3E-E3-81-8A-E3-81-A3-E3-81-B1-E3-83-BC-E3-81-B4-E3-83-BC-21-21-3C-2F-4D-65-73-73-61-67-65-3E-0D-0A-20-20-3C-2F-52-65-67-69-73-74-52-65-73-75-6C-74-3E-0D-0A-3C-2F-47-72-6F-75-70-49-6E-66-6F-46-6F-72-6D-44-53-3E-0D-0A
- >>> receiveXml.Load start!!
- <<< receiveXml.Load normal end.
- trace-7

---------------------------------
(2)Content-Type:text/xmlの場合
- >>> GetXmlFromResponseBody start!!
- trace-3
- trace-4
- trace-5:282
- trace-5-1:<?xml version="1.0" encoding="utf-8" ?>
<GroupInfoFormDS xmlns="http://nttd-bb.com/terasoluna/framework/dotnet/client/TeraClientSample21/ViewData/">
<RegistResult>
<ResultCode>0</ResultCode>
<Message> 文字化けした内容 </Message>
</RegistResult>
</GroupInfoFormDS>
- trace-5-2:3C-3F-78-6D-6C-20-76-65-72-73-69-6F-6E-3D-22-31-2E-30-22-20-65-6E-63-6F-64-69-6E-67-3D-22-75-74-66-2D-38-22-20-3F-3E-0D-0A-3C-47-72-6F-75-70-49-6E-66-6F-46-6F-72-6D-44-53-20-78-6D-6C-6E-73-3D-22-68-74-74-70-3A-2F-2F-6E-74-74-64-2D-62-62-2E-63-6F-6D-2F-74-65-72-61-73-6F-6C-75-6E-61-2F-66-72-61-6D-65-77-6F-72-6B-2F-64-6F-74-6E-65-74-2F-63-6C-69-65-6E-74-2F-54-65-72-61-43-6C-69-65-6E-74-53-61-6D-70-6C-65-32-31-2F-56-69-65-77-44-61-74-61-2F-22-3E-0D-0A-20-20-3C-52-65-67-69-73-74-52-65-73-75-6C-74-3E-0D-0A-20-20-20-20-3C-52-65-73-75-6C-74-43-6F-64-65-3E-30-3C-2F-52-65-73-75-6C-74-43-6F-64-65-3E-0D-0A-20-20-20-20-3C-4D-65-73-73-61-67-65-3E-00-00-00-82-83-00-89-83-00-8E-E1-00-8A-E1-00-00-21-3C-2F-4D-65-73-73-61-67-65-3E-0D-0A-20-20-3C-2F-52-65-67-69-73-74-52-65-73-75-6C-74-3E-0D-0A-3C-2F-47-72-6F-75-70-49-6E-66-6F-46-6F-72-6D-44-53-3E-0D-0A
- >>> receiveXml.Load start!!
- trace-6
- サーバから受信したデータは、XML 電文ではありません。 <TERASOLUNA.Fw.Client.Communication.CommunicationException - サーバから受信したデータは、XML 電文ではありません。>
System.Xml.XmlException : '.' (16 進数値 0x00) は無効な文字です。 行 5、位置 14 です。
場所 System.Xml.XmlTextReaderImpl.Throw(Exception e)
場所 System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
場所 System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Int32 pos, Char invChar)
場所 System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
場所 System.Xml.XmlTextReaderImpl.ParseText()
場所 System.Xml.XmlTextReaderImpl.ParseElementContent()
場所 System.Xml.XmlTextReaderImpl.Read()
場所 System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
場所 System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
場所 System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
場所 System.Xml.XmlDocument.Load(XmlReader reader)
場所 System.Xml.XmlDocument.Load(Stream inStream)
場所 TERASOLUNA.Fw.Client.Communication.ReceiverBase.GetXmlFromResponseBody(WebResponse response, IProgressChangeReporter reporter)
-----
ここまで
Responder al #38154

Responder al #38169×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

RE: リッチクライアントフレームワークでの日本語メッセージの取得 (2008-08-05 10:22 by Anónimo #38078)

UTF-8でエンコードされていないか、BOMが付いていないのではないでしょうか?
Responder al #38074

Responder al #38078×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar