Search code examples
c#visual-studio-2010web-servicesasmxwebmethod

How to return multiple values from a webservice?


I am very new to the world of web services so please bear with me. I am creating a very simple web service in Visual Studio 2010 using .asmx files.

Here is the code I am using:

namespace MyWebService
{
    [WebService(Namespace = "http://www.somedomain.com/webservices")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]

    public class Service1 : System.Web.Services.WebService
    {
        [WebMethod]
        public string simpleMethod(String str)
        {
            return "Hello " + str;
        }   
    }
}

When I invoke this and enter a value "John Smith" for the the str parameter it returns:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.somedomain.com/webservices">Hello John Smith</string>

My question is what is the best practice for returning more than 1 value for a web service method? If the values are all the same data type should I use an array? If the the values contain different data types would I need to create a custom class?


Solution

  • I believe that the best design is to write a class and include it on your WSDL. This will make the class signature available along with the description of your service. This means that a client, despite of it's language, will be able to use an object of that type.

    When creating this class, try not to use .Net built-in custom types, like DataSet or anyother. Try always using basic types whenever possible. This will ensure that your object will be easily serialized and deserialized, as well as used by clients developed frameworks other than .Net.

    Please, check this question: How to Declare Complex Nested C# Type for Web Service It does show a little code and a small advice as well.

    Let me know if you need any further support.


    UPDATE

    Let's say that you want to return, for a given webmethod, the following set of data:

    • Student's name
    • Student's birth date
    • A list of the courses that the student is current assigned to (represented by their names)

    Look at how the service would be signed:

    public class WebService1 : System.Web.Services.WebService
    {
        public class Course
        {
            public string Name { get; set; }
        }
    
        public class Student
        {
            public string Name { get; set; }
            public DateTime BirthDate { get; set; }
            public List<Course> CurrentCourses { get; set; }
        }
    
        [WebMethod]
        public Student HelloWorld()
        {
            Student Baxter = new Student();
    
            Baxter.Name = "Baxter";
            Baxter.BirthDate = new DateTime(1986, 04, 22);
            Baxter.CurrentCourses = new List<Course>();
            Baxter.CurrentCourses.Add(new Course() { Name = "SOAP Webservices 101" });
            Baxter.CurrentCourses.Add(new Course() { Name = "Mastering C#" });
            Baxter.CurrentCourses.Add(new Course() { Name = "Why you (and I) suck at Javascript" });
    
            return Baxter;
        }
    }
    

    After calling it, this is the result:

    <Student xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
        <Name>Baxter</Name>
        <BirthDate>1986-04-22T00:00:00</BirthDate>
        <CurrentCourses>
            <Course>
                <Name>SOAP Webservices 101</Name>
            </Course>
            <Course>
                <Name>Mastering C#</Name>
            </Course>
            <Course>
                <Name>Why you (and I) suck at Javascript</Name>
            </Course>
        </CurrentCourses>
    </Student>
    

    And the best is that, because this class signature is public (included in the WSDL), you can do the following at a different project, by simply processing the WSDL:

            ServiceReference1.WebService1SoapClient SoapClient = new ServiceReference1.WebService1SoapClient();
            ServiceReference1.Student IsThisBaxter = SoapClient.HelloWorld();