- PR -

Webサービスのパラメータについて

投稿者投稿内容
まゆりん
ぬし
会議室デビュー日: 2002/08/12
投稿数: 539
お住まい・勤務地: よこはま
投稿日時: 2002-12-24 16:06
こんにちは、まゆりんです。
Win2K、VB.NETを使用してWEBシステムを開発しております。

Webアプリケーションで作成したクラス情報をWebサービスに渡したいのですが、
その場合サービス側のパラメータはObject型で良いのでしょうか?
実行した際、例外処理でエラーになってしまいました。
その時ログに残っていたメッセージと、実際に作成したコードのサンプル版を載せます。
(グローバル宣言やインポート等は省略しています)

【ログ】
Exception:at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces
namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Serialize(SoapClientMessage message)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

【コード(VB・Webアプリ側)】
コード:
Public Class SampleClass


Private sCode() As String '商品コード
Private sName() As String '商品名
Private sTanka() As Long '単価
Private sKosuu() As Integer '個数
Private sKingaku() As Long '金額

'商品コード
Public Property pCode() As String()
Get
Return sCode
End Get
Set(ByVal Value As String())
sCode = Value
End Set
End Property

'商品名
Public Property pName() As String()
Get
Return sName
End Get
Set(ByVal Value As String())
sName = Value
End Set
End Property

'単価
Public Property pTanka() As Long()
Get
Return sTanka
End Get
Set(ByVal Value As Long())
sTanka = Value
End Set
End Property

'個数
Public Property pKosuu() As Integer()
Get
Return sKosuu
End Get
Set(ByVal Value As Integer())
sKosuu = Value
End Set
End Property

'金額
Public Property pKingaku() As Long()
Get
Return sKingaku
End Get
Set(ByVal Value As Long())
sKingaku = Value
End Set
End Property

End Class

Public Class SampleClass

Private Sub Touroku()
''データクラス情報
Dim objData As New SampleData()
''Webサービス
Dim objWf As New localhost.WfService()

''ここでデータの取得を行う

''Webサービスメソッドを呼び出す
ResText.Text = objWf.SetData(objData)

End Sub

End Class



【コード(VB・Webサービス側)】
コード:
Public Class WfService

Inherits System.Web.Services.WebService

<WebMethod()> Public Function SetData(ByVal objData As Object) As String

Return = "OK"

End Function

End Class



ちなみに、SOAPプロトコルを使用しております。
宜しくお願い致します。

[ メッセージ編集済み 編集者: まゆりん 編集日時 2002-12-24 16:28 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-12-24 16:46
こんにちは。

 うろ覚えですみませんが、SampleClassがシリアル化を実装する必要があると、VSのヘルプに書かれていたと思います。
ヘルプキーワード「System.Xml.Serialization.XmlSerializer クラス」
まゆりん
ぬし
会議室デビュー日: 2002/08/12
投稿数: 539
お住まい・勤務地: よこはま
投稿日時: 2002-12-25 02:42
引用:

Jittaさんの書き込み (2002-12-24 16:46) より:
こんにちは。

 うろ覚えですみませんが、SampleClassがシリアル化を実装する必要があると、VSのヘルプに書かれていたと思います。
ヘルプキーワード「System.Xml.Serialization.XmlSerializer クラス」



Jittaさん、有難うございます!
やはりシリアル化するしかないんですね・・・。
事前にヘルプは読んだのですが、他に方法はないかと思ったので。
(すみません、先に言っておけば良かったです。お手数掛けました )
で、ヘルプを元に早速実装してみたのですが、

Dim myObject As MySerializableClass = New SampleClass()
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(SampleClass))
Dim myWriter As StreamWriter = New StreamWriter("C:\Inetpub\wwwroot\myFileName.xml")
mySerializer.Serialize(myWriter, myObject)

と書いて実行したところ、3〜4行目のコードで例外が発生し、

Msg: パス "C:\Inetpub\wwwroot\myFileName.xml" へのアクセスが拒否されました。
Exception: at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at System.IO.StreamWriter.CreateFile(String path, Boolean append)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(String path)

というエラーログが出てしまいました。
「アクセスが拒否されました」と言う事はアクセス権限等の問題になるのでしょうか?
もしかしたら初歩的な質問になってしまうのかもしれませんが、
ご教授頂きたく宜しくお願い致します。

また、シリアル化のサンプルなどを紹介して頂けると大変助かります。

