C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[20]: クラス名を変更するとDeserialize()でエラーが発生


(過去ログ 43 を表示中)

[トピック内 21 記事 (1 - 20 表示)]  << 0 | 1 >>

■22745 / inTopicNo.1)  クラス名を変更するとDeserialize()でエラーが発生
  
□投稿者/ セラナ太郎 (1回)-(2008/07/31(Thu) 11:27:34)

分類:[C#] 

WebサービスをVisualStudio2003で作っています。
「Webサービス仕様」
1)WebサービスクラスからHTTP(REST)メッセージを投げる。
2)返答としてXMLを受信する。
3)受信したXMLをXmlSerializer:Deserialize()する。



クラスの簡単な構成は以下の通りで問題なく動作しています。
●クラス構成
##xsd.exeによる自動生成クラス##
逆シリアル化対象クラス。(受信したXMLメッセージをこのクラスに逆シリアル化する。)
public partial class PriceInfo : XMLBase123
{
}

##逆シリアル化対象クラスの規定クラス。(ポリモーフィズム用)##
abstract public class XMLBase123
{
}

##Webサービスクラス##
public class REST24 : System.Web.Services.WebService
{
protected XMLBase123 sendRequestCore(string strURL, string strParam, string strEncoding, string strOption)
{
1)HTTPリクエスト送信
2)返答XMLメッセージ受信
3)Deserialize()実行
XMLBase123 objXML = (PriceInfo)serializerXML.Deserialize(readerXML);
4)後処理

return objXML;
}
}

簡単なクラス説明ですが、現在クラス構成で問題なく動作しています。
ただし、上記"逆シリアル化対象クラス"のPriceInfoクラス名を変更すると、"Webサービスクラス"のDeserialize()実行時にエラーが発生します。(コンパイルは問題なし。)

##クラス名PriceInfoをPriceInfo3に変更した場合のエラー##
------------------------------------------------
System.InvalidOperationException: XML ドキュメント (2,2) でエラーが発生しました。 ---> System.InvalidOperationException: &lt;PriceInfo xmlns=''&gt; は指定できません。
場所 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPriceInfo3.Read5_PriceInfo3()
--- 例外スタック トレースの最後 ---
場所 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
場所 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
場所 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
------------------------------------------------

上記PriceInfoクラス名を変更してもDeserialize()実行時エラーが発声しないようにする方法はありますでしょうか?

解決方法などわかりましたら、ご教授いただければ幸いです。
よろしくお願い致します。


●追記事項
・PriceInfo名を変更する目的は、xsd.exeで自動生成したクラスに同一名クラスが存在するためです。
・上記WebサービスクラスREST24で、xsd.exeで自動生成した複数の逆シリアル化対象クラスを使用することを目的としています。


引用返信 編集キー/
■22774 / inTopicNo.2)  Re[1]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta on the way (146回)-(2008/07/31(Thu) 19:47:46)
No22745 (セラナ太郎 さん) に返信

おそらく、クラスに属性を追加すればいいと思うのですが、クラスに追加したことはないので、出来るかどうかわかりません。

XML で定義されている名前と、クラス名が一致していないことが原因です。
なので、出力される XML の最上位要素の名前を変えるか、クラスの方を名前空間で分離してやるほうが良いのかな?
引用返信 編集キー/
■22785 / inTopicNo.3)  Re[2]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (3回)-(2008/08/01(Fri) 11:29:28)
Jitta on the way さん、ありがとうございます。

属性の操作(XML要素とクラスのマッピング)で対応しようと考えたのですが、C#初心者ということもありまして方法がわかりませんでした。

また、namespaceをns1,ns2で分けたところ、実行時に以下のエラーが発生しました。
--err------------------
名前空間 '' の最上位の XML 要素 'ekidata' が、明示型である ns1.ekidata および ns2.ekidata を参照しています。XML 属性を使用して、この要素または型の代わりとなる別の XML 名または名前空間を指定してください
-----------------------

XMLの最上位要素名を変える方法で対応可能か試してみようと思います。


属性の操作、クラスに属性を追加する方法をご存知の方がいらっしゃいましたらご教授いただけますでしょうか?


