An Overview

Let’s think of a scenario, where I am planning to show information on regional, national and international news, weather information, ongoing sports scores, and other personalized content on web site. Just think how much effort & time it will take me to develop this application, if I will start writing code for all these functionalities. On the other hand all these functionalities are already provided by other available sites. So, what if I can use these logics in my application!!! But, question here is “how I can use someone else’s business logic in my application?”.

For situations of this sort (& many other), we have techniques like WebService.

With web services, you can reuse someone else's business logic instead of replicating it yourself, using just a few lines of code. This technique is similar to what programmers currently do with libraries of APIs, dlls or plug-ins. The main difference is that web services can be located remotely on another server.

While HTML pages (or the HTML output generated by ASP.NET web forms) are rendered on browser for the end user, web services are invoked by other applications. They are pieces of business logic that is hosted somewhere on the internet & can be accessed by other applications.

Note1: Web services are not limited to the .NET Framework. The standards were defined before .NET was released, and they are exposed, used, and supported by vendors other than Microsoft.

Note2: Web services are cross platform, a service written in one language can be invoked by an application in some other language. Only requirement for accessing a service is internet connection to make http request.

As web service is cross platform, there should be some commonly understandable language for requesting service & getting response from the service. Such a standard common language is XML. That's why web services are built on XML-based standards for exchanging data.

As a result, the set of data types web services can use is limited to the set of data types recognized by the XML Schema standard. So you can use simple data types such as strings and numbers to communicate with web service and you can’t send proprietary .NET objects such as a FileStream, an Image, or an EventLog. This restriction makes a lot of sense. As other programming languages have no way to interpret these .NET objects, so even if you could devise a way to send them over the wire, the client might not be able to interpret them, which would thwart interoperability.

Note3: If you need to work with .NET proprietary objects,you can go for .NET remoting. It is a distributed technology which allows to use .NET objects. But non-.NET clients can't consume it.

Here's the list of supported data types.

Built-in types (The Basics) : The built in C# data types such as short, int, long, ushort, uint, ulong, float, double, decimal, bool, string, char, byte, and DateTime.

Custom Objects : You can object of any user defined class. If your class has methods, these methods will not be transmitted to the client.

Arrays : Arrays of any supported type (Built-in or custom objects). You can also use an ArrayList (which is simply converted into an array).

Enumerations : Enums are supported. However, web service uses the string name of the enumeration value (not the underlying integer).

XmlNode : Objects based on System.Xml.XmlNode represent a portion of an XML document. You can use this to send arbitrary XML.

DataSet and DataTable : DataSet and DataTable are allowed. But, Other ADO.NET data objects, such as DataColumns and DataRows, aren't supported.

Create a web service

Web service is a simple asmx page.

Here I will use Visual studio 2012(though you can use any editor), with .net framework 3.5 to create a web service.

Up to framework 3.5, visual studio provides a direct template for Web service. Starting from 4, it doesn’t provide any direct template, so you need to create a web application & add web service to your application(right click on your web application → Add → New Item → WebService).

Let’s create a simple service that will return sum of 2 integers.

Open visual studio in administrator mode. File → New → Project → Select .Net Framework 3.5(on top) → Asp.net web service application → Name your project (I named it as MyWebServiceDemo) → click ok

Creating ASP.NET Web Service Application

Visual studio will create a web service boilerplate (Service1.asmx & Service1.asmx.cs) for you. Now, let's analyze this template created by visual studio.

In Service1.asmx.cs, you can notice

#1. An additional namespace System.Web.Servicesis included along with the 4 default namespaces that visual studio includes for web application.

#2. “Service1” class is inherited from “System.Web.Services.WebService”. By inheriting a class from “System.Web.Services.WebService, you can access built-in ASP.NET objects such as (Application, Session, User, Context, server). If you don't need built-in objects of .net, you don't need to inherit your service class from “WebService”.

#3. “Service1” is decorated with WebService(Namespace = "http://tempuri.org/")” attribute. If you want to expose a class as a service, you need to decorate it withWebService” attribute. This WebService attribute has several properties like:

i. Namespace: This property makes a service uniquely identifiable. This is an xml property. A client application may be consuming several service, so there is probability of naming collision. To avoid this, it's service providers responsibility to use a unique namespace.
ii. Name: Use this property to give a descriptive name to your service
iii. Description: To give a brief description on the service.

#4. “Service1” has another attribute WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)”. This is to indicate the standard which service is following. If service will not confirm to this standard, you will get exception.

#5. One more attribute service is decorated with is “[System.Web.Script.Services.ScriptService]”, to make a service accessible from client script, it should be decorated with this attribute.

#6. The Service1 class has a method HelloWorld, that is decorated with “[WebMethod]” attribute. The methods of service which are to be accessed by client application should be decorated with this attribute. There may be some method that service is using for some internal functionality, client applications don't need to access them. Don't decorate such methods with WebMethod attribute. WebMethod attribute also has Name & Description properties that you can use to give a self describing name or description respectively.

Now let's see the mark up. Right click on Service1.asmx in solution explorer → select view mark up. In Service1.asmx, you can notice there is only a WebService directive with some attributes. As a service will be invoked by some application not by any end user. So the asmx page is not having any mark up.

<%@ WebService Language="C#" CodeBehind="Service1.asmx.cs" Class="MyWebServiceDemo.Service1"%>

The “WebService” directive, indicates this asmx page is a web service.

The “Language="C#"”, is to indicate language used for this service.

The “CodeBehind” property is nothing to do with asp.net or web service, this is completely a visual studio property, that is used to map the asmx page with it's code behind page.

The “Class property holds fully qualified name of service class. This marks the entry point of service like main() in C programming language.

Now, run your application by hitting F5, http://localhost:56655/Service1.asmx will open in your browser(port number may vary). You will find a link for Service Description, that will redirect to WSDL document of service, another link for HelloWorld (list for methods exposed by service) that will redirect to a page for testing this method.

Implementing a web service

Now let's implement service. Rename “Service1” file in solution explorer to something convenient like “MyService”. Change the class name from Service1 to MyService or you can just delete Service1.asmx & create MyService.asmx. Open the mark up(asmx) page.

Service mark up

As you can notice here visual studio is unable to resolve “Service1” in class property. As class indicates fully qualified name of service and we renamed our Service1 class to MyService. So visual studio is unable to resolve it. So, now change the class property to “MyWebServiceDemo.MyService”. Change “CodeBehind” property from “Service1.asmx.cs” to “MyService.asmx.cs” as we renamed the file also.

MyService.asmx

<%@ WebService Language="C#" CodeBehind="MyService.asmx.cs" Class="MyWebServiceDemo.MyService"%>

MyService.asmx.cs

using System.Web.Script.Serialization;
using System.Web.Services;
namespace MyWebServiceDemo
{
// Use "Namespace" attribute with an unique name,to make service uniquely discoverable

[WebService(Namespace = "http://tempuri.org/")]

// To indicate service confirms to "WsiProfiles.BasicProfile1_1" standard,
// if not, it will throw compile time error.
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To restrict this service from getting added as a custom tool to toolbox
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX
[System.Web.Script.Services.ScriptService]
public class MyService : WebService
{
[WebMethod]
public int SumOfNums(int First, int Second)
{
return First + Second;
}
}

}

Now, service is ready to be used, let's compile & test it.

Test a web service

Let's run the project by hitting F5, “ http://localhost:56655/MyService.asmx” page will open which has a link for Service description (the WSDL document, documentation for web service) another link for SumOfNums, which is for test page of SumOfNums method.

Let's use method overloading OOP concept. Add following WebMethod in MyService class.

[WebMethod]
public float SumOfNums(float First, float Second)
{
return First + Second;
}

Hit F5 to run application, you will get Both Single SumOfNums(Single, Single) and Int32 SumOfNums(Int32, Int32) use the message name 'SumOfNums'. Use the MessageName property of the WebMethod custom attribute to specify unique message names for the methods.” error message. We just used method overloading concept, so why this error message? This is because these methods are not unique for a client application. As the error message suggests let's use MessageName property of WebMethod attribute as shown below:

