Вы находитесь на странице: 1из 20

Si nuestra aplicacin tiene que llevar a cabo un cierto trabajo que no sabemos cuanto durar y que a la vez consume

muchos recursos, tenemos dos problemas, como le hacemos saber al usuario que tiene que esperar un tiempo sin hacer nada? y segundo, como evitamos que nuestra aplicacin se cuelgue mientras el trabajo an no termina?. Para esos problemas tenemos una solucin, utilizar el componente swing jProgressBar (barra de progreso) combinado con Thread (hilos) . La implementacin no es ta difcil como suena pero que mejor que con un ejemplo, manos a la obra. 1. Partimos de un proyecto en netbeans que estar compuesto de la siguiente forma:

Un JFrame llamado interfaz.java, en esa interfaz tenemos un jbutton, un jProgressBar y dos jTextField. Los nombres de cada objeto estn en rojo. El objeto TimeJob nos indicar el tiempo en segundos que durara un cierto proceso en paralelo y el objeto SpeedBar se refiere a la velocidad de la animacin del Jprogressbar. Tenemos ademas tres clases, la clase JcSampleBar, la clase Job.java y jcThread.java. explicamos el contenido y cdigo ms abajo, 2. La clase JcSampleBar es nuestro main encargado de lanzar la aplicacin, el cdigo es:
public class JcSampleBar { public static void main(String[] args) { new interfaz().setVisible(true); } }

3. Simularemos un trabajo XYZ en la clase Job.java la cual implementa Runnable para hacer uso de hilos. Este proceso XYZ se ejecutara cada cierto tiempo. En la prctica, este proceso puede ser una consulta a la base de datos, conexin a un servidor web, eliminacin de archivos, etc. todos estos ejemplos, tienen algo en comn, no sabemos cuanto tiempo duraran, controlaremos eso utilizando una variable statica band que inicial izaremos en FALSE, eso quiere decir que an el proceso no a terminado, desde luego, cuando el proceso finalice, la variable cambiara a TRUE, el static es para poder utilizar esta variable desde otra clase, la clase jcThread que veremos ms adelante.
public class Job implements Runnable{ public static boolean band=false; private int tiempo = 5;

/** * Constructor de clase */ public Job( int tiempo ){ this.tiempo = tiempo; } @Override public void run() { band=false; for (int i=1; i <= this.tiempo ; i++){ System.out.println("Haciendo algo divertido... -> " + i + " segundo transcurrido."); try{Thread.sleep( 1000 );} catch (InterruptedException e){ System.err.println( e.getMessage() ); } } band=true; } }