引用返信 編集キー/
■22811 / inTopicNo.4)  Re[3]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta (499回)-(2008/08/01(Fri) 22:37:11)
Jitta さんの Web サイト
No22785 (セラナ太郎 さん) に返信

 ん?なんか、変。ケータイで見ていたときは気づかなかったけど。。。

> WebサービスをVisualStudio2003で作っています。
 Visual Studio 2003 ですか?

> public partial class PriceInfo : XMLBase123
 2003には、partial キーワードはないはずですけど?

 それとも、2008で作った Web Service に、2003で作ったアプリケーションでアクセスしようとしています?

 あと、PriceInfo の名前を変えようというのも、なんか、変な気がする。。。
クラス名がバッティングしているんですよね?コンパイルが通らないのでは?


 MSDN ライブラリを「xml 属性」で検索すれば、こんなページがヒットするんだけどなぁ?
http://msdn.microsoft.com/ja-jp/library/xzys86e8(VS.80).aspx
「方法 : XML 要素および XML 属性名を修飾する」

お望みのことは、おそらくこちらに書いてあると思います。
http://msdn.microsoft.com/ja-jp/library/2baksw0z(VS.80).aspx
「属性を使用した XML シリアル化の制御」

引用返信 編集キー/
■22814 / inTopicNo.5)  Re[4]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (5回)-(2008/08/02(Sat) 09:23:35)
Jittaさん ご教授いただきましてありがとうございます。

上記URL確認しました。
まさしくほしかった情報で、問題解決できるかもしれません。
週明け早速試してみます。


>  Visual Studio 2003 ですか?
IDEはVisual Studio.net 2003です。同IDEで、WebService自身を作っています。
xsd.exeで自動生成したクラスに、partialキーワードがついていて、コンパイルも通っています。

> クラス名がバッティングしているんですよね?コンパイルが通らないのでは?
そうですね。
xsd.exeで自動生成したクラスでクラス名がバッティングする。
そのためクラス名を変更する。
すると 名前を変更したクラスの Deserialize() でエラーが発生する。
が、問題になっています。


私C#の開発経験が無く、[]や<>でくくった属性の設定?が良くわからなくて戸惑っています。
いろいろと教えていただきまして助かります。
ありがとうございます。

引用返信 編集キー/
■22815 / inTopicNo.6)  Re[5]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ シャノン (556回)-(2008/08/02(Sat) 11:54:38)
No22814 (セラナ太郎 さん) に返信
>> Visual Studio 2003 ですか?
> IDEはVisual Studio.net 2003です。同IDEで、WebService自身を作っています。
> xsd.exeで自動生成したクラスに、partialキーワードがついていて、コンパイルも通っています。

その xsd.exe はどうやって実行してるんですかね?
どうも .NET Framework 2.0 SDK の xsd.exe を使ってしまっているような気がします。
引用返信 編集キー/
■22845 / inTopicNo.7)  Re[6]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (6回)-(2008/08/04(Mon) 12:26:34)
シャノンさん、Jittaさん、ご教授ありがとうございます。

XMLRoot属性を以下のように使用してクラスPriceInfo123にXML要素PriceInfoを読み込ませることができました。
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = true)]
public partial class PriceInfo123 : XMLBase123
{
}


ただ、以下のように別クラスから同一ROOT XML要素を読もうとするとエラーになってしまいました。
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = true)]
public partial class PriceInfo123 : XMLBase123
{
}
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = true)]
public partial class PriceInfo456 : XMLBase123
{
}
--------------------------------------------------------------------------------
'/' アプリケーションでサーバー エラーが発生しました。
--------------------------------------------------------------------------------
名前空間 '' の最上位の XML 要素 'ekidata' が、明示型である ns01.PriceInfo123 および ns01.PriceInfo456 を参照しています。XML 属性を使用して、この要素または型の代わりとなる別の XML 名または名前空間を指定してください。
説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

例外の詳細: System.InvalidOperationException: 名前空間 '' の最上位の XML 要素 'ekidata' が、明示型である ns01.PriceInfo123 および ns01.PriceInfo456 を参照しています。XML 属性を使用して、この要素または型の代わりとなる別の XML 名または名前空間を指定してください。
--------------------------------------------------------------------------------


別クラスから同一名要素を読み込むのは無理なのでしょうか?
それとも、私のXMLスキーマクラス(PriceInfo)の作り方に問題があるのでしょうか?
ひとつのWebServiceを実行してその戻り値のXMLをそのままXSD.exeにかけてC#のクラスを作っています。