[WebMethod (MessageName = "SumOfFloats")]
public float SumOfNums(float First, float Second)
{
    return First + Second;
}

Now, compile & run the application. Again it's showing some different error message “Service 'MyWebServiceDemo.MyService' does not conform to WS-I Basic Profile v1.1”. As, WsiProfiles.BasicProfile1_1 doesn't support method overloading we are getting this exception. Now, either remove this “[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]” attribute or make it “[WebServiceBinding(ConformsTo = WsiProfiles.None)]”.

using System.Web.Script.Serialization;
using System.Web.Services;
namespace MyWebServiceDemo
{
 [WebService(Namespace = "http://tempuri.org/")]
 [WebServiceBinding(ConformsTo = WsiProfiles.None)] 
 [System.ComponentModel.ToolboxItem(false)]
 [System.Web.Script.Services.ScriptService]
    public class MyService : WebService
    {
 [WebMethod]
        public int SumOfNums(int First, int Second)
        {
            return First + Second;
        }
 [WebMethod(MessageName = "SumOfFloats")]
        public float SumOfNums(float First, float Second)
        {
            return First + Second;
        }
    }
}

The Test page

Click on SumOfNums, you will be redirected to “http://localhost:56655/MyService.asmx?op=SumOfNums”. You can notice here just “?op=SumOfNums” is appended to service url. This page has 2 text boxes for 2 input values(First, Second) which SumOfNums method takes as input parameter and button “Invoke”, clicking on which you'll be redirected tohttp://localhost/WebServiceForBlog/MyService.asmx/SumOfNumswhich is having value that SumOfNums method returned in xml format.

Similarly, by Clicking on “SumOfNums MessageName="SumOfFloats"”, you will be redirected to “http://localhost:56655/MyService.asmx?op=SumOfFloats”. So the SumOfNums MessageName="SumOfFloats"” method will be known as “SumOfFloats” for client applications.

Now, question is from where this test page came? We never added any mark up still a page got rendered!!!

The test pages aren't part of the web services; they're just a frill provided by ASP.NET. In fact, the test page is rendered by ASP.NET on the fly using the web page c:\[WinDir]\Microsoft. NET\Framework\[Version] \Config\DefaultWsdlHelpGenerator.aspx. “Reflection” concept is used to render test page.

You can also modify this test page for which you simply need to copy the DefaultWsdlHelpGenerator.aspx file to your web application directory, modify it, give it a name, I named it as “MyWsdlHelpGenerator.aspx” and then change the web.config file for the application by adding the <wsdlHelpGenerator> element, as shown here:

<configuration>
 <system.web>
  <webServices>
   <wsdlHelpGenerator href="MyWsdlHelpGenerator.aspx"/>
  </webServices>
 </system.web>
</configuration>

The WSDL document

Web services are self-describing, which means ASP.NET automatically provides all the information the client needs to consume a service as a WSDL document. The WSDL document tells a client what methods are present in a web service, what parameters and return values each method uses, and how to communicate with them. WSDL is a xml standard. We'll explore the WSDL document in our next articles.

Host web service

AS we are going to add reference to this service & consume it from different applications and port number supposed to change, let's host this service on IIS to have a specific address of service. Open IIS, go to default web sites node → Add Application → Give an alias name (I gave WebServiceForBlog) → browse to physical location of your service for physical path field → click “OK”. Now, you can browse with alias name (like http://localhost/WebServiceForBlog/) to test if application got hosted properly. You'll get “HTTP Error 403.14 – Forbidden” error as there is no default document set for this application. Add “MyService.asmx” page as a default document. Now you can browse your service.

Reference

Book: Pro ASP.NET 3.5 in C# 2008

Discussion
25 - Five
** To prevent abusing comments from publishing, posted comments will be reviewed and then published!
 Rasmita Dash
Works at Mindfire Solutions

Software developer