3. La clase jcThread.java, es la encargada de animar el JProgressBar tambin implementa la clase Runnable para el manejo de hilos. En el mtodo RUN implementaremos un ciclo WHILE para animar la barra de progreso la cual estar controlado por la variable BAND de la clase Job.java, cuando el trabajo en paralelo finalice, el ciclo se romper dando fin a la animacin del progressbar .
import javax.swing.JProgressBar; /** * @web http://www.jc-mouse.net * @author Mouse */ public class jcThread implements Runnable{ private JProgressBar jProgressBar; private int i = 1; private int value = 50;//retardo en milisegundos /** * Constructor de clase */ public jcThread( JProgressBar jProgressBar , int value ) { this.jProgressBar = jProgressBar; this.value = value; } @Override public void run() { i=1; //mientra el trabajo en paralelo no finalice el jProgressBar continuara su animacion una y otra vez while( !Job.band ) { //si llega al limite 100 comienza otra vez desde 1, sino incrementa i en +1 i = (i > 100) ? 1 : i+1; jProgressBar.setValue(i); jProgressBar.repaint();

//retardo en milisegundos try{Thread.sleep( this.value );} catch (InterruptedException e){ System.err.println( e.getMessage() ); } //si el trabajo en paralelo a terminado if( Job.band ) { jProgressBar.setValue(100); System.out.println("Trabajo finalizado..."); break;//rompe ciclo } } } }

4. Finalmente la clase interfaz.java donde implementaremos ambos hilos en el evento ActionPerformed del jbutton,
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { //trabajo cualquiera new Thread(new Job( Integer.valueOf(TimeJob.getText()))).start(); // animacion de jProgressBar new Thread(new jcThread( this.jProgressBar1 , Integer.valueOf(SpeedBar.getText()) ) ).start(); }

Ejecutando ahora tendremos como resultado:

a diferentes valores de las variables de TimeJob y SpeedBar podremos comprender mejor como funciona :=D Eso es todo bjate el proyecto en netbeans 7.2 AQUI

Te gusto el post? Comparte con tus amigos..

How to consume an ASP.NET webservice from Java via SOAP


By David S Hobbs, 15 Jan 2004

4.29 (22 votes) Sign Up to vote vote 1vote 2vote 3vote 4vote 5

Download demo project - 14.6 Kb

Introduction
This article will be useful if you need to consume ASP.NET webservices from languages or platforms without .NET support. In this example, I am consuming a webservice from a Java applet, but it would take very little work to adapt my code to run as a Java application. Although I have only tested this on Windows XP, the code should run on other platforms, providing crossplatform client-side consumption of ASP.NET webservices. I developed this solution because I needed to add complex client-side processing to my ASP.NET application. I did not want to have to cope with all of the slightly different JavaScript implementations used by the main browsers, and this led me to consider a Java applet. This article shows you how to use a Java applet in your webpage and get it to communicate back to ASP.NET by consuming an XML webservice on the client.

Background
There are, no doubt, many reasons why somebody might want cross-platform consumption of ASP.NET webservices, but this is my story: I have an ASP.NET application where I needed to add client side image manipulation facilities. I looked into writing the client-side code in JavaScript which seemed like the obvious choice, but was frustrated by different implementations in the browsers, especially when trying to use image manipulation features. For example, if you want to alpha blend your image, you would have to use img.style.MozOpacity in Netscape, img.filters.alpha.opacity in Internet Explorer and there is no way to do this at all in Opera. I really didn't want to have to write special code for each browser or downgrade the functionality to the lowest common denominator. Therefore, I decided to try writing my client-side code in Java 1.1. Note that I'm using the Java 1.1 SDK, as Internet Explorer currently does not support code developed with Java SDKs after

1.1.4 (although it seems to me that Java SDK 1.1.7 code seems to work OK in IE). A Java applet can do all of the image manipulation I needed and is supported by many browsers. Finally, I don't have to write separate code for each browser. The next problem was, how do I get the result of the data processing done in the Java applet back into my ASP.NET application? The answer that I came up with was to create an ASP.NET webservice and consume it in the Java applet.

A Simple Example
Take a look at the following very basic webservice:
Collapse | Copy Code
[WebMethod] public string ConcatWithSpace(string one, string two) { return one+" "+two; }

It could be consumed very simply by making the Java applet perform a request to: webservice.asmx/ConcatWithSpace?one=FirstValue&two=SecondValue... But what if we wanted to send larger amounts of data to the webservice? How would we go about implementing a SOAP request and response in a Java applet...? There are probably many options if you are using a more recent Java SDK, but because I want to support many browsers including Internet Explorer, I'm stuck with the Java 1.1 SDK. However, this gives us a better opportunity to understand how to talk to ASP.NET web services on other languages and platforms. Therefore, I have written my own SoapRequestBuilder class in Java that makes it quite easy to consume a service and return a single string response. Take a look at this example, which consumes the webservice above:
Collapse | Copy Code
SoapRequestBuilder s = new SoapRequestBuilder(); s.Server = "127.0.0.1"; // server ip address or name s.MethodName = "ConcatWithSpace"; s.XmlNamespace = "http://tempuri.org/"; s.WebServicePath = "/SimpleService/Service1.asmx"; s.SoapAction = s.XmlNamespace+s.MethodName; s.AddParameter("one", "David"); s.AddParameter("two", "Hobbs"); String response = s.sendRequest();

In this example, the response string is filled with the result from the webservice after we sent it two parameters. The full source code of the SoapRequestBuilder class is included in the source files. That's it! It's only a very simple example and at the moment, I'm only interested in returning a single value back from the webservice, but I have used something similar with a webservice that

talks to my back-end database and this allows my Java applet to store data which can then be accessed by the ASP.NET pages. To run the example code, set up the webservice first, then copy the Java applet files to any folder on the same machine and double-click the HTML file. All of the parameters are configured inside the HTML file, so you can change the values passed to the webservice by editing the HTML; you should not have to re-compile the Java source. I have tested the example in IE 6.0, Netscape 7.1 and Opera 7.23 on Windows XP.

Notes
Some Java Virtual Machines (like the Microsoft one) only allow you to make a socket connection to the same machine that hosts the Java class files. Therefore, if you're using an applet like me, you will need to host the Java class files on the same machine where the webservice resides.

License
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below. A list of licenses authors might use can be found here

Consuming .NET Web Service from Java


In this blog, I want to show you a couple of things about Web Services. Here is the list of things on my mind.

How to create a web service using .NET with C#. How to use DAL (Data Access Layer) to access database. This is used from Web Service code. So that Web Service doesn't depend on data access API. How to use custom classes in Web Services. This class goes to client in the form of XML Schema so that client can generate class from schema. How to consume this web service (created in .NET) from Java. We create proxy for this Web Service in Java and call methods through proxy.

Creating a web service


First let us create a new project in Visual Studio.NET for web service. Then add classes related to data access and write code for Web Service methods. 1. Start Visual studio.NET 2008/2005 2. Select File->New->Website. Select ASP.NET Web service as the type of the project and enter InventoryWS as the name of the project. Visual Studio provides Service.cs and Service.asmx files along with others. Delete these two files.

3. We add a new web service to the project using Website -> Add new item -> Web Service and enter name as InventoryService. Visual Studio creates InventoryService.aspx in root directory and InventoryService.cs in App_Code directory. We will write code for web service later. First let us create DAL to access database.

Creating Data Access Layer


Data Access Layer is set of classes used to access database. We centralize the entire data access to DAL. In this project we create two classes to represent data.

I am using PRODUCTS table, which is created by me in MSDB database of Sql Server Express Edition. You have to do the same in your system. Create PRODUCTS table with the following structure.
PRODID prodname price qoh remarks catcode int (Primary key) varchar(50) money int varchar(200) varchar(10)

Add some rows to PRODUCTS table.

Add a class to the project using Website-> Add New Item -> Class and enter name as Product. Here is the code for Product.cs.
using System; using System.Web.Services; using System.Runtime.Serialization; public class Product { private int prodid, qty; private string name, remarks; private double price; public int Qty { get { return qty; } set { qty = value; } } public int Prodid { get { return prodid; } set { prodid = value; } } public string Remarks { get { return remarks; } set { remarks = value; } }

public string Name { get { return name; } set { name = value; } } public double Price { get { return price; } set { price = value; } } }

Add connection string in connectionStrings section of web.config as follows.


<connectionStrings> <add name="msdbcs" connectionString="data source=localhost\sqlexpress;integrated security=true;Initial Catalog=msdb" providerName="System.Data.SqlClient" /> </connectionStrings >

Add Database.cs class and enter the following code.


using System.Web.Configuration; public class Database { public static string ConnectionString { get { return WebConfigurationManager.ConnectionStrings["msdbcs"].ConnectionString; } } }

Now create ProductDAL, which contains static methods for operations related to PRODUCTS table as follows.
using System; using System.Data; using System.Data.SqlClient; using System.Collections.Generic; public class ProductsDAL { public static List GetAllProducts() { SqlConnection con = new SqlConnection(Database.ConnectionString); con.Open(); SqlCommand cmd = new SqlCommand("select * from products", con); SqlDataReader dr = cmd.ExecuteReader(); List products = new List(); while (dr.Read()) { Product p = new Product(); p.Prodid = (int)dr["prodid"]; p.Name = dr["prodname"].ToString(); p.Remarks = dr["remarks"].ToString(); p.Qty = (int)dr["qoh"];

p.Price = Convert.ToDouble(dr["price"]); products.Add(p); } dr.Close(); con.Close(); return products; } public static Product GetProduct(int prodid) { SqlConnection con = new SqlConnection(Database.ConnectionString); con.Open(); SqlCommand cmd = new SqlCommand("select * from products where prodid = @prodid", con); cmd.Parameters.AddWithValue("@prodid", prodid); SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) { Product p = new Product(); p.Prodid = (int) dr["prodid"]; p.Name = dr["prodname"].ToString(); p.Remarks = dr["remarks"].ToString(); p.Qty = (int) dr["qoh"]; p.Price = Convert.ToDouble (dr["price"]); return p; } else } } // product not found return null;

Using DAL in Web Service


Now let us write code in web service, which makes use of DAL. It is always better you separate data access code into DAL so that other parts of the application do not depend on data access. They access database through DAL.

Write the following code in InventoryService.cs.


using System; using System.Web.Services; using System.Collections.Generic; [WebService(Namespace = "http://www.srikanthtechnologies.com/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class InventoryService : System.Web.Services.WebService { [WebMethod( Description ="Returns Details Of All Products")] public List GetAllProducts() { return ProductsDAL.GetAllProducts(); } [WebMethod(Description = "Returns Details Of A Single Product ")]

public Product GetProduct(int prodid) { return ProductsDAL.GetProduct(prodid); } }

Now we are through our web service creation. Select web service - InventoryService.asmx and select View In Browser option from context menu (right click).

From the page displayed in browser, click on methods and invoke them to test them.

Custom classes and WSDL


Click on Service Description link and you get WSDL for the web service. The following section in that is of interest.
<s:complexType name="ArrayOfProduct"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Product" nillable="true" type="tns:Product" /> </s:sequence> </s:complexType> <s:complexType name="Product"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Qty" type="s:int" /> <s:element minOccurs="1" maxOccurs="1" name="Prodid" type="s:int" /> <s:element minOccurs="0" maxOccurs="1" name="Remarks" type="s:string" /> <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="Price" type="s:double" /> </s:sequence> </s:complexType>

Product class is taken as complexType and its members are placed as sub elements. Collection of Products is taken as an ArrayOfProduct. When you need to access this web service from Java application, we create proxy in Java. Product element will become a class in Java and ArrayOfProduct becomes another class that contains a List of product objects. So, WSDL contains details about custom classes so that clients can generate these classes again on the client.

Creating Proxy in Java


Now, let us create a proxy in Java to access InventoryService Web Service. 1. Start NetBeans IDE 6.5. 2. Select File->New Project. Select Java in category and Java Application in projects. Click on Next. 3. Enter InventoryClient as the name of the application. Change name of the class in Create Main Class option to Client 4. Click on Finish. 5. Select InvenotryClient project in Projects window. Right click to invoke context menu. Select New->Other. Select Web service in categories and Web Service Client in File Types.

6. In the next window, select WSDL URL radio button (as shown below) and enter the URL at which InventoryService is running. Click on Finish. NetBeans creates required classes to access web service.

Write code in Java to call web service


Once proxy is created then we can write code to access web service methods from Java. In fact, NetBeans can do that for you. Follow the steps given below. 1. Open Client.java 2. Go into main function and click on right button. From context menu select Web Service Client Resources -> Call Web Service Operation... 3. A window pops up with operations in the web service (shown below).

Select GetProduct in InventoryServiceSoap12 section. NetBeans automatically writes code for you. Just assign product id 100 to prodid and change code regarding output, to complete the code.
try { // Call Web Service Operation com.srikanthtechnologies.InventoryService service = new com.srikanthtechnologies.InventoryService(); com.srikanthtechnologies.InventoryServiceSoap port = service.getInventoryServiceSoap12(); // TODO initialize WS operation arguments here int prodid = 100; // TODO process result here com.srikanthtechnologies.Product result = port.getProduct(prodid); System.out.println( result.getName()); } catch (Exception ex) { // TODO handle custom exceptions here }

Lines in bold are modified by me. The rest is provided by NetBeans. That's all you have to do to call web service created in .NET from Java.

As you can see, NetBeans created a class Product for which information is provided in WSDL. Follow the same steps to call GetAllProducts method. Change the code as follows.

try { // Call Web Service Operation com.srikanthtechnologies.InventoryService service = new com.srikanthtechnologies.InventoryService(); com.srikanthtechnologies.InventoryServiceSoap port = service.getInventoryServiceSoap12(); // TODO process result here com.srikanthtechnologies.ArrayOfProduct result = port.getAllProducts(); List products = result.getProduct(); for(Product p : products) { System.out.println( p.getName() + " : " p.getPrice()); } } catch (Exception ex) { // TODO handle custom exceptions here } +

4. Now, run Client.java to see whether details of products are displayed from Java program.

JTable: Ordenar y filtrar filas


Desde java 6 tenemos las clases TableRowSorter y RowFilter que nos permiten ordenar y filtrar las filas de un JTable de java. Vamos aqu a ver un ejemplo sencillo de cmo se usa.

Contenido
[ocultar]

1 TableRowSorter: el que permite ordenar el JTable 2 RowFilter: el que permite filtrar el JTable 3 El cdigo completo del ejemplo 4 Otros filtros ya construidos o 4.1 RowFilter.regexFilter() o 4.2 RowFilter.dateFilter() o 4.3 RowFilter.numberFilter() o 4.4 RowFilter and, or y not

TableRowSorter: el que permite ordenar el JTable


Para que la tabla sea ordenable no necesitamos hacer grandes cosas. Basta con pasarle al JTable una instancia de TableRowSorter. A partir de ese momento, haciendo click en la cabecera de las columnas con el ratn, ordenaremos el JTable en orden ascendente o descendente alternativamente segn esa columna.

// Instanciamos nuestro modelo de datos, por ejemplo, DefaultTableModel // y lo metemos en el JTable DefaultTableModel modelo = new DefaultTableModel(); JTable tabla = new JTable(modelo); // Instanciamos el TableRowSorter y lo aadimos al JTable TableRowSorter<TableModel> elQueOrdena = new TableRowSorter<TableModel>(modelo); tabla.setRowSorter(elQueOrdena);

Listo, no necesitamos hacer ms.

RowFilter: el que permite filtrar el JTable


Para el filtro, slo tenemos que pasarle a nuestro TableRowSorter un RowFilter una columna concreta, por medio del mtodo setRowFilter(). Este RowFilter es el que dice si un valor de esa columna (y por tanto la fila entera del JTable) pasa o no pasa el filtro. Si el valor de esa columna no pasa el filtro, la fila entera no lo pasa y no ser visible. Podemos hacernos nuestros propios RowFilter heredando de esta clase e implementando su mtodo abstracto include(), pero RowFilter tiene varios mtodos estticos que nos proporcionan los filtros habituales. En nuestro ejemplo, usaremos un filtro regex, es decir, el dato pasa el filtro si cumple un determinado patrn, que ser muy simple: pasa el filtro si tiene un "2". Para obtener dicho RowFilter, usamos el mtodo RowFilter.regexFilter(). Como primer parmetro se pasa una expresin regular (regex) que tiene que cumplir el dato para pasar el filtro. En nuestro caso es un simple String con un "2" dentro. Como segundo parmetro se pasa un entero para identificar la columna a la que se quiere aplicar el filtro. La primera columna es el cero. En nuestro caso, lo haremos sobre la segunda columna, as que pasaremos un 1.
modeloOrdenado.setRowFilter(RowFilter.regexFilter("2", 1));

Y ya est. Esto har que se oculten todas las filas cuya segunda columna no tenga un 2.

El cdigo completo del ejemplo


Aqu un ejemplo con el cdigo completo.
package chuidiang.ejemplos.jtable; import javax.swing.JFrame; import javax.swing.JScrollPane;

import import import import import import import

javax.swing.JTable; javax.swing.RowFilter; javax.swing.SwingUtilities; javax.swing.WindowConstants; javax.swing.table.DefaultTableModel; javax.swing.table.TableModel; javax.swing.table.TableRowSorter;

/** * Ejemplo de uso de TableRowSorter y RowFilter. * * @author Chuidiang * */ public class PruebaJTable { private TableRowSorter<TableModel> modeloOrdenado; /** * main del ejemplo. * * @param args */ public static void main(String[] args) { new PruebaJTable(); } /** * Instancia un JFrame con un JTable dentro y diez filas de datos. Lleva un * trozo de cdigo comentado para poder reemplazar. */ public PruebaJTable() { JFrame v = new JFrame("Prueba JTable"); // Modelo de datos, segunda columna Integer y primera String. Los // ndices empiezan en cero. DefaultTableModel modelo = new DefaultTableModel() { @Override public Class getColumnClass(int columna) { if (columna == 1) return Integer.class; return String.class; } }; // Aadimos unos datos. modelo.addColumn("columna 1"); modelo.addColumn("columna 2"); for (int i = 0; i < 10; i++) { modelo.addRow(new Object[] { "" + i, 100 - i }); } // Metemos el modelo ordenable en la tabla. modeloOrdenado = new TableRowSorter<TableModel>(modelo); tabla.setRowSorter(modeloOrdenado);

modeloOrdenado.setRowFilter(RowFilter.regexFilter("2", 1)); // Lo pintamos todo en la ventana y la mostramos. JTable tabla = new JTable(modelo); JScrollPane scroll = new JScrollPane(tabla); v.getContentPane().add(scroll); v.pack(); v.setVisible(true); v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } }

Otros filtros ya construidos


RowFilter tiene adems los siguientes mtodos:

RowFilter.regexFilter()
El que hemos visto en el ejemplo. El siguiente filtro hace que pasen las filas que en la primera columna tengan un texto que empiece por "a" minscula
RowFilter.regexFilter("^a", 0);

RowFilter.dateFilter()
Para fechas. El siguiente filtro hara que pasaran el filtro aquellas fechas anteriores a la actual en la columna 2.
RowFilter.dateFilter(ComparisonType.BEFORE, new Date(),1);

RowFilter.numberFilter()
Para nmeros. El siguiente filtro hara que pasaran el filtro las filas con un 10 en la primera columna
RowFilter.numberFilter(ComparisionType.EQUAL, 10, 0);

RowFilter and, or y not

Si hemos construido ya varios RowFilter cualesquiera y los tenemos metidos en un Iterable, podemos hacer operaciones lgicas and, or y not con ellos
LinkedList<RowFilter> lista = new LinkedList<RowFilter>(); lista.add(RowFilter.dateFilter(....)); lista.add(RowFilter.regexFilter(....)); RowFilter filtroAnd = RowFilter.andFilter(lista); // and de ambos filtros RowFilter filtroOr = RowFilter.orFilter(lista); // or de ambos filtros. RowFilter filtroNo = RowFilter.notFilter(lista.getFirst());

How to call a Web Service from client-side JavaScript using ASP.Net AJAX
Published 18.08.2007. Last updated 09.09.2007

Introduction
ASP.Net AJAX framework provides us with an easy and elegant way to consume Web Services from client-side JavaScript code. In fact it is even easier to write a simple AJAX enabled Web Service and connect to it from client-side JavaScript then it is to write an article like this one. In this article I have tried to collect some of my experiences which I hope can be useful for you to get started with using ASP.Net AJAX technology in general and ASP.Net AJAX enabled Web Services in particular.

Background
For some time ago I was looking for a possibility to dynamically update some parts of my page without refreshing the rest of it. In fact I only needed to update some small text fields on my page. Apart from this text my page had a lot of graphics on it and it was a bit irritating for users to watch the whole page flashing while those text fields were updated. So I had to avoid refreshing the graphics on the page while updating my text data. ASP.Net AJAX technology has shown to be perfect choice for this purpose. It is possible to use different AJAX techniques to achieve this kind of behaviour, for example: partial page updates, page methods and Web Service calls. In this article I will try to cover the Web Service approach.

Installing ASP.Net AJAX


Whell, first of all to get started you will have to install the ASP.Net AJAX framework. You can do the first step by visiting AJAX: The Official Microsoft ASP.NET 2.0 Site. There you can find links and pretty good instructions on how to install and get started with ASP.Net AJAX. I was using ASP.Net AJAX version 1.0 while writing this article.

Creating AJAX enabled Web Service


Lets us assume that you managed to install the ASP.Net AJAX framework. So we can start with creating new AJAX ebabled Web Application:

What we need now is the AJAX enabled Web Service. Let us add new Web Service called MySampleService to the project:

In order to AJAX enable it we will have to add the following attribute to the Web Service declaration part:
[System.Web.Script.Services.ScriptService()].

When this is done our Web Service is ready to respond to client-side JavaScript calls. One more thing has to be done here: we need the Web Method that we will call from client-side JavaScript. Let us define it like this:
[WebMethod] public string GetServerResponse(string callerName) { if(callerName== string.Empty) throw new Exception("Web Service Exception: invalid argument"); return string.Format("Service responded to {0} at {1}", callerName, DateTime.Now.ToString()); }

Configuring ASP.Net Application


ASP.Net applications web.config file also has to be modified in order to enable Web Service calls from client-side JavaScript code. This modification is though made for you by Microsoft Visual Studio 2005 if you are using ASP.Net AJAX template. Here is the example of what can be inserted into httpHandles section of your web.config file:
<configuration> ... <system.web> ... <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> ... </httpHandlers> ... </system.web> ... <configuration>

Making client-side JavaScript code


Let us take a look at the default.aspx file that was automatically created in our project (if it was not then you will have to add one manually). First we have to make sure that we have one and only one instance of Script Manager object on your page:
<body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp: ScriptManager> <div> </div> </form> </body>

Then we have to add Services collection to our ScriptManager object, add ServiceReference to the Services collection and specify Path to the desired service. The result might look like this:
<body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server">> <Services> <asp:ServiceReference Path="~/WebServices/MySampleService.asmx" /> </Services> </asp:ScriptManager> <div> </div> </form> </body>

or like this if you prefer to do it directly in your code-behind file :


ScriptManager1.Services.Add(new ServiceReference("~/WebServices/MyWebService.asmx"));

Now we need some client-side functions, button to trigger Web Service request and a text box to provide the input for the Web Service:
SendRequest - this function will send asyncroneus request to the Web Service OnComplete - this function will receive result from the Web Service OnError - this function will be triggered if an error occures while executing Web Service OnTimeOut - this function will be triggered if Web Service will not respond MyTextBox - text box with the input for the Web Service RequestButton - the button that triggers SendRequest function

The result might look like this:


<head id="Head1" runat="server"> <title>Web Service call from client-side JavaScript</title> <script language="javascript" type="text/javascript"> function SendRequest() {

MySampleService.GetServerResponse(form1.MyTextBox.value, OnComplete, OnError, OnTimeOut); } function OnComplete(arg) { alert(arg); } function OnTimeOut(arg) { alert("timeOut has occured"); } function OnError(arg) { alert("error has occured: " + arg._message); } </script> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/WebServices/MySampleService.asmx" /> </Services> </asp:ScriptManager> <div> <input type="text" value="" id="MyTextBox" /> <input type="button" value="Send Request to the Web Service" id="RequestButton" onclick="return SendRequest()" /> </div> </form> </body>

This is basically it. You have a functioning client-side JavaScript code that calls server-side Web Service and treats returned response:

If we supply empty input value to the GetServerResponse method of MySampleService then as expected it will throw an exception. This exception will be caught by the OnError function in the clientside JavaScript:

Conclusion
The described client-to-server communication model where client-side JavaScript code invokes Web Service methods provides us with a lot of flexibility to extend the web site functionality. At the same time the traffic is minimal: we send only the input data required by the Web Method and we receive only the return value from the method being invoked.