別Webサービスの戻り値のROOT XML要素名がバッティングすると、クラス名がバッティングするので、名前空間を変更もしくは、XmlRoot属性を使用してクラス名とXML要素のマッピングをしても、別クラスで同一ROOT XML要素を参照すると上記エラーが発生してしまいます。
スキーマクラスをマージすることで解決できるか少しやって見ます。


XSD.exeは
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin
のものを使用しています。(C:\Program Files下にあるのはこちらのexeのみでした。)
バージョンなどがあっていないなどの問題もございますでしょうか?


問題点などアドバイスなどいただけましたら幸いです。
引用返信 編集キー/
■22851 / inTopicNo.8)  Re[7]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ シャノン (559回)-(2008/08/04(Mon) 13:28:12)
No22845 (セラナ太郎 さん) に返信
> ただ、以下のように別クラスから同一ROOT XML要素を読もうとするとエラーになってしまいました。
> [XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = true)]
> public partial class PriceInfo123 : XMLBase123
> {
> }
> [XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = true)]
> public partial class PriceInfo456 : XMLBase123
> {
> }
>
> 別クラスから同一名要素を読み込むのは無理なのでしょうか?

「別クラスから同一名要素を読み込む」というのがよくわかりません。
同じ XML 要素に対応するクラスが複数あり、どっちの型にデシリアライズするかが異なる場合がある、ということでしょうか?

XmlSerializer のインスタンスはどうやって作っていますか?
コンストラクタにデシリアライズ対象の型を渡せばいい気がしますが。

> XSD.exeは
> C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin
> のものを使用しています。(C:\Program Files下にあるのはこちらのexeのみでした。)
> バージョンなどがあっていないなどの問題もございますでしょうか?

本当に Visual Studio 2003 ですか?
Visual Studio 8 ってのは Visual Studio 2005 のことですよ。
実は 2005 を使ってませんか?
引用返信 編集キー/
■22856 / inTopicNo.9)  Re[8]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (7回)-(2008/08/04(Mon) 17:19:05)
シャノンさん ご返信ありがとうございます。

>Visual Studio 8 ってのは Visual Studio 2005 のことですよ。
>実は 2005 を使ってませんか?
Visual Studio 2005を使っていました。
シャノンさん、Jitta さん、いい加減なことを言ってしまい、お手数をおかけしまして大変すみませんでした。


「別クラスから同一名要素を読み込む」
これは...

・XML1-----------
<aaa>
<name></name>
<number></number>
</aaa>
-----------------
・XML2-----------
<aaa>
<title></title>
<role></role>
<date></date>
</aaa>
-----------------
このようなルート要素名が同じXMLが二つあるとき、XSL.exeはそれぞれに...
class aaa
を生成します。ただ、そのままですと、IDEでコンパイルが通らないため、以下のように名前を変更し、XMLRootで要素をクラスに割り当てます。
[XmlRoot(Namespace = "", ElementName = "aaa"]
class aaa002{}
class aaa{}
ただ、このようにすると、前に記述したような「'/' アプリケーションでサーバー エラーが発生しました。」が発生してしまいます。
現在これが問題となっています。
目的は、上記のような2つのXMLをそれぞれ Deserialize() できるようにすることです。



>XmlSerializer のインスタンスはどうやって作っていますか?
リクエスト送受信後、XmlSerializerの生成、Deserialize()する関数は以下のようになります。

XMLBase123 objXML = new aaa();

protected XMLBase123 sendRequestCore(string strURL, string strParam, string strEncoding, string strOption)
{
if (0 == strURL.Length) return null;
if (0 == strEncoding.Length) strEncoding = STR_ENC_UTF8;

string strMessageREST = strURL + STR_Q + strParam;

while (strMessageREST.Contains(STR_QQ)) strMessageREST = strMessageREST.Replace(STR_QQ, STR_Q); ;

Encoding enc = Encoding.GetEncoding(strEncoding);
WebRequest reqWeb = WebRequest.Create(strMessageREST); // リクエストの作成

_respsWeb = reqWeb.GetResponse(); // 送信とレスポンスの取得
_strmHttp = _respsWeb.GetResponseStream();

XmlReader readerXML = XmlReader.Create(_strmHttp);

XmlSerializer serializerXML = new XmlSerializer(objXML.GetType());

objXML = (XMLBase123)serializerXML.Deserialize(readerXML); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
readerXML.Close();
_strmHttp.Close();

return (XMLBase123)objXML;

}

何か改善点などございましたら、アドバイスいただければ幸いです。
よろしくお願い致します。


引用返信 編集キー/
■22863 / inTopicNo.10)  Re[9]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta (500回)-(2008/08/04(Mon) 21:20:16)
Jitta さんの Web サイト
No22856 (セラナ太郎 さん) に返信
> 「別クラスから同一名要素を読み込む」
> これは...
>
> ・XML1-----------
> <aaa>
> <name></name>
> <number></number>
> </aaa>
> -----------------
> ・XML2-----------
> <aaa>
> <title></title>
> <role></role>
> <date></date>
> </aaa>
> -----------------
> このようなルート要素名が同じXMLが二つあるとき、XSL.exeはそれぞれに...
> class aaa
> を生成します。

 ここで、XML1 と XML2 の元となるクラスが同じ名前空間にあるなら、それは競合します。
