Creating a Web Service in Microsoft.NET and consuming from WebLogic’s Web Client

Creating a Web Service in Microsoft.NET and consuming from WebLogic’s Web Client



By: John Charles Olamendy Turruellas.

According to Microsoft.NET, Web Services are not inherently service-oriented—they represent a solution to implementing a SOA strategy. Web Services provide a necessary standards-based implementation of SOA wherein services are described using WSDL and accessed via SOAP. So that interoperability across platform, organizational, and network boundaries is feasible. Web Services technologies implemented by the .NET distributed computing model can support such a strategy.

Web Services are logic units that allow programs written in different programming languages and on different platforms to communicate through standard Internet protocols. Microsoft has stated: “XML Web Services platform will enable developers to create programs that transcend device boundaries and fully harness the connectivity of the Internet.”
Web Services allow applications, which may be written in different programming languages or on different platforms, to communicate and share data through standard Internet protocols.

Implementing a Web Services in Microsoft.NET.

Microsoft.NET includes a good support for Web Services. Using Visual Studio .NET let’s create Web Services implementations from a project template. Whether we create our Web Services in Microsoft.NET Framework or in Java, there are several common concepts, such as, we have a business object implementing some logic and we want to provide such behavior as a Service to other elements.

Creating Web Services in .NET Framework.
Web services are tightly integrated into the .NET Framework. It’s very easy to use the Visual Studio .NET to design and create a Web service. The .NET Web services implementation uses the same page framework as ASP.NET, consisting of the following:
? URL for accessing the Web Service (.asmx file).
?The code behind which implement the Web Service’s behavior. It might be a backend object providing its behavior through the Web Service.

Using Visual Studio .NET, we may create an ASP.NET Web service project in any of the supported languages using the Web service project templates (File -> New -> Project -> ASP.NET Web Application).

After we create an ASP.NET Web service project in Visual Studio, it’s constructed a
Web application project structure, that is the .asmx file and the code behind associated for each Web Services and the references to external components, on the Web server which we have chosen and a Visual Studio solution file on our local computer which contains the configuration and build settings and keeps a list of files associated with the project.

We are going to model the Purchase Order Information object using the Business Entity POInfo as information holder. The logic of our Web Service is very simple. The contract to the clients is composed by two operations, first one is initializing a standard Purchase Order, and the second one is receiving a Purchase Object serialized in XML as a message and make some changes in its state such shipping date, the user id, etc.
We can implement the functionality of a Web Services using a class, and marking with attributes the context of the class and the exportable methods (Aspect-Oriented programming).

Using the WebServiceAttribute attribute object we may specify the context of the instance of our WebService such as a description, a name and its namespace. Using the WebMethodAttribute attribute object we may configure aspects of the available method such as its name and a description, whether the messaging is buffered or not, whether it’s bound to a session for implementing a stateful services.

Listing 1 shows the definition of the POInfo information holder (Purchase Order Information Business Entity), and in listing 2 the implementation of the PurchaseOrder Web Service.

using System;

namespace WSTest
{
public class POInfo
{
private int m_nId=0;
private string m_strLastName=null;
private string m_strFirstName=null;
private DateTime m_dtShipping=DateTime.Now;
private int m_nAmount=0;

public POInfo()
{}

public int Id
{
get
{
return this.m_nId;
}
set
{
this.m_nId=value;
}
}
public string LastName
{
get
{
return this.m_strLastName;
}
set
{
this.m_strLastName=value;
}
}
public string FirstName
{
get
{
return this.m_strFirstName;
}
set
{
this.m_strFirstName=value;
}
}
public DateTime Shipping
{
get
{
return this.m_dtShipping;
}
set
{
this.m_dtShipping=value;
}
}
public int Amount
{
get
{
return this.m_nAmount;
}
set
{
this.m_nAmount=value;
}
}
}
}

Listing 1.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;

namespace WSTest
{
///
/// Summary description for PurchaseOrder.
///

///

[WebService(Namespace="http://www.olamendy.com/")]
public class PurchaseOrder : System.Web.Services.WebService
{
public PurchaseOrder()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
}

#region Component Designer generated code

//Required by the Web Services Designer
private IContainer components = null;

///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
}

