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?

Baxter
  • 5,633
  • 24
  • 69
  • 105
  • 2
    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. – Andre Calil Aug 20 '12 at 13:48
  • 1
    I wouldn't get tripped up over it being a webservice or not. Simply return back the data type that you need. – Menefee Aug 20 '12 at 13:48
  • @AndreCalil Could you point me to a reference / tutorial that provides more information regarding declaring a class at my WSDL? – Baxter Aug 20 '12 at 13:55
  • 1
    @Baxter Give me 1 minute – Andre Calil Aug 20 '12 at 13:55
  • @Baxter Done, take a look at my answer – Andre Calil Aug 20 '12 at 13:58
  • 1
    @Baxter Could you provide any feedback on my answer? Is it what you were looking for? – Andre Calil Aug 20 '12 at 18:51
  • @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. – Baxter Aug 21 '12 at 15:16
  • 1
    @Baxter Check out the new example I've added to my answer. Regards. – Andre Calil Aug 21 '12 at 23:06

1 Answers1

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();
Community
  • 1
  • 1
Andre Calil
  • 7,652
  • 34
  • 41
  • @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. – Baxter Aug 22 '12 at 18:41
  • @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 much – David Gidony Jul 06 '15 at 09:33
  • 1
    @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`. – Andre Calil Jul 06 '15 at 14:45
  • @AndreCalil, hi, i did so, but when i return the list type as my response , i get no data displayed. – David Gidony Jul 07 '15 at 06:01
  • 1
    @DavidGidony Hi David, could you post your code as a new question and link it here? It will be easier to help this way. – Andre Calil Jul 07 '15 at 21:26