0

I have a couple of questions regarding Web Services, and I would really appreciate if someone could point me in the right direction.

In my class library, I have a two classes: Hotel & RoomType. Hotel class contains an ArrayList of RoomType objects.

In my Web Service, I have a GetHotels method as follows:

[WebMethod]
[XmlInclude(typeof(Hotel))]
[XmlInclude(typeof(RoomType))]
public ArrayList GetHotels()
{
    return Sistema.GetInstance().GetHotels();
}

GetHotels() in class Sistema, retrieves the information from the database and returns an ArrayList.

I had to use XMLInclude because I was getting:

The type Hotel (or RoomType) was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically

Then in my Web app I have this code:

WebService sample = new Service();
ArrayList hotels = service.GetHotels();

This doesn't compile, so I had to change to the following code:

WebService sample = new Service();
object[] hotels = service.GetHotels();

Here's my first question: Is it possible to return an ArrayList, or every time I will have to cast the result to an ArrayList?

Knowing that the ArrayList contains Hotel objects, I added the following code:

foreach (Hotel hotel in hotels)
{
    ...        
}

This compiles, but when I execute, I get the following error:

Unable to cast object of type 'System.Xml.XmlNode[]' to type 'Hotel'.

So, my next question is: How can I cast the result to a Hotel object and work with it?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Gonzalo
  • 982
  • 6
  • 23
  • 39
  • What version of .NET are you using? Why are you using ArrayList instead of a generic collection? Why are you using ASMX instead of WCF? – John Saunders Mar 12 '12 at 16:26
  • .NET 3.5. I'm using ArrayList and ASXML because I find it more comfortable to work with. Are there any disadvantages in using ASMX instead of WCF? Thanks – Gonzalo Mar 12 '12 at 16:31
  • 1
    Aside from the fact that ASMX is a legacy technology that is kept around only for backwards compatibility, WCF is about 10 times as powerful as ASMX. It is the _replacement_ for ASMX. You're not doing your career much good by remaining "comfortable". See http://stackoverflow.com/questions/2448472/wcf-vs-asmx-web-service – John Saunders Mar 12 '12 at 16:34
  • I wasn't aware of this. I'll take a look at the post you provided. Thanks – Gonzalo Mar 12 '12 at 16:47

3 Answers3

6

Neither ArrayList nor any other type specific to .NET will ever be passed across the wire from a web service. Web services only speak XML.

See Basics: How Web Services Work for more details.

In this particular case, ArrayList is being treated like object[], which means: "an arbitrary number of some kind of object". The only way to handle that in SOAP XML is to treat it like an array of some kind of XML Node, hence XmlNode[].

John Saunders
  • 160,644
  • 26
  • 247
  • 397
1

Complex objects are converted into simple objects when pass through SOAP.

I suggest to use this List<> in your Web Service

public List<Hotel> GetHotels()
{
  return ...;
}

so when you will call the method you'll have an Array of Hotel

Hotel[] hotels = service.GetHotels();

and then you will write

foreach (Hotel hotel in hotels)
{
...        
}
Emanuele Greco
  • 12,551
  • 7
  • 51
  • 70
  • Hi Emanuele. I tried what you suggested, but I get the following compilation error in the line Hotel[] hotels = service.GetHotels() - "Cannot implicitly convert type 'object[]' to 'Hotel[]'." – Gonzalo Mar 12 '12 at 16:46
  • @Gonzalo how did you create the reference to that web service? – Emanuele Greco Mar 12 '12 at 17:04
  • Right click on App_WebReferences > Add Web Reference. Then I typed the URL and selected Add Reference. – Gonzalo Mar 12 '12 at 17:07
  • My solution should work.. are you shure you published web service and refreshed the reference? Can you rename the method to GetHotels1 to be shure? – Emanuele Greco Mar 12 '12 at 17:08
  • You should not use web references unless necessary. Use a service reference. – John Saunders Mar 12 '12 at 23:26
1

Technique - 1 to avoid type casting

dynamic hotels = service.GetHotels();
foreach (Hotel str in d)
{
   //Your Code
}

Technique - 2 to avoid type casting

var hotels = service.GetHotels();
foreach (Hotel str in d)
{
   //Your Code
}
Pankaj
  • 9,749
  • 32
  • 139
  • 283