///
/// Clean up any resources being used.
///

protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion

// WEB SERVICE EXAMPLE
// The HelloWorld() example service returns the string Hello World
// To build, uncomment the following lines then save and build the project
// To test this web service, press F5

[WebMethod]
public POInfo GetPurchaseOrderInfo()
{
POInfo objInfo=new POInfo();

objInfo.Amount=10;
objInfo.FirstName="John Charles";
objInfo.LastName="Olamendy";
objInfo.Id=3;
objInfo.Shipping=DateTime.Now;

return objInfo;
}

[WebMethod]
public POInfo ProcessPurchaseOrderInfo(POInfo objInfo)
{
objInfo.Amount=objInfo.Amount+1;
objInfo.FirstName=objInfo.FirstName+":C";
objInfo.LastName=objInfo.LastName+":C";
objInfo.Id=objInfo.Id+1;
objInfo.Shipping=objInfo.Shipping.AddDays(1);

return objInfo;
}
}
}

Listing 2.

After we build a Web service, ASP.NET automatically provides the infrastructure and handles the processing of Web service requests and responses such as the serialization and de serialization of the involved objects and the creation of SOAP messages. We may access to this WebServices using the URL pointing to .asmx file, for instance http://localhost/WSTest/ PurchaseOrder.asmx .It is also created a test page for the Web Services for watching its behavior.

Creating a WebCient in BEA WebLogic which consumes the Web Services.

After we create our Web service, we need to have client applications to access it. There are several ways of doing this, depending on the protocols that our Web service supports.
If our Web service supports the HTTP-GET protocol, we can access it from a Web browser. By default, Web services that we create in Visual Studio using the ASP.NET Web service project template support HTTP-GET, HTTP-POST, and HTTP-SOAP. In our case, we’re going to access unsing HTTP-SOAP.

We’re going to create an application in BEA WebLogic, File->New->Application->Default Application. Then, it is created a J2EE application, and inside the former, a Web Module.

First of all, we must access to the Web Service’s contract for taking the description of all operations and using the URL http://localhost/WSTest/PurchaseOrder.asmx?wsdl it is download an XML application where all the operations, the messages and transport protocol are specified. Then save this document as PurchaseOrder.wsdl inside our WebLogic Web Module. Then using the WebLogic Workshop’s Application View browse to the file PurchaseOrder.wsdl right-click and choose Generate Service Control generating all the plumbing for the messaging on behalf of us with the Web Services protocol stack, such PurchaseOrderControl which is a Java Control acting a proxy with the real Web Service, and all the XML persistent data types for creating the messages.
Listing 3 shows the generated code.

package ControlRef;

/**
* @jc:location http-url="http://localhost/wstest/PurchaseOrder.asmx"
* @jc:wsdl file="#PurchaseOrderWsdl"
* @editor-info:link source="PurchaseOrder.wsdl" autogen="true"
*/
public interface PurchaseOrderControl extends com.bea.control.ControlExtension, com.bea.control.ServiceControl
{
public static class POInfo
implements java.io.Serializable
{
public int Id;
public java.lang.String LastName;
public java.lang.String FirstName;
public java.util.Calendar Shipping;
public int Amount;
}


/**
* @jc:protocol form-post="false" form-get="false"
*/
public POInfo GetPurchaseOrderInfo ();

/**
* @jc:protocol form-post="false" form-get="false"
*/
public POInfo ProcessPurchaseOrderInfo (POInfo objInfo);

static final long serialVersionUID = 1L;
}

