dポイントプレゼントキャンペーン実施中!

開発環境:
Visual Studio .NET 2003
.NET Framework 1.1

言語:
C#

Web サイトにあるxmlファイルを更新する方法を教えてください。

自作クラスに保持した情報をシリアライズ・デシリアライズしxmlファイルで保存しようとしています。

シリアライズでxmlファイルを更新するのが上手くいきません。
ローカルPCでテストした結果は上手く動作しますが、Web サイトでテストするとエラーが出ます。

エラー内容は、
System.ArgumentException : ストリームに書き込めませんでした。

===ソースコード始===
//URLを取得する
Uri myUri = new Uri ("http://www.**********/test.xml");//URLを指定
XmlUrlResolver resolver = new XmlUrlResolver();

//XmlSerializerオブジェクトを作成
//書き込むオブジェクトの型を指定する
System.Xml.Serialization.XmlSerializer serializer =
new System.Xml.Serialization.XmlSerializer(
typeof(MyData));//MyDataはオブジェクトの型
//ファイルを開く
System.IO.Stream fs =
(System.IO.Stream)resolver.GetEntity(myUri, null, typeof(System.IO.Stream));

//シリアル化し、XMLファイルに保存する
serializer.Serialize(fs, d_MyData);//d_MyDataはオブジェクト *ココでエラーが出ます。
===ソースコード終===
Web サイトでのフォルダ権限はフルコントロールに設定しています。

A 回答 (1件)

himajin100000の日記



まず,当方環境は.NET 3.5(.NET 2.0ベース)とVB.NET Orcas Beta1を用いていることを述べておく。

回答するにあたり、サンプルソースを内容を変化させずにVB.NETに移植して動作させてみたが,
ローカル環境においても動作しなかった。

原因はいくつかあって、
まず最初に気づいたのは

Dim fs As System.IO.Stream = TryCast(resolver.GetEntity(myUri, null, Type.GetType("System.IO.Stream")),System.IO.Stream)

によってfsに格納されたSystem.IO.StreamのCanWriteプロパティ[ReadOnly]がFalseだったこと。

dobon.netの内容を参考にSystem.IO.FileStreamのコンストラクタの第二引数にSystem.IO.FileMode.Create
を与えることで,書き込みができるオブジェクトが得られるだろうと考えた。
http://dobon.net/vb/dotnet/file/xmlserializer.html

そこでSystem.IO.IOStreamオブジェクトとSystem.IO.FileMode.Createを引数に与えて
System.IO.FileStreamを得る方法に自信がなかったし,必要性もよくわからなかったのでresolver.GetEntityを経由せず、
system.uriを直接指定する形をとり

Namespace hoge

Module Module1

Sub Main()

'Dim myUri As System.Uri = New System.Uri("C:\Data\Administrator\Oshiete_Goo\(略)\Q3200230A\SerializedObject.xml")
'Dim resolver As System.Xml.XmlUrlResolver = New System.Xml.XmlUrlResolver()
Dim d_MyData As New Mydata

Dim serializer As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(Type.GetType("ConsoleApplication1.hoge.Mydata"))

Dim fs As System.IO.FileStream = New System.IO.FileStream(myUri.AbsoluteUri, System.IO.FileMode.Create)

serializer.Serialize(fs, d_MyData)

End Sub

End Module

Public Class Mydata
Public hoge As Integer
Sub New()
hoge = 3

End Sub

End Class

End Namespace

としたが、やっぱり動作しなかった。
少し考えて

'Dim myUri As System.Uri = New System.Uri("C:\Data\Administrator\Oshiete_Goo\(略)\Q3200230A\SerializedObject.xml")
とコメントアウトし
Dim fs As System.IO.FileStream = New System.IO.FileStream("C:\Data\Administrator\Oshiete_Goo\(略)\Q3200230A\SerializedObject.xml", System.IO.FileMode.Create)

とファイル名を直に与えたところ動作したため,実行時のmyUri.Absoluteuriを見たら

file:///で始まっていて、出たエラーが「URI フォーマットはサポートされていません。」だった。

ここでピンと来たのだが,
【http://で始まるURIを指定しているということは当たり前ながら使っているプロトコルはHTTPである。
HTTPでファイルを作成したりするにはPUTメソッド等を用いるはずで,
serializer.Serialize(fs, d_MyData)の処理中にあるであろう
書き込み処理の仕方はローカルでファイルを書き込む方法とは異なるはずだ。
これらのクラスはそこまで考えられているだろうか?】

もしコレが原因なら,場合によってはFTPを使う方法やHTTPでPUTメソッドを使う方法で回避することになる。

リモートマシンへの書き込み方法を調べていると,
UNCという言葉に行き当たった。

http://www.atmarkit.co.jp/icd/root/91/5787091.html

もともと,以前うちでは家族に言われて俺が実験的にNetBIOSの設定等をする羽目になり,
その勉強として色々学んだからなんとなく勝手はわかる。

コンピュータ名はHIMAJINだ。

ローカルマシン上にgyaフォルダを作成し
このフォルダにgyaという共有名をつけて共有。
フルコントロール権をAdministrator,Administrators,CreateOwner,EveryOneに与え,

Namespace hoge
Module Module1

Sub Main()

'Dim myUri As System.Uri = New System.Uri("C:\Data\Administrator\Oshiete_Goo\(略)\Q3200230A\SerializedObject.xml")
'Dim resolver As System.Xml.XmlUrlResolver = New System.Xml.XmlUrlResolver()
Dim d_MyData As New Mydata

Dim serializer As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(Type.GetType("ConsoleApplication1.hoge.Mydata"))
Dim fs As System.IO.FileStream = New System.IO.FileStream("\\HIMAJIN\gya\test.xml", System.IO.FileMode.Create)

'Dim fs As System.IO.FileStream = New System.IO.FileStream("C:\Data\Administrator\Oshiete_Goo\Quarter2\Q3200230\Q3200230A\Q3200230A\SerializedObject.xml", System.IO.FileMode.Create)

serializer.Serialize(fs, d_MyData)

End Sub

End Module

Public Class Mydata
Public hoge As Integer
Sub New()
hoge = 3

End Sub

End Class

End Namespace

どきどきしながら実行してみるとファイルが作成された。
やはりそれがスキームが原因だったのだろう。
    • good
    • 0
この回答へのお礼

himajin100000様

回答ありがとうございます。

http経由で書き込み処理する時に、System.IO.FileStreamがサポートされてないのが原因のようですね。

Webサービス経由でオブジェクトを渡して、そこからWebサーバー内にSystem.IO.FileStreamで書き込む方法で試してみたいと思います。

ありがとうございました。

お礼日時:2007/07/26 09:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!