XML も同じで、名前空間を分けてください。XSD.EXE を使っているなら、デフォルトの tempuri.org だかになっていると思います。
で、そこで指定した名前空間を、クラスの属性で指定してやってみてください。

引用返信 編集キー/
■22898 / inTopicNo.11)  Re[10]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (8回)-(2008/08/05(Tue) 13:28:07)
Jitta さん、いろいろと教えていただきましてありがとうございます。

XmlRootのnamespaceに注目していろいろ試してみました。
##クラス1
namespace ns01
{
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = false)]
public partial class PriceInfo123 : XMLBase123
{
}
}

このようなクラスがある時、XmlRootのNamespaceには何を設定すればよろしいでしょうか?(調査してみたのですが、恥ずかしながらわかりませんでした。)
Namespace を "" にすると問題なく動作するのですが、文字列を入れると実行時以下のエラーが発生します。
-Error-------------------------------
System.InvalidOperationException: XML ドキュメント (2,2) でエラーが発生しました。 ---> System.InvalidOperationException: &lt;PriceInfo xmlns=''&gt; は指定できません。
場所 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPriceInfo.Read7_PriceInfo()
-------------------------------------
追加情報として、クラスPriceInfo123はxsd.exeで自動生成したクラスですが、以下の変更を行っています。
・クラス名の変更。PriceInfo -> PriceInfo123
・[XmlRoot(ElementName = "PriceInfo")]の追加
・抽象クラスXMLBase123から派生させる
・namespace の記述がなかったので、namespace ns01を追加。



また、以下の形で異なるクラスからXML同一名要素を読み込むことができました。

##クラス1
namespace ns01
{
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = false)]
public partial class PriceInfo123 : XMLBase123
{
}
}

##クラス2
namespace ns02
{
public partial class PriceInfo : XMLBase123
{
}
}



ただ、以下の問題が残っています。
・クラス2を以下のように変更すると実行時エラーが発生する。
##クラス2
namespace ns02
{
[XmlRoot(Namespace = "", ElementName = "PriceInfo", IsNullable = false)]
public partial class PriceInfo02 : XMLBase123
{
}
}
-Error-------------------------------
「'/' アプリケーションでサーバー エラーが発生しました。」
...........
-------------------------------------
おそらくこの形で2つのクラスを作成することは可能ですが、3つ目の作成でエラーが発生すると思われます。

問題点、改善点などご教授いただければ幸いです。



引用返信 編集キー/
■22900 / inTopicNo.12)  Re[11]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (9回)-(2008/08/05(Tue) 13:39:37)
追記事項です。
xsd.exeで自動生成された他のクラスで、XmlElementAttribute("PriceInfo") があったので、そちら(以下クラス)を変更することで、エラーがなくなりました。(2つのクラスを作成することは可能、3つ目の作成でエラーが発生する件)

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.dammy.jp/", ElementName = "PriceInfo", IsNullable = false)] //<<<<<<<ここのNamespace = "http://www.dammy.jp/" と "ElementName = "PriceInfo""を追加
public partial class NewDataSet
{

private PriceInfo[] itemsField;

/// <remarks/>
// [System.Xml.Serialization.XmlElementAttribute("PriceInfo")] //<<<<<<<<<これを削除
public ekidata[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}


引用返信 編集キー/
■22926 / inTopicNo.13)  Re[12]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta (502回)-(2008/08/05(Tue) 21:49:38)
Jitta さんの Web サイト
No22900 (セラナ太郎 さん) に返信
ごめん、最初に戻ろう。
どのようにプロジェクトを作ったか、1つずつ手順を追って書いてください。
読み返してみて、こんな感じかな?