/** @common:define name="PurchaseOrderWsdl" value::
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.olamendy.com/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.olamendy.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.olamendy.com/">
<s:element name="GetPurchaseOrderInfo">
<s:complexType />
</s:element>
<s:element name="GetPurchaseOrderInfoResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetPurchaseOrderInfoResult" type="tns:POInfo" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="POInfo">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="LastName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="FirstName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Shipping" type="s:dateTime" />
<s:element minOccurs="1" maxOccurs="1" name="Amount" type="s:int" />
</s:sequence>
</s:complexType>
<s:element name="ProcessPurchaseOrderInfo">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="objInfo" type="tns:POInfo" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ProcessPurchaseOrderInfoResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ProcessPurchaseOrderInfoResult" type="tns:POInfo" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="GetPurchaseOrderInfoSoapIn">
<wsdl:part name="parameters" element="tns:GetPurchaseOrderInfo" />
</wsdl:message>
<wsdl:message name="GetPurchaseOrderInfoSoapOut">
<wsdl:part name="parameters" element="tns:GetPurchaseOrderInfoResponse" />
</wsdl:message>
<wsdl:message name="ProcessPurchaseOrderInfoSoapIn">
<wsdl:part name="parameters" element="tns:ProcessPurchaseOrderInfo" />
</wsdl:message>
<wsdl:message name="ProcessPurchaseOrderInfoSoapOut">
<wsdl:part name="parameters" element="tns:ProcessPurchaseOrderInfoResponse" />
</wsdl:message>
<wsdl:portType name="PurchaseOrderSoap">
<wsdl:operation name="GetPurchaseOrderInfo">
<wsdl:input message="tns:GetPurchaseOrderInfoSoapIn" />
<wsdl:output message="tns:GetPurchaseOrderInfoSoapOut" />
</wsdl:operation>
<wsdl:operation name="ProcessPurchaseOrderInfo">
<wsdl:input message="tns:ProcessPurchaseOrderInfoSoapIn" />
<wsdl:output message="tns:ProcessPurchaseOrderInfoSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PurchaseOrderSoap" type="tns:PurchaseOrderSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GetPurchaseOrderInfo">
<soap:operation soapAction="http://www.olamendy.com/GetPurchaseOrderInfo" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ProcessPurchaseOrderInfo">
<soap:operation soapAction="http://www.olamendy.com/ProcessPurchaseOrderInfo" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PurchaseOrder">
<wsdl:port name="PurchaseOrderSoap" binding="tns:PurchaseOrderSoap">
<soap:address location="http://localhost/wstest/PurchaseOrder.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
* ::
*/

Listing 3.

Using Model-View-Controller design pattern is very easy in WebLogic. We may define the flow of the pages using the PageFlowController class, an instance of the class PageFlowController manages all the pages, loading the right page according to the flow definition and calling the application logic on behalf of the pages using the actions.

In this case, when application starts, it is loaded the page index.jsp for gathering user information, then the user triggers the getPurchaseOrder action, for calling the logic of the application and doing some operations, in our case it is an access to the former PurchaseOrder Web Service, sending a messages and waiting a response message using the SOAP/HTTP as a transport protocol. Finally the message is received, the page response.jsp is loaded and the information is shown to user.

In the definition of the PageFlowController, it is created an instance of the Java Control PurchaseOrderControl for accessing the Web Service, and it’s also define a reference to the object Purchase Order received from the messaging.

The code of the getPurchaseOrder action is shown in the listing 4.
   
/**
* @jpf:action
* @jpf:forward name="success" path="response.jsp"
*/
protected Forward getPurchaseOrder(GetPurchaseOrderForm form)
{
ControlRef.PurchaseOrderControl.POInfo objInfo=new ControlRef.PurchaseOrderControl.POInfo();
objInfo.Amount=form.amount;
objInfo.FirstName=form.firstname;
objInfo.Id=form.id;
objInfo.LastName=form.lastname;
objInfo.Shipping=java.util.Calendar.getInstance();

this.POInfo=this.purchaseOrderControl.ProcessPurchaseOrderInfo(objInfo);
return new Forward("success");
}

Listing 4.

It is created an instance of POInfo class and filled the state with the gathered information from index.jsp. Then it is called the operation ProcessPurchaseOrderInfo in the instance of PurchaseOrder proxy control, which receives a POInfo object, serializes it to XML and then passes it to the Web Services stack.