[ メッセージ編集済み 編集者: まゆりん 編集日時 2002-12-25 02:43 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-12-25 08:46
すみません、私も途中でパスしたくちなんで・・・(^^;
来年度には必要になるので教えてください!!!(ぉ?)

で、ヘルプを再検索したところ、シリアライザーを実装するのではなく、属性で制御できるようです。
.NET 開発→.NET 開発→.NET Framework→.NET Framework を使用したプログラミング→オブジェクトのシリアル化→XML シリアル化およびSOAP シリアル化→XML Web サービスを使用した XML シリアル化

「XML シリアル化およびSOAP シリアル化」が章の扉。
#「XML Web…」以降を追記

[ メッセージ編集済み 編集者: Jitta 編集日時 2002-12-25 08:54 ]
まゆりん
ぬし
会議室デビュー日: 2002/08/12
投稿数: 539
お住まい・勤務地: よこはま
投稿日時: 2002-12-25 14:57
Jittaさん、またまた有難うございます。
よーくヘルプの方を読んでみましたが、その方法でも無理なようです。

JittaさんがおっしゃるページはWebサービス側でのシリアル化だったようですが、
私の目的はWebアプリからWebサービスのメソッドを呼ぶ時のパラメータの
型がObjectでは無理でしたので、シリアル化も含めて代用するものがあるかと思い
スレッドを立てさせて頂いた次第です。
(タイトルが誤解を招いてしまったみたいですね。申し訳ないです・・・)

昨日エラーになっていた
Dim myWriter As StreamWriter = New StreamWriter("C:\Inetpub\wwwroot\myFileName.xml")
をCドライブの直下に指定してみらた難なく通りましたので、
XMLファイルに書き込む方法で試していきたいと思います。
(たぶんIISによるセキュリティでアクセス拒否されたのかもしれません。
・・・あくまで推測ですが)
出来たらご報告させて頂きますので、来年試してみてくださいね(笑)。

お付き合い頂き、有難うございました!
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2002-12-27 09:11
まゆりん さん

 予定より少し早く片づいたので、ちょっとさわってみました。これで、一応OKになりましたけど???

ソリューションを作る
Webアプリプロジェクトを作る (a)
クラスライブラリプロジェクトを作る (b)
Webサービスプロジェクトを作る (c)
bに、SampleDataクラスを作成する
クラス宣言に、「<System.Xml.Serialization.SoapType()>」属性を追加する
cがbを参照する
aがcをweb参照する
aがSampleDataクラスのインスタンスを、c経由で作成する(Dim a As New localhost.SampleData())
aがcのメソッドをコールする

*aのコード
コード:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click
	Dim a As New localhost.SampleData()
	a.pName = New String() {TextBox1.Text}
	Dim we As New localhost.Service1()
	TextBox2.Text = we.TST_Recieve(a)
End Sub


*bのコード
コード:
<System.Xml.Serialization.SoapType()> _
Public Class SampleData
	Private sCode() As String	 '商品コード
	Private sName() As String	 '商品名
	Private sTanka() As Long	  '単価
	Private sKosuu() As Integer	  '個数
	Private sKingaku() As Long	   '金額
以下略


*cのコード
コード:
<WebMethod()> _
Public Function TST_Recieve(ByVal sample As ClassLibrary1.SampleData) As Boolean
	Return True
End Function

まゆりん
ぬし
会議室デビュー日: 2002/08/12
投稿数: 539
お住まい・勤務地: よこはま
投稿日時: 2003-01-06 11:38
あけましておめでとうございます。
本年も宜しくお願い致します。

早速ですが、Jittaさん有難うございました。
なるほど、クラスライブラリを使用することで
実現可能となるわけですね。
そこが抜けていたので不可能と勝手に決め付けてしまいました。
現在XMLに吐き出して処理を行ってしまっているので、
今後のためにこちらでも試験的に作成させて頂きました。

引用:

Jittaさんの書き込み (2002-12-27 09:11) より:

cがbを参照する
aがcをweb参照する
aがSampleDataクラスのインスタンスを、c経由で作成する(Dim a As New localhost.SampleData())



ここで「Dim a As New localhost.SampleData()」を作成しようと思ったのですが、
localhost直下にSampleDataがありませんでした。
「cがbを参照する」と「aがcをweb参照する」時にただ普通に参照・Web参照しただけでは
c経由でクラスのインスタンスを作成できないのでしょうか?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-01-06 12:00
こちらこそ、よろしくお願いします。

引用:

まゆりんさんの書き込み (2003-01-06 11:38) より:
引用:

Jittaさんの書き込み (2002-12-27 09:11) より:

cがbを参照する
aがcをweb参照する
aがSampleDataクラスのインスタンスを、c経由で作成する(Dim a As New localhost.SampleData())



ここで「Dim a As New localhost.SampleData()」を作成しようと思ったのですが、
localhost直下にSampleDataがありませんでした。
「cがbを参照する」と「aがcをweb参照する」時にただ普通に参照・Web参照しただけでは
c経由でクラスのインスタンスを作成できないのでしょうか?


 名前空間を設定していれば、それがいるかもしれません。また、ポスト後にいろいろ試したのですが、どうも、*Webサービスの引数になっていなければならない*ようです(先に書いておけって)。

 また、DataTableからInheritsしたものは、まゆりんさんの最初のポストのような実行時エラーが出ました。同じクラスをDataSetにしまうと、クラスの情報が失われてしまいます。じゃぁということで、DataTableを内包したDataSetを継承したクラス(フォームデザイナのコンテキストメニューで「データセットを生成」したのと同じような感じ)を、と思った時点でTime Upしてしまいました。

 やはり、シリアライズ処理を実装しなければいけないのでしょう。。。。。

スキルアップ/キャリアアップ(JOB@IT)