VS2005 を起動する。
新しいプロジェクトを作成する。→ Web Service
XML ファイルを作成する。
プログラム メニューから、VS コマンド ツールを起動する。
コマンド ツールを、XML ファイルがあるディレクトリへ移動する。
xsd.exe ファイル.xml /classes を実行する。
エディタで、できたクラス ファイルを開く。
クラス名を変更する。
VS のソリューション エクスプローラで、プロジェクトに追加する。

引用返信 編集キー/
■22952 / inTopicNo.14)  Re[13]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (10回)-(2008/08/06(Wed) 11:39:02)
Jitta さん、ご返信ありがとうございます。

もう一度整理させていただきました。
ソースも添付いたします。
*バッティングのXML root要素、クラス名は、"ekidata"となります。

Jittaさん、皆さん、更なるご教授いただけましたら幸いです。
よろしくお願い致します。

引用返信 編集キー/
■22953 / inTopicNo.15)  Re[14]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (12回)-(2008/08/06(Wed) 11:40:09)
●目的
同一ROOT要素を持つ異なるXMLファイルをそれぞれxsd.exeでクラス化し、それらを1Webサービスで使用可能にする。

●クラス
REST Webサービスのラッパークラス(Webサービス)。
・WebServiceJSC : REST24Ando クラス : Webサービス具象クラス
・REST24Ando : WebService クラス : Webサービス抽象クラス

●仕様
[WebServiceJSC クラスメソッド]
getEkiDataListTodohuken(string)
getEkiDataListRosen(string)
共に、httpリクエストを投げる。リクエスト戻り値をシリアル化し、それをメソッドの戻り値として返す。
参考資料: http://www.ekidata.jp/tools/api_pref.html

●問題点
異なるWebサービスが同一名のROOT XML要素を返すとき、そのXMLからxsd.exeを使ってクラスを作成すると、名前がぶつかる。
名前を変更後、C#のXmlRoot要素を使用しクラスとXMLをマッピングすると、エラーが発生する。
(バッティング要素名:ekidata)

●エラー
'/' アプリケーションでサーバー エラーが発生しました。
--------------------------------------------------------------------------------
名前空間 '' の最上位の XML 要素 'ekidata' が、明示型である ando1.ekidata および ando.ekidata513 を参照しています。XML 属性を使用して、この要素または型の代わりとなる別の XML 名または名前空間を指定してください。
説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。
例外の詳細: System.InvalidOperationException: 名前空間 '' の最上位の XML 要素 'ekidata' が、明示型である ando1.ekidata および ando.ekidata513 を参照しています。XML 属性を使用して、この要素または型の代わりとなる別の XML 名または名前空間を指定してください。
ソース エラー:
現在の Web 要求の実行中にハンドルされていない例外が生成されました。障害の原因および発生場所に関する情報については、下の例外スタック トレースを使って確認できます。

●プロジェクト構築
[IDE] VisualStudio 2005
[言語] C#
[フロー]
1) ASP.net WebService App の新規プロジェクト作成(プロジェクト名:ando)
2) 後述のWebサービス抽象・具象クラスの作成
3) XMLのシリアル化
3-1)以下2つのURIをブラウザから実行し、戻り値XMLをファイルに落とし、xsd.exeでクラス化する。
http://www.ekidata.jp/api/p/23.xml 駅データ 都道府県 Webサービス
http://www.ekidata.jp/api/l/11302.xml 駅データ 路線 Webサービス
3-2)作成したCSファイルをandoプロジェクトに追加する
*上記2Webサービスの戻り値XMLのroot要素は共に"ekidata"
4)3-2で追加した2つのクラスに変更を加える。(修正箇所は "//+*+*" マーク付加。)
5)ビルド後、実行すると、正常に動作する。
*"ekidata"をXML root要素として持つ2つのxmlシリアライズドクラスが共存している状態。
6)下記クラスの コメント行 "//key:aa333"をアクティブにすると、エラーが発生する。(●エラー参照)

