質問者
パラメタにクラスをつかいたい場合

質問
-
.Net2003 C#です。
以下のようなWebサービスを作ってみたのですが、
考え方として間違っていないか、また
呼び出し側のアプリ開発について質問があります。パラメタ:ReqA(ヘッダ部とデータ部から構成されるクラス)
返却値:ResA(ヘッダ部とデータ部から構成されるクラス)---
namespace AAA
{
/// <summary>
/// A問合せサービスクラス
/// </summary>
public class WebServA : System.Web.Services.WebService
{
[webMethod]
public ResA getA(ReqA param)
{
・
・
・
}
}
/// <summary>
/// A要求クラス
/// </summary>
public class ReqA
{
/// <summary>
/// ヘッダ
/// </summary>
public Header Header = new Header();
/// <summary>
/// データ
/// </summary>
public Data Data = new Data();
}
/// <summary>
/// A応答クラス
/// </summary>
public class ReqA
{
/// <summary>
/// ヘッダ
/// </summary>
public Header Header = new Header();
/// <summary>
/// データ
/// </summary>
public Data Data = new Data();
}
/// <summary>
/// ヘッダ
/// </summary>
public class Header
{
int a = 0;
}
/// <summary>
/// データクラス
/// </summary>
public class Data
{
string b = "";
byte[] c;
}}
---質問1)
上記のような方法だと、ReqA = new ReqA();
としただけではHeaderやDataは実体化されず、呼出側アプリで別途
実体化してあげないとだめなのですがなぜでしょうか。
あまりよくない構造だと思うのですが、ではどう実装するのがよいのでしょうか。
コンストラクタを用意しても通りません。また
”byte[] c;”
の部分の初期化の方法もどうしたらよいかわかりません。
質問2)
呼び出し側のアプリで”ReqA.”まで書いたときに候補として表示されるメンバのコメントは
Microsoft.VSDesigneによって自動生成される.\Web References\localhost\Reference.cs
からひいてきているということがわかり、自分でコメントを追加すれば表示はできるのですが、
ソースのコメントの書き方が間違っているからコメントを自動ではひろってきてくれないのでしょうか。
それともそうゆう仕様なのでしょうか。/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public class ReqA {
/// <summary>
/// 説明を追加してみた 元は<remarks/>になっていた
/// </summary>
public Header Header;
/// <summary>
/// 説明を追加してみた 元は<remarks/>になっていた
/// </summary>
public Data Data;
}
すべての返信
-
質問1)
質問2)で出てきてるReference.csの該当部分にインスタンスを作るコンストラクタがないからです。
なんでそういうコードを吐くかまでは分かりませんが、
あまりに複雑なものだと自動的に作るのが難しい → 必要なら自分でやれ
ということかな、と想像します。
なので別にクラスファイルを用意して、namespaceをReference.csのものと同じにして
コンストラクタを用意してやればどうでしょうか。
# こういう事をするためにReference.cs内のクラスはpartialになってるのかな?
例:
namespace WebSvcTest.localhost
{
/// <summary>
/// 表示される説明文
/// </summary>
public partial class ReqA
{
/// <summary>コンストラクタ</summary>
public ReqA()
{
HeaderInstance = new Header();
DataInstance = new Data();
}
}
}
質問2)
クラスの説明だけなら上記で作ったクラスファイルに書けば良いと思います。
メソッドやフィールドについてはわかりません。
ここまで書いといてなんですが、
どっちも別の解がある気がしますね(笑
追記
よく考えたらWSDLにした時、XMLにならない部分は取得しようがないですね。
コンストラクタなんかできるわけないや(笑 -
お返事どうもありがとうございます。
>質問2)で出てきてるReference.csの該当部分にインスタンスを作るコンストラクタがないからです。
>なんでそういうコードを吐くかまでは分かりませんが、・・・Webサービスのソースで、コンストラクタありのクラスを用意しても、構造体を用意しても
作成されるReference.csはともにコンストラクタなしのクラスとなることがわかりました。さらに・・・>よく考えたらWSDLにした時、XMLにならない部分は取得しようがないですね。
>コンストラクタなんかできるわけないや(笑そうなんですか・・・と最初はイメージがわかなかったのですが、
クラスのメンバアクセスをget/set方式にして、setで例外を発生させるように仕込んだら
Reference.csはあいかわらずシンプルなもので(例外発生のロジックは消えてなくなる)
呼び出しアプリ側で値を代入する箇所(ReqA.Header.a = x;)ではなく、メソッド(getA)を呼んだ時点で
例外が発生したのをみて、なんとなくわかったような気がしました。>どっちも別の解がある気がしますね(笑
もうしばらくみなさんの書き込みを待ってみようと思います。
-
とりあえず一度 .NET Framework 開発者ガイド の SOAP メッセージ形式のカスタマイズ あたりを通して読まれてはどうでしょうか?
-
考え方として間違ってるに一票かな
WebサービスってHTTP over SOAPなので、ヘッダに相当する物はHTTPヘッダやSOAPエンベロープ等が自動的についていますので、それをうまく使う方法を考えるほうが良いです。
質問1についてですが、Webサービスでデータを渡す場合には基本はNull許可(XML的に言えば要素省略可能)ですので、最低限の初期化としてはNullが入っている状態となります。
なのでコンストラクタを置き換えるなりしない限りにはNullが入った状態となります。
またバイト配列はそのものをXML上に出すのは出来ません。
BASE64エンコード等をつかって文字列化してあげれば良いのではないでしょうか。
質問2についてはasmx側を属性で修飾してあげればWSDLに説明を出すことができて、WSDLに出た説明はWeb参照時に自動生成されるソースに展開されたと思います。
(たぶんですが)