How to return multiple values from a webservice?
Asked Answered
C

1

14

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?

Cobalt answered 20/8, 2012 at 13:45 Comment(8)
IMO, the best design is to declare a class at your WSDL and return an instance of it. This way, this method can be invoked by any other framework, because the exchanged type is public and not framework-specific.Rumrunner
I wouldn't get tripped up over it being a webservice or not. Simply return back the data type that you need.Photoelectron
@AndreCalil Could you point me to a reference / tutorial that provides more information regarding declaring a class at my WSDL?Cobalt
@Cobalt Give me 1 minuteRumrunner
@Cobalt Done, take a look at my answerRumrunner
@Cobalt Could you provide any feedback on my answer? Is it what you were looking for?Rumrunner
@AndreCalil I appreciate the feedback but I don't believe that is what I am looking for. I am not looking to accept a complex nested C# type. I am looking for the best practice of how to return more than one value of the same type and also how to do different types from a web service method. I will be using SOAP for the request / response.Cobalt
@Cobalt Check out the new example I've added to my answer. Regards.Rumrunner
R
37

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();
Rumrunner answered 20/8, 2012 at 13:53 Comment(5)
@AndreCalil I copied and deployed that code in Visual studio. When I run it in the browser it shows me a correct soap request / response for SOAP 1.1 and SOAP 1.2 and when I click the invoke button it returns the response listed above.Cobalt
@AndreCalil hi andre. great answer . what can i do if i want to return a multiple Student objects ? like after querying all students in the age of 6, what is the correct workflow to that ? thank you very muchPaleozoology
@DavidGidony Hi there! Do you see how a student has a list of courses? It would be the same idea, you'd create a type - for example, Result - that would have a List<Student>.Rumrunner
@AndreCalil, hi, i did so, but when i return the list type as my response , i get no data displayed.Paleozoology
@DavidGidony Hi David, could you post your code as a new question and link it here? It will be easier to help this way.Rumrunner

© 2022 - 2024 — McMap. All rights reserved.