引用返信 編集キー/
■22954 / inTopicNo.16)  Re[15]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (13回)-(2008/08/06(Wed) 11:40:33)
////////Webサービス具象クラス////////
namespace ando
{
public class WebServiceJSC : REST24Ando
{
[WebMethod]
public ando1.ekidata getEkiDataListTodohuken(string strParam)
{
initXMLObject(new ando1.ekidata());
return (ando1.ekidata)sendRequestCore("http://www.ekidata.jp/api/p/23.xml", "", STR_ENC_UTF8, "");
}


[WebMethod]
public ando.ekidata513 getEkiDataListRosen(string strParam)
{
initXMLObject(new ando.ekidata513());
return (ando.ekidata513)sendRequestCore("http://www.ekidata.jp/api/l/11302.xml", "", STR_ENC_UTF8, "");
}
}
}

//////Webサービス抽象クラス////////
namespace ando
{
/// <summary>
/// Summary description for REST
/// </summary>
[WebService(Namespace = "http://wsjsc.com/rest/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
abstract public class REST24Ando : System.Web.Services.WebService
{
WebResponse _respsWeb;
Stream _strmHttp;
XMLBaseAndo _objXML;

public const string STR_ENC_UTF8 = "UTF-8";
public const string STR_ENC_SJIS = "S-JIS";
public const string STR_Q = "?";
public const string STR_QQ = "??";

protected void initXMLObject(XMLBaseAndo objXMLnew)
{
_objXML = _objXMLnew;
}

protected XMLBaseAndo sendRequestCore(string strURL, string strParam, string strEncoding, string strOption)
{
if (0 == strURL.Length) return null;
if (0 == strEncoding.Length) strEncoding = STR_ENC_UTF8;

string strMessageREST = strURL + STR_Q + strParam;

while (strMessageREST.Contains(STR_QQ)) strMessageREST = strMessageREST.Replace(STR_QQ, STR_Q); ;

Encoding enc = Encoding.GetEncoding(strEncoding);
WebRequest reqWeb = WebRequest.Create(strMessageREST); // リクエストの作成

_respsWeb = reqWeb.GetResponse(); // 送信とレスポンスの取得
_strmHttp = _respsWeb.GetResponseStream();

XmlReader readerXML = XmlReader.Create(_strmHttp);

XmlSerializer serializerXML = new XmlSerializer(_objXML.GetType());

_objXML = (XMLBaseAndo)serializerXML.Deserialize(readerXML);
readerXML.Close();
_strmHttp.Close();

return (XMLBaseAndo)_objXML;
}
}
}

------------------------------------------------------
//////// シリアライズドXML クラスの抽象クラス ////////
abstract public class XMLBaseAndo : Attribute
{
}



////////路線 シリアライズドXML クラス////////
////マスターXML http://www.ekidata.jp/api/l/11302.xml 戻り値////
namespace ando //+*+* 追加
{
using System.Xml.Serialization;

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[XmlRoot(Namespace = "", ElementName = "ekidata", IsNullable = false)] //+*+* ElementName追加
public partial class ekidata513 : XMLBaseAndo //+*+* 修正 ekidata -> ekidata513 XMLBaseAndoから継承
{
private string station_cdField;
private string station_g_cdField;
private string station_nameField;
private string lonField;
private string latField;
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.ekidata89.jp/", ElementName = "ekidata", IsNullable = false)]
public partial class NewDataSet513 : XMLBaseAndo //+*+* 修正 NewDataSet -> NewDataSet513 XMLBaseAndoから継承
{
private ekidata513[] itemsField;

/// <remarks/>
// [System.Xml.Serialization.XmlElementAttribute("ekidata")] //+*+*削除
public ekidata513[] Items
{
}
}
}
------------------------------------------------------
////////都道府県 シリアライズドXML クラス////////
////マスターXML http://www.ekidata.jp/api/p/23.xml 戻り値////
namespace ando1 //+*+* 追加
{
using System.Xml.Serialization;

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
// [XmlRoot(Namespace = "", ElementName = "ekidata", IsNullable = true)] //+*+* 一行追加後 コメント化 //key:aa333
public partial class ekidata : XMLBaseAndo //+*+* 変更 XMLBaseAndoから継承
{
private ekidataPref[] prefField;
private ekidataLine[] lineField;
private string versionField;

//以下get/set 関数削除
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ekidataPref
{
private string codeField;
private string nameField;

//以下get/set 関数削除
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ekidataLine
{
private string line_cdField;
private string line_nameField;

//以下get/set 関数削除
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", ElementName = "ekidata", IsNullable = false)] //+*+* ElementName追加
public partial class NewDataSet : XMLBaseAndo
{
private ekidata[] itemsField;

/// <remarks/>
// [System.Xml.Serialization.XmlElementAttribute("ekidata")] //+*+*削除
public ekidata[] Items
{
}
}
}

引用返信 編集キー/
■22963 / inTopicNo.17)  Re[16]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta on the way (150回)-(2008/08/06(Wed) 15:06:17)
いや、ごめん、そのクラスを、どの様にプロジェクトに追加したのか。そこが鍵なんじゃないかと思うんです。

XML も、クラスも、名前空間を含めて同じ名前のものが存在してはいけないのです。
今、そのいけないことが発生している。なぜ、発生しているのか。そこを取り除かないと、解決したとは言えないでしょう。
引用返信 編集キー/
■23003 / inTopicNo.18)  Re[17]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ セラナ太郎 (14回)-(2008/08/06(Wed) 20:13:48)
Jittaさん 何度もすみません。

以下、XMLシリアルクラスのプロジェクトへの追加手順です。

////////路線 シリアライズドXML クラス////////
追加手順
1)http://www.ekidata.jp/api/l/11302.xmlをブラウザでたたき、戻り値をaaa.xmlファイルにする。
2)aaa.xml ファイルをxsd.exeにかけて、CSファイルを作る。
3)VisualStudioのソリューションエクスプローラから、新規アイテムとして、空のクラスを追加する。(rosen.cs)
4)2で作ったクラスを、3で作ったrosen.csファイルにコピー&ペーストする。
5)namespace は andoのまま。
6)WebServiceJSCクラスgetEkiDataListRosenメソッドを作成