Conclusion.
This article explains the step necessary to create a Web Service in Microsoft.NET and consume it from a Web Client in BEA WebLogic. It is touched important aspects of Microsoft.NET technologies for Web Services, and BEA WebLogic technologies for implement the Model-View-Controller design pattern.


Comments

Author: ketan Italiya21 Aug 2013 Member Level: Gold   Points : 0

It is so helpful..
thanks



Author: ketan Italiya22 Aug 2013 Member Level: Gold   Points : 8

See this and please don't forget to give review it.

How do i pass user name, password when calling web services ? or
How do i authenticate the web service request before invoking web methods ?

There are several ways to do this and one of the most easiest way is to pass user name, password as input parameters to web method called. but na, that is not a good way to implement as this information is at the periphery of the core business functionality of the web service exposed. Hence keeping this out makes more sense.

Another way to control anonymous access can be achieved through IIS (web server) settings. Just uncheck the anonymous access or limit the IPs that can hit your web services or validate it against your windows account group... but again you may want to implement partial anonymous access! Few web methods can be accessed by everyone, few have restricted access.

In that case, better way to do this is to pass this information into SOAP header (SOAP web services communicate through SOAP messages - which include SOAP envelope (inc. namespace and root element), SOAP Header (this is optional) and SOAP body (contains web method, input parameters and response result)

Working with SOAP Headers in order to have a Web service accept a SOAP header we need to perform the following three tasks:
1> Define a SOAP header class in the Web service project

public class AuthenticationHeader : SoapHeader
{
public string Username;
public string Password;
}

2> Add a public member variable of the SOAP header class created in step (1) to the Web service class

[WebService(Namespace=http://www.comp.com/yournamespace )]
public class MyWebService : System.Web.Services.WebService
{
public AuthenticationHeader AuthHeader;
... The Web service's methods would be defined down here ...
}

3> Add the SoapHeader attribute to the Web method(s) that need to be able to programmatically access the value of the header

Once we perform these three steps at the Web service's end, our next task is to configure the client so that it can invoke a Web service method and pass along data for the appropriate SOAP header(s). The first step, as we've discussed in earlier installments of this article series, is to create a proxy class on the client. This will auto-generate the SOAP header class defined in the Web service project and will add a public property to the proxy class through which an instance of the SOAP header can be affixed to outgoing messages.

To actually pass along a populated SOAP header when calling a Web method the client needs to first create an instance of the proxy's SOAP header class, populate its values, and then assign this header class instance to the appropriate proxy class property. Finally, calling one of the Web service's methods will invoke the method, passing along the SOAP header.

[WebMethod(), SoapHeader("AuthHeader")]
public string GetMessage()
{
// Only allow valid user/password to access this secret message...
if (AuthHeader.Username == "user" && AuthHeader.Password == "password")
return "This is the secret message!!!";
else
return "YOU ARE NOT AUTHORIZED TO SEE THIS MESSAGE!";
}

In order to send a SOAP header to the Web service method, the client should do the following:
1> Create an instance of the proxy class,
2> Create an instance of the SOAP header class and populate its values,
3> Affix the SOAP header to the proxy class by assigning the SOAP header class instance created in step (2) to the proxy class's AuthHeaderValue property, and, finally
4> Call the Web service method

The following code illustrates these four steps. The GetMessage() Web method is invoked from the client passing along a username/password pair of scott and password.

// step 1, create the proxy class
localhost.MyWebService proxy = new localhost.MyWebService();
// step 2, create and populate the header class
localhost.AuthenticationHeader authInfo = new localhost.AuthenticationHeader();
authInfo.Username = "user";
authInfo.Password = "password";
// step 3, affix the SOAP header to the proxy
proxy.AuthHeaderValue = authInfo;
// step 4, call the method
string result = proxy.GetMessage();
The value returned from GetMessage() will contain the appropriate message, based on the username/password sent via the SOAP header.



Thanks
ketan



  • Do not include your name, "with regards" etc in the comment. Write detailed comment, relevant to the topic.
  • No HTML formatting and links to other web sites are allowed.
  • This is a strictly moderated site. Absolutely no spam allowed.
  • Name:
    Email: