- PR -

XMLWebサービスでArraylistの値を戻したい

1
投稿者投稿内容
mso
ぬし
会議室デビュー日: 2003/12/04
投稿数: 496
お住まい・勤務地: 宮城
投稿日時: 2007-03-08 11:51
msoです。

環境
 WindowsXP SP2
 VisualStudio2005(C#)
 IIS5.1

現在、Webサービスについて勉強をしていますが、
Webサービスのデータの戻し方についてどのように
対応をすれば良いのかわかりません。

テストソース
コード:
[WebMethod]
public Person[] GetPerson()
{
    Person[] Persons = new Person[2] ;

    Person obj1 = new Person();
    Persons[0] = obj1;

    Person obj2 = new Person();
    Persons[1] = obj2;

    return Persons;
}


Personクラス
コード:
public class Person
{
    private string name = "未設定";
    private string address = "未設定";
    [SoapAttribute()]
    public int Age = 0;
    private string temporaryID = "未設定";
    [SoapElement()]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string Address
    {
        get { return address; }
    }
}




現在は、上記のようなサンプルソースを作成し、
WebサービスにアクセスされたときにクラスをXMLとして出力するようにしています。

ただ、現状の作りでは不特定多数のデータを戻す際に、配列の数が
影響するためArrayListをつかって戻せるようにしたいと思います。

そこで試行錯誤し、以下のように修正をしたところ期待した内容が戻されませんでした。
ArrayListにセットした値をWebサービスから戻したい場合は、
どのようにすればよろしいでしょうか?


Webサービス側
コード:
[WebMethod]
public string GetPerson()
{
    ArrayList list = new ArrayList();

    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());

    SoapFormatter formatter = new SoapFormatter();

    string retXmlStream = string.Empty;
    using (Stream stream = new MemoryStream())
    {
        formatter.Serialize(stream, list);
        retXmlStream = stream.ToString();
    }

    return retXmlStream;
}



Personクラス
コード:
public class Person
{
    private string name = "未設定";
    private string address = "未設定";
    [SoapAttribute()]
    public int Age = 0;
    private string temporaryID = "未設定";
    [SoapElement()]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string Address
    {
        get { return address; }
    }
}



出力された内容
コード:
  <?xml version="1.0" encoding="utf-8" ?> 
  <string xmlns="http://tempuri.org/">System.IO.MemoryStream</string> 



きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2007-03-08 13:33
msoさん、こんにちは。

return list.ToArray();

ではダメですか?

【追記】
ArrayList よりも
ジェネリックの List<T> の方が良いかも。


[ メッセージ編集済み 編集者: きくちゃん 編集日時 2007-03-08 13:41 ]
mso
ぬし
会議室デビュー日: 2003/12/04
投稿数: 496
お住まい・勤務地: 宮城
投稿日時: 2007-03-08 16:35
msoです。

引用:

きくちゃんさんの書き込み (2007-03-08 13:33) より:
msoさん、こんにちは。

return list.ToArray();

ではダメですか?

【追記】
ArrayList よりも
ジェネリックの List<T> の方が良いかも。


[ メッセージ編集済み 編集者: きくちゃん 編集日時 2007-03-08 13:41 ]



ToArray()やってみましたが、エラーになりました。

エラーメッセージ
コード:
System.InvalidOperationException: XML ドキュメントを生成中にエラーが発生しました。 ---> System.InvalidOperationException: 型 Person は指定されていません。スタティックに使用できない型を指定するには XmlInclude または SoapInclude 属性を使ってください。
   場所 System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
   場所 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
   場所 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_ArrayOfAnyType(Object o)
   場所 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
   場所 System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   --- 例外スタック トレースの最後 ---
   場所 System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   場所 System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
   場所 System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
   場所 System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
   場所 System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
   場所 System.Web.Services.Protocols.WebServiceHandler.Invoke()




エラーメッセージの内容をみても、すぐにはわからないのですが、
調査をしてみたいと思います。
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2007-03-09 18:42
msoさん、こんばんは。

引用:

ToArray()やってみましたが、エラーになりました。


マジっすか。
試してみましたが、ArrayList でも List<T> でも、そのような例外は発生しませんでした。

コード:
[WebMethod]
public Person[] GetPerson()
{
    System.Collections.Generic.List<Person> list
     = new System.Collections.Generic.List<Person>();
    //ArrayList list = new ArrayList();

    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());
    list.Add(new Person());

    return list.ToArray();
    //return (Person[])list.ToArray(typeof(Person));
}

mso
ぬし
会議室デビュー日: 2003/12/04
投稿数: 496
お住まい・勤務地: 宮城
投稿日時: 2007-03-15 13:45
msoです。

改めてテストを行ってみました。
前回うまく出来なかったのは、自分の対応が間違っていました。
そして、きくちゃんさんから提示していただいた方法でやってみた
ところうまく出来ました。

ありがとうございます。

Personクラス
コード:
/// <summary>
/// Person の概要の説明です
/// </summary>
[Serializable()]
public class Person
{
    private string name = "未設定";
    private string address = "未設定";
    [SoapAttribute()]
    public int Age = 0;
    private string temporaryID = "未設定";
    [SoapElement()]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string Address
    {
        get { return address; }
    }
    public void SetTemporaryID(string temporaryID)
    {
        this.temporaryID = temporaryID;
    }
    public void Dump()
    {
        System.Diagnostics.Trace.WriteLine(name);
        System.Diagnostics.Trace.WriteLine(address);
        System.Diagnostics.Trace.WriteLine(Age);
        System.Diagnostics.Trace.WriteLine(temporaryID);
    }

}



Webサービス
コード:
    [System.Xml.Serialization.XmlArrayItem(typeof(Person))]
    ArrayList list = new ArrayList();

    [WebMethod]
//    public Object[] GetPerson()
    public Person[] GetPerson()
    {

        list.Add(new Person());
        list.Add(new Person());
        list.Add(new Person());
        list.Add(new Person());
        list.Add(new Person());

        Person[] persons = new Person[list.Count];

        int i=0;
        foreach (Object obj in list)
        {
            persons[i++] = obj as Person;
        }

//        return list.ToArray();
        return return (Person[])list.ToArray(typeof(Person));;
    }



1

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