////////都道府県 シリアライズドXML クラス////////
追加手順
1)http://www.ekidata.jp/api/p/23.xmlをブラウザでたたき、戻り値をbbb.xmlファイルにする。
2)bbb.xml ファイルをxsd.exeにかけて、CSファイルを作る。
3)VisualStudioのソリューションエクスプローラから、新規アイテムとして、空のクラスを追加する。(todohuken.cs)
4)2で作ったクラスを、3で作ったtodohuken.csファイルにコピー&ペーストする。
5)namespace を ando1に変更する。
6)WebServiceJSCクラスgetEkiDataListTodohukenメソッドを作成

何度もお手数をおかけしましてすみません。
何かわかりましたらご教授いただければ幸いです。
よろしくお願い致します。

、発生しているのか。そこを取り除かないと、解決したとは言えないでしょう。
引用返信 編集キー/
■23065 / inTopicNo.19)  Re[18]: クラス名を変更するとDeserialize()でエラーが発生
□投稿者/ Jitta (503回)-(2008/08/07(Thu) 22:18:26)
Jitta さんの Web サイト
No23003 (セラナ太郎 さん) に返信
 「返ってくるデータのルートがすべて ekidata だから」というのが、
ファイル名をかえようとしている理由でしょうか。そこの認識を変えましょう。
サービスは、ekidata というデータを返します。この ekidata に、
0個以上の駅、駅グループ、路線、県データが入っている、
と考えてください。
そうすると、サービスごとにデシリアライズするクラスを変更する必要はなく、
すべて ekidata にデシリアライズすれば良くなります。
また、ekidata に入っているクラスは、すべてのサービスの戻り値を見て、
すべての要素を網羅するようにします。

 ここで、Station は Line と StationGroup に同じプロパティがあります。
しかし、Station を Line と StationGroup から継承してはいけません。
駅は、路線や駅グループとは違うものだからです。

# 「座標から最寄り駅」「駅名検索」「隣接駅一覧」は、未コード化
# あれ?なんか、Ekidata クラスだけ手抜いてる...orz

[Serializable()]
public class Line
{
    private uint lineCode = 0;
    private string lineName = string.Empty;

    public Line() {
    }

    public Line(uint c, string n) {
        lineCode = c;
        lineName = n;
    }

