- - PR -
[WebMethod] attribute と element
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2001-12-11 22:46
ASP.NET(beta2) の WebService で SOAP メソッドコールの
element と attribute の両方の値を受け取るには、どうすればよいでしょうか? UDDI 2.0 API に find_business というメソッドコールがあるのですが、 xml-element と xml-attribute の両方の引数を取ります。 <soap:Body> <find_business maxRows="10" generic="2.0" xmlns="urn:uddi-org:api_v2" > <name>service corp</name> </find_business> </soap:Body> これの Web Service 側で maxRows の値"10"と、<name> の値"service corp"を 受け取りたいのです。 以下のように、ASP.NET(C#,beta2) で XmlAttribute を使ってみたのですが、 maxRows の値をまったく拾えていません。(戻り値はいい加減) [WebMethod] public string find_business( string name, [XmlAttribute("maxRows")]int maxRows ) { .... } いったいどのようにすれば、maxRows の値を取ってこれるのか、 情報をお持ちの方はいらっしゃいませんでしょうか? では、よろしくお願いします。 -- | ||||||||
|
投稿日時: 2001-12-12 04:44
私のとこ(同じくC#,beta2)では、
[WebMethod] public string HelloWorld([System.Xml.Serialization.XmlAttribute("valueofattribute")]int valueofattribute,int valueofelement) { return "valueofattribute is " + valueofattribute + "valueofelement" + valueofelement; } ってすると、 <s:element name="HelloWorld"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="valueofelement" type="s:int" /> </s:sequence> <s:attribute name="valueofattribute" type="s:int" /> </s:complexType> </s:element> というWSDLが生成されて、実行もきちんとされてるようですが... #[]の中って名前の最後のAttributeが省略されるんですね... #最初、[System.Xml.XmlAttribute]をつけようとしていて、 #そんなのはないと言われて、パニクりました(^^; #(上で付けてるのは System.Xml.Serialization.XmlAttributeAttributeクラス) | ||||||||
|
投稿日時: 2001-12-12 22:18
遅くなってすみません。実は上手くいってないです。
確かに WSDL は、きれいに出ているようです。クライアントプロクシーも作成できました。 System.Xml.Serialization.XmlAttributeAttribute を使うのは、間違ってないようです。 しかし、実際に実行してみるとダメです。 int だと、暗黙の初期化で 0 が入ってくるように見えますが、string にしてみると、空文字列( String.Empty )になってしまっています。 つまり、値が取れてきていないことになります。 # 私の環境のせいかなぁ... Web Service 側のメソッドの引数の順番も関係あるかも知れないと思い、2引数での4通りを試してみました。 クライアントからは、第1引数に文字列 "foo" 、第2引数に文字列 "bar" が乗るようにプログラムします。 (基本) using System.Xml.Serialization; [WebMethod] public string AttrElem( string first, string second ) { return first + "+" + second; } (1) public string AttrElem( [XmlElement]string first, [XmlElement]string second ) 戻り値:<AttrElemResult>foo+bar</AttrElemResult> 当たり前に上手くいってます。 (2) public string AttrElem( [XmlAttribute]string first, [XmlElement]string second ) 戻り値:<soap:Fault>.. サーバーは要求を読み取れませんでした なんと HTTP 500 (3) public string AttrElem( [XmlElement]string first, [XmlAttribute]string second ) 戻り値:<AttrElemResult>foo+</AttrElemResult> attribute の値が採れてない (4) public string AttrElem( [XmlAttribute]string first, [XmlAttribute]string second ) 戻り値:<AttrElemResult>+</AttrElemResult> attribute の値が両方とも採れてない 泥沼にはまっているようです。 すみません、追試していただけませんか? -- | ||||||||
|
投稿日時: 2001-12-13 15:15
昨日は、サーバ側だけ作って、テスト用ページからのメソッド呼び出しで、
答えが返ってきていたので、動いているようだと思ったのですが、 あのページからだと、GETでとっているのでテストになってなかったようです。 クライアントを作って(1)-(4)を呼び出したら、確かにうまく行かず、 ほぼ同じような結果になりました。 #デバッグオプションつけたままコンパイルしたので、(2)ではデバッガが上がってきてしまいましたが。 | ||||||||
|
投稿日時: 2001-12-13 15:40
ちなみに、手で接続して、
をPOSTすると、
ってのがかえってきました。 引数の読み込みっぽいところ(ReadParameters)で例外が発生しているようですが... 私はお手上げ状態ですが、何かの参考になるでしょうか? 文字化けのとこが読めればもう少し情報になりそうなのですが...telnetのせいかな? [ メッセージ編集済み 編集者: けい 編集日時 2001-12-13 15:41 ] | ||||||||
|
投稿日時: 2001-12-13 21:44
う〜〜ん。ダメでしたか。
私の環境だけではないとわかって、ちょっと安心です。(いや安心しちゃいけないのか) soap:Fault の文字化けの部分は、UTF-8 で以下のようになります。 <soap:Fault> <faultcode>soap:Client</faultcode> <faultstring>System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: サーバーは要求を読みとれませんでした。 ---> System.Exception: XML ドキュメント (5,8) でエラーが発生しました。 ---> System.IndexOutOfRangeException: 種類 System.IndexOutOfRangeException の例外がスローされました。 at n2499d7d93ffa468fbd8861780677ee41.XmlSerializationReader1.Read1_AttrElem() at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters() at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.Invoke() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring> <detail /> </soap:Fault> Request の5行8桁目とは、多分、element 引数のタグ名の始まりです。 namespace がいるのかとも思い、いろいろ付けてみましたが、結局ダメでした。 何のインデックスが溢れているのでしょうか。さっぱりわかりません。 私もこれ以上こればっかりに関わってはいられないので、あきらめるとします。 お客さまには、「attribute に使うものは、それほど重要ではない」とか言って、先に進ませて貰いましょう。 「ダメだ」と言われたら、apache.axis に行くかな。 お付き合いいただき、ありがとうございました。 -- | ||||||||
|
投稿日時: 2001-12-21 18:12
いまさら、ですが...
System.Web.Services.Protocols.SoapParameterStyleが関係しています。ASP.NETのデフォルトであるSoapDocumentMethodのParameterStyleのデフォルトはSoapParameterStyle.Wrappedです。つまり、soap:Body直下の要素は価値ある情報と解釈されません。この場合、<find_business>要素は、単にメソッド実装へのルーティング情報でしかないことになります。 soap:Body直下の要素を意味あるものとして扱うには、SoapParameterStyle.Bareを指定しなければなりません。さて、ではこれでいけるかというと、
は、次のようなエラーになります。 XmlAttribute をパラメータで使ったり戻り値にすることはできません。 ちゃんちゃん。 どうしても<find_business>みたいなものをASP.NETで扱いたい場合は、SoapExtensionを使って、属性を要素にしてしまうとか送られたSOAPメッセージ全体をさらにくるむとか、そういう処理を実装する必要がありそうです。たとえば、MicrosoftのUDDI SDKはそうしていますね。 | ||||||||
|
投稿日時: 2002-01-08 19:25
あぁ、まったく気づかずに休みに入ってしまい、失礼しました。
私のほうも、あきらめの宣言をしましたが、ちょっと踏ん切りがつかずまだいじくっていて、System.Web.Services.Protocols.SoapDocumentMethodAttribute にたどり着きました。 しかし結果は、NothingBut.NETFW さんが実験してくださったように、 XmlAttribute をパラメータで使ったり戻り値にすることはできません。 でした。 .NET で言うところの System.Web.Services.Protocols.SoapParameterStyle.Bare とは、特に System.Web.Services.Description.SoapBindingUse.Literal と組み合わせたとき <soap:Body> <parameter1>element1</parameter1> <parameter2>element2</parameter2> <parameter3>element1</parameter3> </soap:Body> のように、soap:Body 直下に並ぶ xml エレメントを、適当な WebMethod 名で受け取るための物のようです。 ここで例えば、 <parameter1 attr="foo">element1</parameter1> <parameter2 attr="bar">element2</parameter2> とあったとき、attr アトリビュートは、parameter1 に属するのか、parameter2 に属するのか、WebMethod の方では、なかなか区別がつかないと言うことみたいです。 しょうがないような気もしますが、天下の MS ですから、何とかしてほしい気もします。 私の UDDI サービスは結局どうしたかというと、本来の asmx による Web サービスは、あきらめて、ASP.NET(aspx) の System.Web.UI.Page を継承して、HTTP メッセージをSOAP ごとゴッソリ xml ストリームで取得することにしました。 soap:Enviroment からオブジェクトクラスを作成して、XmlSerializer にかけるという、ちょっと強引な方法です。 UDDI の API ごとに自分で switch-case しないといけないので、あまりきれいじゃありません。 まだ中身を何も作ってないのですが、結構めんどくさそうです。 SOAP や UDDI の仕様的にはどうなのか? のちほど、別に投稿しようと思います。 -- |