    [XmlElement(ElementName = "line_cd")]
    public uint Code {
        get { return lineCode; }
        set { lineCode = value; }
    }

    [XmlElement(ElementName = "line_name")]
    public string Name {
        get { return lineName; }
        set { lineName = value; }
    }
}

[Serializable()]
public class Station
{
    private uint stationCode = 0;
    private uint groupCode = 0;
    private string stationName = string.Empty;
    private uint lineCode = 0;
    private string lineName = string.Empty;
    private double lon = 0.0;
    private double lat = 0.0;

    public Station() {
    }

    [XmlElement(ElementName = "station_cd")]
    public uint Code {
        get { return stationCode; }
        set { stationCode = value; }
    }

    [XmlElement(ElementName = "station_g_cd")]
    public uint GroupCode {
        get { return groupCode; }
        set { groupCode = value; }
    }

    [XmlElement(ElementName = "station_name")]
    public string Name {
        get { return stationName; }
        set { stationName = value; }
    }

    [XmlElement(ElementName = "line_cd")]
    public uint LineCode {
        get { return lineCode; }
        set { lineCode = value; }
    }

    [XmlElement(ElementName = "line_name")]
    public string LineName {
        get { return lineName; }
        set { lineName = value; }
    }

    [XmlElement(ElementName="lon")]
    public double Lon {
        get { return lon; }
        set { lon = value; }
    }

    [XmlElement(ElementName = "lat")]
    public double Lat {
        get { return lat; }
        set { lat = value; }
    }
}

[Serializable()]
public class Prefecture
{
    private uint code = 0;
    private string name = string.Empty;

    public Prefecture() {
    }

    [XmlElement(ElementName="code")]
    public uint Code {
        get { return code; }
        set { code = value; }
    }
    [XmlElement(ElementName="name")]
    public string Name {
        get { return name; }
        set { name = value; }
    }
}

[Serializable()]
public class StationGroup
{
    private uint stationCode = 0;
    private string stationName = string.Empty;
    private uint lineCode = 0;
    private string lineName = string.Empty;

    public StationGroup() {
    }

    [XmlElement(ElementName = "station_cd")]
    public uint Code {
        get { return stationCode; }
        set { stationCode = value; }
    }

    [XmlElement(ElementName = "station_name")]
    public string Name {
        get { return stationName; }
        set { stationName = value; }
    }

    [XmlElement(ElementName = "line_cd")]
    public uint LineCode {
        get { return lineCode; }
        set { lineCode = value; }
    }

    [XmlElement(ElementName = "line_name")]
    public string LineName {
        get { return lineName; }
        set { lineName = value; }
    }
}

[Serializable()]
[XmlRoot(ElementName="ekidata")]
public class Ekidata
{
    [XmlElement(ElementName = "pref", Type = typeof(Prefecture))]
    public List<Prefecture> prefecture = new List<Prefecture>();
    [XmlElement(ElementName = "line", Type = typeof(Line))]
    public List<Line> line = new List<Line>();
    [XmlElement(ElementName = "station", Type = typeof(Station))]
    public  List<Station> station = new List<Station>();
    [XmlElement(ElementName = "station_g", Type = typeof(StationGroup))]
    public List<StationGroup> stationGroup = new List<StationGroup>();
    [XmlAttribute(AttributeName = "version", Type = typeof(string))]
    public string Version = string.Empty;

    public Ekidata() {
    }
}

引用返信 編集キー/
■23090 / inTopicNo.20)  Re[19]: クラス名を変更するとDeserialize()でエラーが発生
 
□投稿者/ セラナ太郎 (15回)-(2008/08/08(Fri) 13:27:45)
Jitta さん

Webサービスごとにシリアル化するのではなくて、すべてに対応可能なようにまとめてしまえばよいわけですね。

非常に詳しくご説明いただきましてありがとうございます。
XML、シリアル化は、汎用性を考えた際に武器になりそうなので、教えていただいたソースコードを元に、自分でももう少し研究してみたいと思います。


Jitta さんはじめ皆さん、お忙しい中お気にかけていたただきまして本当にありがとうございました。
この情報が他の皆さんにも参考になればうれしいです。

今後は僕もJittaさんのように教えられる立場になれるようがんばります。

セラナ太郎


解決済み
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -