从客户端脚本调用 Web 服务


上一篇: ScriptManager实现Web服务的异步调用

从客户端脚本调用 Web 服务 

本主题解释如何使用 ASP.NET 的 AJAX 功能从 ECMAScript (JavaScript) 调用 Web 服务。为了使应用程序能够使用客户端脚本调用 ASP.NET Web 服务,服务器的 Web 服务通信层自动生成 JavaScript 代理类。对于页中 ScriptManager 控件中的 ServiceReference 元素所引用的每个 Web 服务,都会生成一个代理类。

Web 服务可以采用 ASP.NET Web 服务(.asmx 服务)或 Windows Communication Foundation (WCF) 服务(.svc 服务)的形式。如果已创建 ASP.NET Web (.asmx) 服务,则可以修改这些服务以使支持 AJAX 的网页中的脚本可以调用它们。有关更多信息,请参见向客户端脚本公开 Web 服务。如果已创建 WCF 服务,则可以添加终结点以使支持 AJAX 的网页中的脚本可以访问这些服务。有关更多信息,请参见向客户端脚本公开 WCF 服务

若要调用 Web 服务的方法,请调用生成的 JavaScript 代理类的相应方法。该代理类接下来会与 Web 服务进行通信。

调用 Web 服务方法

从脚本调用 Web 服务方法是异步过程。若要获取返回值或确定请求何时返回,必须提供成功回调函数。该回调函数在请求成功完成时调用,并且它包含来自 Web 方法调用的返回值(如果有的话)。您还可以提供失败回调函数以处理错误。此外,可以传递用户上下文信息以便在回调函数中使用。

下面的示例演示如何进行以下类型的 Web 服务调用:

  • 调用没有返回值的 Web 服务。

  • 调 用能够返回值的 Web 服务。

  • 调用带参数的 Web 服务方法。

  • 使用 HTTP GET 谓词调用 Web 服务方法。

  • 调用能够返回 XmlDocument 对象的 Web 服务方法。

该示例的第一部分演示一个网 页,该网页使用客户端脚本进行服务调用。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>

<title>Calling Web Methods</title>

</head>

<body>
<form id="Form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManagerId">
<Scripts>
<asp:ScriptReference Path="CallWebServiceMethods.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>

</asp:ScriptManager>

<div>
<h2>Calling Web Methods</h2>

<table>
<tr align="left">
<td>Method that does not return a value:</td>
<td>
<!-- Getting no retun value from
the Web service. -->
<button id="Button1"
onclick="GetNoReturn()">No Return</button>
</td>
</tr>

<tr align="left">
<td>Method that returns a value:</td>
<td>
<!-- Getting a retun value from
the Web service. -->
<button id="Button2"
onclick="GetTime(); return false;">Server Time</button>
</td>
</tr>

<tr align="left">
<td>Method that takes parameters:</td>
<td>
<!-- Passing simple parameter types to
the Web service. -->
<button id="Button3"
onclick="Add(20, 30); return false;">Add</button>
</td>

</tr>

<tr align="left">
<td>Method that returns XML data:</td>
<td>
<!-- Get Xml. -->
<button id="Button4"
onclick="GetXmlDocument(); return false;">Get Xml</button>
</td>
</tr>
<tr align="left">
<td>Method that uses GET:</td>
<td>
<!-- Making a GET Web request. -->
<button id="Button5"
onclick="MakeGetRequest(); return false;">Make GET Request</button>
</td>
</tr>

</table>

</div>
</form>

<hr/>

<div>
<span id="ResultId"></span>
</div>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// This function calls the Web service method without 
// passing the callback function.
function GetNoReturn()
{
Samples.AspNet.WebService.GetServerTime();
alert("This method does not return a value.");

}


// This function calls the Web service method and
// passes the event callback function.
function GetTime()
{
Samples.AspNet.WebService.GetServerTime(
SucceededCallback);

}


// This function calls the Web service method
// passing simple type parameters and the
// callback function
function Add(a, b)
{
Samples.AspNet.WebService.Add(a, b,
SucceededCallback);
}

// This function calls the Web service method
// that returns an XmlDocument type.
function GetXmlDocument()
{
Samples.AspNet.WebService.GetXmlDocument(
SucceededCallbackWithContext, FailedCallback,
"XmlDocument")
}

// This function calls a Web service method that uses
// GET to make the Web request.
function MakeGetRequest()
{

Samples.AspNet.WebService.EchoStringAndDate(
new Date("1/1/2007"), " Happy",
SucceededCallback,
FailedCallback, "HappyNewYear");

}

// This is the callback function invoked if the Web service
// succeeded.
// It accepts the result object, the user context, and the
// calling method name as parameters.
function SucceededCallbackWithContext(result, userContext, methodName)
{
var output;

// Page element to display feedback.
var RsltElem = document.getElementById("ResultId");

var readResult;
if (userContext == "XmlDocument")
{

if (document.all)
readResult =
result.documentElement.firstChild.text;
else
// Firefox
readResult =
result.documentElement.firstChild.textContent;

RsltElem.innerHTML = "XmlDocument content: " + readResult;
}

}

// This is the callback function invoked if the Web service
// succeeded.
// It accepts the result object as a parameter.
function SucceededCallback(result, eventArgs)
{
// Page element to display feedback.
var RsltElem = document.getElementById("ResultId");
RsltElem.innerHTML = result;
}


// This is the callback function invoked if the Web service
// failed.
// It accepts the error object as a parameter.
function FailedCallback(error)
{
// Display the error.
var RsltElem =
document.getElementById("ResultId");
RsltElem.innerHTML =
"Service Error: " + error.get_message();
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();



该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.WebService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

namespace Samples.AspNet
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class WebService : System.Web.Services.WebService
{

private string _xmlString =
@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<message>
<content>
Welcome to the asynchronous communication layer world!
</content>
</message>"
;

// This method returns an XmlDocument type.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XmlDocument GetXmlDocument()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(_xmlString);
return xmlDoc;
}

// This method uses GET instead of POST.
// For this reason its input parameters
// are sent by the client in the
// URL query string.
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public string EchoStringAndDate(DateTime dt, string s)
{
return s + ":" + dt.ToString();
}

[WebMethod]
public string GetServerTime()
{

string serverTime =
String.Format("The current time is {0}.", DateTime.Now);

return serverTime;

}

[WebMethod]
public string Add(int a, int b)
{

int addition = a + b;
string result =
String.Format("The addition result is {0}.",
addition.ToString());

return result;

}

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml,
XmlSerializeString = true)]
public string GetString()
{
return "Hello World";
}

}

}


指定回调函数作为默认属性

在上述示例中,对 Web 服务方法的调用是使用代理类进行的。有关成功回调函数、失败回调函数和用户上下文的信息都通过在调用中使用附加参数进行传递。

或者,也可以指定成功回调函数、失败回调函数和用户上下文,作为类的默认属 性。然后,脚本可以调用代理类的 Web 服务方法,而无需传递这些值作为调用中的参数。这可以简化调用 Web 服务方法的语法。

下面的示例演示如何设置 Web 服务代理类的默认属性,然后调用 Web 服务方法。

MyNameSpace.MyService.set_defaultSucceededCallback(SucceededCallback);
MyNameSpace.MyService.set_defaultFailedCallback(FailedCallback);
MyNameSpace.MyService.set_defaultUserContext("my context");
MyNameSpace.MyService.myServiceMethod(param1, param2);

设置回调函数作为代理类实例的属性

您还可以创建生成的代理类的 实例。在这种情况下,可以指定成功回调函数、失败回调函数和用户上下文,作为每个实例的默认属性。与调用生成的代理类一样,您随后可以使用代理类实例来调 用 Web 服务方法,而无需传递这些值作为调用中的参数。

通常,当您希望对 Web 服务的方法进行多次调用并对每个代理类实例使用不同的默认属性值时,可以创建代理类实例。例如,可以为每个实例指定不同的回调函数。通过使用不同的回调函 数,可以根据应用程序的需要和返回的数据的性质,以不同方式处理返回的数据。

下面的示例演示如何创建代理类的实例,设置其默认属性,并调用 相关的 Web 服务方法:

var myServiceProxy = new MyNameSpace.MyService();
myServiceProxy.set_defaultSucceededCallback(SuccededCallback);
myServiceProxy.set_defaultFailedCallback(FailedCallback);
MyNameSpce.MyService.set_defaultUserContext("my context");
myServiceProxy.myServiceMethod(param1, param2);

有关更多信息,请参见生成的代理类

处理 Web 服务方法调用中的错误

为了捕捉错误,必须提供接受单个参数的失败回调函数。此参数将包含 Web 服务发送的错误对象。

下面的示例演示如何提供在 Web 服务方法调用过程中发生错误时调用的失败回调函数。该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>

<title>Handling Web Service Error</title>


</head>

<body>
<form id="Form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManagerId">

<Scripts>
<asp:ScriptReference Path="WebServiceMethodError.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>

</asp:ScriptManager>
<div>
<h2>Handling Web Service Error</h2>

<table>
<tr align="left">
<td>Method with error:</td>
<td>
<!-- Cause divide by zero failure. -->
<button id="Button1"
onclick="Div(10, 0); return false;">Div Error</button>
</td>
</tr>

</table>

</div>
</form>

<hr/>

<div>
<span id="Results"></span>
</div>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// This function can cause a divide by zero error.  
function Div(a, b)
{
Samples.AspNet.WebService.Div(a, b,
SucceededCallback, FailedCallback);
}

// This is the failed callback function.
function FailedCallback(error)
{
var stackTrace = error.get_stackTrace();
var message = error.get_message();
var statusCode = error.get_statusCode();
var exceptionType = error.get_exceptionType();
var timedout = error.get_timedOut();

// Display the error.
var RsltElem =
document.getElementById("Results");
RsltElem.innerHTML =
"Stack Trace: " + stackTrace + "<br/>" +
"Service Error: " + message + "<br/>" +
"Status Code: " + statusCode + "<br/>" +
"Exception Type: " + exceptionType + "<br/>" +
"Timedout: " + timedout;
}

// This is the succeeded callback function.
function SucceededCallback(result)
{
// Display the result.
var RsltElem = document.getElementById("Results");
RsltElem.innerHTML = result;
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();



该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.WebService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

namespace Samples.AspNet
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class WebService : System.Web.Services.WebService
{

[WebMethod]
public string Div(int a, int b)
{

int division = a / b;
string result =
String.Format("The division result is {0}.",
division.ToString());

return result;


}


}


}


从多个 Web 服务方法调用单个回调函数

可以提供从多个 Web 服务方法调用的单个成功回调函数。为了使函数能够区分调用方,可以向函数传递用户上下文,也可以测试调用方法的名称。用户上下文和调用方法名称都可以在回 调函数中使用。

下面的示例演示如何从多个 Web 服务请求调用单个回调函数。该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>
<title>Passing user context or method name</title>


</head>

<body>
<form id="Form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>

<Scripts>
<asp:ScriptReference Path="WebServiceMultipleCallers.js" />
</Scripts>

</asp:ScriptManager>
<div>
<h2>Passing User Context or Method Name</h2>

<table>
<tr align="left">
<td>Passing user context:</td>
<td>
<button id="Button1"
onclick="AddWithContext(10, 20, 'user context information'); return false;">User Context</button>
</td>
</tr>
<tr align="left">
<td>Passing method:</td>
<td>
<button id="Button7"
onclick="AddWithMethod(10, 30); return false;">Method Name</button>
</td>
</tr>
</table>

</div>
</form>

<hr/>

<div>
<span id="Results"></span>
</div>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// This function calls a Web service method 
// passing simple type parameters and the user context.
function AddWithContext(a, b, userContext)
{
Samples.AspNet.WebService.Add(a, b,
SucceededCallbackWithContext, FailedCallback, userContext, null);
}


// This function calls the Web service method
// passing the method name.
function AddWithMethod(a, b)
{
Samples.AspNet.WebService.Add(a, b,
SucceededCallbackWithContext, FailedCallback);
}

// This is the callback function called if the
// Web service succeeded. It accepts the result
// object, the user context, and the method name as
// parameters.
function SucceededCallbackWithContext(result, userContext, methodName)
{
// It holds feedback message.
var output = "";

// Page element to display the feedback message.
var RsltElem =
document.getElementById("Results");

if (userContext)
{
output += "The user context is : " + userContext + "<br/>";
RsltElem.innerHTML = output;
return;
}

if (methodName)
output += "The method name is : " + methodName + "<br/>";

RsltElem.innerHTML = output;

}

// This is the callback function called if the
// Web service failed. It accepts the error object
// as a parameter.
function FailedCallback(error)
{
// Display the error.
var RsltElem =
document.getElementById("Results");
RsltElem.innerHTML =
"Service Error: " + error.get_message();
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();


该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.WebService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

namespace Samples.AspNet
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class WebService : System.Web.Services.WebService
{

[WebMethod]
public string Add(int a, int b)
{

int addition = a + b;
string result =
String.Format("The addition result is {0}.",
addition.ToString());

return result;

}


}


}


传递和返回复杂类型

如果 Web 服务方法返回复杂类型,则成功回调函数所收到的返回值的形式是对应于服务器类型的 JavaScript 对象。

下面的示例演示返回复杂类型的 Web 服务方法。该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">

<title>Receiving Complex Type</title>

<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>


</head>

<body>

<h2>Receiving Complex Type</h2>

<form id="form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="HandleColor.asmx" />
</Services>
<Scripts>
<asp:ScriptReference Path="HandleColor.js" />
</Scripts>
</asp:ScriptManager>

<table style="font-size:12px">
<tr>
<td>Web Service Default Color:</td>
<td>
<button id="Button1"
onclick="GetDefaultColor(); return false;">Get Default Color</button>
</td>
</tr>
</table>

<hr />

<!-- Display current color object. -->
<p>
<span style="background-color:Yellow">Color:</span>
<span id="ResultId"></span>
</p>


</form>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// It gets the default color
// from the Web service.
function GetDefaultColor()
{
// Call the Web service method to get
// the default color.
Samples.AspNet.HandleColor.GetDefaultColor(
SucceededCallback);

}

// This is the callback function that
// processes the complex type returned
// by the Web service.
function SucceededCallback(result)
{

// Read the values returned by the
// Web service.
var message = result.message;
var rgb = result.rgb;
var timeStamp = result.timeStamp;

// Transform the rgb array into a string.
var serverColor = rgb[0]+ rgb[1] + rgb[2];

// Display the result.
var displayResult =
document.getElementById("ResultId");
displayResult.style.color = "yellow";
displayResult.style.fontWeight = "bold";
if (document.all)
displayResult.innerText = message + " " + timeStamp;
else
// Firefox
displayResult.textContent = message + " " + timeStamp;
displayResult.style.backgroundColor = "#" + serverColor;

}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();


该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.HandleColor" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Web.Script.Serialization;

namespace Samples.AspNet
{
// Define the color object to
// exchange with the client.
public class ColorObject
{
public string message =
"The default color is Blue.";
public string[] rgb =
new string[] { "00", "00", "FF" };
public string timeStamp;

}

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[GenerateScriptType(typeof(ColorObject))]
[ScriptService]
public class HandleColor :
System.Web.Services.WebService
{


[WebMethod]
public ColorObject GetDefaultColor()
{
// Instantiate the default color object.
ColorObject co = new ColorObject();
// Set time stamp.
co.timeStamp = DateTime.Now.ToString();

return co;
}


[WebMethod]
public ColorObject ChangeDefaultColor(ColorObject color)
{
// Instantiate the default color object.
ColorObject co = new ColorObject();
// Assign the passed values.
co.message = color.message;
co.rgb = color.rgb;
// Set time stamp.
co.timeStamp = DateTime.Now.ToString();

return co;

}


}

}


下面的示例演示如何调用具有对应于复杂类型的参数的 Web 服务方法。这些类型的代理类将自动生成。这使客户端脚本能够创建类型的实例,并将其作为参数传递给方法调用。

该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Web.Script.Serialization" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">

<title>Exchanging Complex Types</title>
<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>

</head>

<body>

<h2>Exchanging Complex Types</h2>

<form id="form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="HandleColor.asmx" />
</Services>
<Scripts>
<asp:ScriptReference Path="HandleColor.js" />
</Scripts>
</asp:ScriptManager>

</form>


<center>
<table style="font-size:12px;" >
<tr align="center">
<td class="text">Change Color:</td>
<td>
<select id="ColorSelectID"
onchange="OnChangeDefaultColor(this);" runat="server">
</select>
</td>
</tr>
</table>
</center>

<hr />

<!-- Display current color object. -->
<span style="background-color:Yellow">Color:</span>
<span id="ResultId"></span>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

 // The Web service default color.
var defaultRgb;

// The page feedback display element.
var displayResult;

// Gets the selection list colors and
// the default color from the Web service.
function GetServerColors()
{
// Gets the default color.
Samples.AspNet.HandleColor.GetDefaultColor(
SucceededCallback, FailedCallback);

// Get selection list colors.
Samples.AspNet.HandleColor.GetColorList(
SucceededCallback, FailedCallback);


}

// This function passes the color selected
// by the user (client) to the Web service.
function OnChangeDefaultColor(comboObject)
{
// Create an instance
// of the server color object.
var color =
new Samples.AspNet.ColorObject();

// Get the user's selected color.
var selectionIndex =
comboObject.selectedIndex;
var selectedColor =
comboObject.options[selectionIndex].text;

// Get the related RGB color value.
var selectionValue =
comboObject.value;
// Transform it into an array.
var colorArray = selectionValue.split(",");

// Assign the new values to
// the server color object.
color.message = "The new default color is " + selectedColor + ".";
color.rgb = colorArray;

// Call the Web service method to change the color.
Samples.AspNet.HandleColor.ChangeDefaultColor(
color, SucceededCallback, FailedCallback);
}

// This is the callback function that processes
// the complex type returned by the Web service.
function SucceededCallback(result, userContext, methodName)
{
switch(methodName)
{
case ("GetColorList"):
{
// Get the select object.
var selectObject = document.getElementById("ColorSelectID");
var i = 0;

// Iterate through the dictionary to populate
// the selection list.
for(var item in result)
{
var option = new Option(result[item], item);
selectObject.options[i]=option;

// Set the default selection.
if (item == defaultRgb)
selectObject.options[i].selected = true;
i++;
}
break;
}
default:
{
// Get the server default color and its current time.
// Read the values returned by the
// Web service.
var message = result.message;
defaultRgb = result.rgb;

var timeStamp = result.timeStamp;

// Transform the rgb array into a string.
var serverColor = defaultRgb[0]+ defaultRgb[1] + defaultRgb[2];

// Display the result.
displayResult.style.color = "yellow";
displayResult.style.fontWeight = "bold";
if (document.all)
displayResult.innerText = message + " " + timeStamp;
else
// Firefox
displayResult.textContent = message + " " + timeStamp;

displayResult.style.backgroundColor = "#" + serverColor;
break;
}
}
}

// Callback function invoked on failure
// of the Web service methods.
function FailedCallback(error, userContext, methodName)
{
if(error !== null)
{
displayResult.innerHTML = "An error occurred: " +
error.get_message();
}
}

// Gets the Web service selection list colors
// and the default color.
function pageLoad()
{
// Get page feedback display element.
displayResult =
document.getElementById("ResultId");
// Get the server's selection list colors and
// the default color.
GetServerColors();
}


if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();


该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.HandleColor" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using System.Collections.Generic;

namespace Samples.AspNet
{
// Define the color object to
// exchange with the client.
public class ColorObject
{
public string message;
public string[] rgb;
public string timeStamp;

public ColorObject()
{
this.message = "The default color is Red.";
this.rgb = new string[] { "FF", "00", "00" };
this.timeStamp = DateTime.Now.ToString();
}
}

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[GenerateScriptType(typeof(ColorObject))]
[ScriptService]
public class HandleColor :
System.Web.Services.WebService
{


[WebMethod]
public ColorObject GetDefaultColor()
{
// Instantiate the default color object.
ColorObject co = new ColorObject();
return co;
}


[WebMethod]
public ColorObject ChangeDefaultColor(ColorObject color)
{
// Instantiate the default color object.
ColorObject co = new ColorObject();
// Assign the passed values.
co.message = color.message;
co.rgb = color.rgb;
// Set time stamp.
co.timeStamp = DateTime.Now.ToString();
return co;
}

[WebMethod]

public Dictionary<String,String> GetColorList()
{
//Instatiate the dictionary object.
Dictionary<String, String> result = new Dictionary<string, string>();

//Add the color items.
result.Add("00,00,FF", "Blue");
result.Add("FF,00,00", "Red");
result.Add("00,FF,00", "Green");
result.Add("00,00,00", "Black");

return result;
}
}

}


传递泛型或数组类型的参数

Web 服务方法可能支持泛型或 T 类型列表数组类型的参数或返回值。在这种情况下,ASP.NET 自动生成 T 类型的代理类以便用于客户端脚本。

但是,如果泛型类型接受多个类型参 数(例如 Dictionary<string, <T>>),则 ASP.NET 不会自动生成这些类型的代理类。为了使 ASP.NET 能够生成 T 类型的代理类,必须使用 T 类型的 GenerateScriptTypeAttribute 属性限定使用该类型的 Web 服务类。

下面的示例演示当参数的类型为泛型或数组时,如何从客户端脚本调用 Web 服务方法。该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">

<title>Using Generics Proxy Types</title>
<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }
.text { font: 10pt Trebuchet MS; text-align: center }
</style>
</head>

<body>

<h2>Using Generics Proxy Types</h2>


<form id="form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="WebService.asmx" />
<asp:ServiceReference Path="WebService2.asmx" />
</Services>
<Scripts>
<asp:ScriptReference Path="generics.js" />
</Scripts>
</asp:ScriptManager>

</form>


<center>
<table style="font-size:12px;" >

<tr align="left">
<td class="text">Generic List:</td>
<td>
<button id="Button1"
onclick="GenericList()">Get List</button>
</td>
</tr>

<tr align="left">
<td class="text">Generic Dictionary:</td>
<td>
<button id="Button2"
onclick="GenericDictionary()">Get Dictionary</button>
</td>
</tr>

<tr align="left">
<td class="text">Generic Custom Type Dictionary:</td>
<td>
<button id="Button3"
onclick="GenericCustomTypeDictionary()">Get Dictionary</button>
</td>
</tr>


<tr align="left">
<td class="text">Generic Dictionary:</td>
<td>
<button id="Button5"
onclick="PassGenericDictionary()">Pass Dictionary</button>
</td>
</tr>

<tr align="left">
<td class="text">Array:</td>
<td>
<button id="Button4"
onclick="ArrayType()">Get Array</button>
</td>
</tr>

</table>
</center>

<hr />

<!-- Display current color object. -->
<span id="ResultId"></span>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// The page feedback display element.
var displayResult;

// This function intializes the global variables and
// assigns default values to the generated proxy.
function pageLoad()
{
// Get page feedback display element.
displayResult =
document.getElementById("ResultId");

// Assign default values to the generated proxy.
Samples.AspNet.TestService.set_defaultUserContext("Default context");
Samples.AspNet.TestService.set_defaultSucceededCallback(SucceededCallback);
Samples.AspNet.TestService.set_defaultFailedCallback(FailedCallback);
}

// Get a generic List.
function GenericList()
{
Samples.AspNet.TestService.GetGenericList();
}

// Get a generic Dictionary.
function GenericDictionary()
{
Samples.AspNet.TestService.GetGenericDictionary();
}

// Get a generic Dictionary of custom types.
function GenericCustomTypeDictionary()
{
Samples.AspNet.TestService.GetGenericCustomTypeDictionary();
}


// Pass a generic dictionary of custom types
// to Webservice.
function PassGenericDictionary()
{

var simple = new Samples.AspNet.SimpleClass2();
simple.s = "WebService proxy.";

Samples.AspNet.TestService.PassGenericDictionary(
{"first":simple});
}

// Get an Array.
function ArrayType()
{
Samples.AspNet.TestService.GetArray();
}


// Callback function invoked when the call to
// the Web service methods succeeds.
function SucceededCallback(result, userContext, methodName)
{
var message;
switch(methodName)
{
case ("GetGenericList"):
{
var i = 0;
var message = new Array();
for(var item in result)
{
message[i] = "List element " + i + ": " + result[item].s;
i++;
}
DisplayMessage(message.toString());
break;
}


case ("GetGenericDictionary"):
{
var i = 0;
var message = new Array();
for(var item in result)
{
message[i] = item + ": " + result[item];
i++;
}
DisplayMessage(message.toString());
break;
}

case ("GetGenericCustomTypeDictionary"):
{
var i = 0;
var message = new Array();
for(var item in result)
{
message[i] = item + ": " + result[item].s;
i++;
}
DisplayMessage(message.toString());
break;
}

case ("PassGenericDictionary"):
{

DisplayMessage(result);

break;
}

case ("GetArray"):
{
var i = 0;
var message = new Array();
for(var item in result)
{
message[i] = result[item];
i++;
}
DisplayMessage(message.toString());
break;
}

default:
{
DisplayMessage("Method unknown");
}
}
}

// Callback function invoked when the call to
// the Web service methods fails.
function FailedCallback(error, userContext, methodName)
{
if(error !== null)
{
displayResult.innerHTML = "An error occurred: " +
error.get_message();
}
}

function DisplayMessage(message)
{
if (document.all)
displayResult.innerText = message;
else
// Firefox
displayResult.textContent = message;
}



if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();



该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.TestService" %>

namespace Samples.AspNet
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.Services;
using System.Web.Script.Services;

// Custom type used by WebService.
public class SimpleClass
{
private string _s = "SimpleClass1";

public String s {
get { return _s; }
set { _s = value; }
}
}

// Custom type used by WebService.
public class SimpleClass2
{
private string _s = "SimpleClass2";

public String s
{
get { return _s; }
set { _s = value; }
}
}

// The following service allows the generation
// of the SimpleClass2 type proxy by applying the
// attribute: GenerateScriptType. This assures
// that the a SimpleClass2 object can be
// passed by the client script to the
// PassGenericDictionary method.
// Note if you comment out the GenerateScriptType
// you get an error because the SimpleClass2 type proxy
// is not generated.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[GenerateScriptType(typeof(SimpleClass2))]
[ScriptService]
public class TestService : System.Web.Services.WebService
{
// The following method return a list of SimpleClass
// objects.
// Note the SimpleClass type proxy is automatically
// generated because used in the return parameter.
[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public List<SimpleClass> GetGenericList()
{
List<SimpleClass> GetGenericList = new List<SimpleClass>();
SimpleClass simple1 = new SimpleClass();
SimpleClass simple2 = new SimpleClass();
simple1.s = "Generics first instance";
simple2.s = "Generics second instance";
GetGenericList.Add(simple1);
GetGenericList.Add(simple2);
return GetGenericList;
}

// The following method return a Dictionary of strings.
[WebMethod]
public Dictionary<String, String> GetGenericDictionary()
{
//Instantiate the dictionary object.
Dictionary<String, String> result =
new Dictionary<string, string>();

//Add items.
result.Add("0000FF", "Blue");
result.Add("FF0000", "Red");
result.Add("00FF00", "Green");
result.Add("000000", "Black");

return result;
}

// The following method return a Dictionary of
// SimpleClass objects.
// Note the SimpleClass type proxy object is automatically
// generated because used in the return parameter.
[WebMethod]
public Dictionary<String, SimpleClass> GetGenericCustomTypeDictionary()
{
//Instantiate the dictionary object.
Dictionary<String, SimpleClass> result =
new Dictionary<string, SimpleClass>();

SimpleClass simple = new SimpleClass();
simple.s = "custom type instance";

//Add items.
result.Add("Custom type", simple);

return result;
}

// The following method accept a Dictionary of
// SimpleClass2 objects.
// Note the SimpleClass2 type proxy object is
// not automatically generated because used in
// an input parameter. You must enable its
// generation by applying the GenerateScriptType
// attribute to the service.
[WebMethod]
public String PassGenericDictionary(
Dictionary<string, SimpleClass2> d)
{

string value = d["first"].s;

string message = "Dictionary element value: " + value;

return message;
}


// This function returns an array.
[WebMethod]
public ArrayList GetArray()
{
//Instantiate the array object.
ArrayList result = new ArrayList();

//Add items.
result.Add("First element: " + "Test1");
result.Add("Second element: " + "Test2");

return result;
}

}

}


传递枚举数类型的参数

使用自动生成的代理类可以访 问枚举数类型。

说 明:

不要为了访问枚举数而实例化生成的代理类。

下 面的示例演示当参数的类型为枚举数时,如何从客户端脚本调用 Web 服务方法。该示例的第一部分演示一个网页,该网页使用客户端脚本调用 Web 服务。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">

<title>Using Generated Proxy Types</title>
<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }
.text { font: 10pt Trebuchet MS; text-align: center }
</style>
</head>

<body>

<h2>Using Generated Proxy Types</h2>

<form id="form1" runat="server">

<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference Path="ServerTypes.asmx" />
</Services>
<Scripts>
<asp:ScriptReference Path="ServerTypes.js" />
</Scripts>
</asp:ScriptManager>

</form>


<center>
<table style="font-size:12px;" >

<tr align="left">
<td class="text">Get Enum:</td>
<td>
<button id="Button2"
onclick="GetSelectedEnumValue()">Get Enum Value</button>
</td>
</tr>

<tr align="left">
<td class="text">Pass Enum:</td>
<td>
<button id="Button1"
onclick="GetFirstEnumElement()">First Enum</button>
</td>
</tr>

</table>
</center>

<hr />

<!-- Display current color object. -->
<span id="ResultId"></span>

</body>

</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

// ServerTypes.js

// The Web service default color.
var defaultRgb;

// The page feedback display element.
var displayResult;

// Gets the Web service selection list colors
// and the default color.
function pageLoad()
{
// Get page feedback display element.
displayResult =
document.getElementById("ResultId");

// Assign default values for the generated proxy using
// the (generated) static proxy.
Samples.AspNet.ServerTypes.set_timeout(200);
Samples.AspNet.ServerTypes.set_defaultUserContext("Default context");
Samples.AspNet.ServerTypes.set_defaultSucceededCallback(SucceededCallback);
Samples.AspNet.ServerTypes.set_defaultFailedCallback(FailedCallback);

}

// This function shows how to get an
// enumeration object from the server.
function GetFirstEnumElement()
{
// Get the first element of the enumeration
Samples.AspNet.ServerTypes.GetFirstColor();
}

// This function shows how to pass an
// enumeration value to the server.
function GetSelectedEnumValue()
{
// Get the value of the selected enumerated
// element.
Samples.AspNet.ServerTypes.GetSelectedColor(
Samples.AspNet.ColorEnum.Blue);
}

// Callback function invoked when the call to
// the Web service methods succeeds.
function SucceededCallback(result, userContext, methodName)
{
var message;
switch(methodName)
{
case ("GetFirstColor"):
{
var firstColor = result;
message = "First enumerated value: " + firstColor;
DisplayMessage(message);
break;
}

default:
{
DisplayMessage("Method unknown");
}
}
}

// Callback function invoked when the call to
// the Web service methods fails.
function FailedCallback(error, userContext, methodName)
{
if(error !== null)
{
displayResult.innerHTML = "An error occurred: " +
error.get_message();
}
}

function DisplayMessage(message)
{
if (document.all)
displayResult.innerText = message;
else
// Firefox
displayResult.textContent = message;
}



if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();



该示例接下来的部分演示网页所调用的 Web 服务。

<%@ WebService Language="C#" Class="Samples.AspNet.ServerTypes" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using System.Collections.Generic;

namespace Samples.AspNet
{


// Define the enum type to
// exchange with the client.
public enum ColorEnum
{
Red = 0,
Green = 1,
Blue = 2
}

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class ServerTypes :
System.Web.Services.WebService
{

// The enum type can be accessed by the client
// script through the generated Web service
// proxy class in a static fashion.
[WebMethod]
public ColorEnum GetFirstColor()
{
// Return the first color
// in the enumeration.
return ColorEnum.Red;
}

[WebMethod]
public string GetSelectedColor(ColorEnum color)
{
// Return the selected color value
// in the enumeration.
return color.ToString();
}

}

}


调用 WCF 服务操作

Windows Communication Foundation (WCF) 是 Microsoft 为生成面向服务的应用程序而提供的统一编程模型。它支持 ASP.NET AJAX 和 JavaScript Object Notation (JSON) 数据格式。这使 WCF 服务能够向运行 JavaScript 代码并因此可以使用 HTTP 请求访问这些服务的网页公开操作。

如果已创建 WCF 服务,则可以添加终结点以使支持 AJAX 的网页中的脚本可以访问该服务。

从脚本调用 Windows Communication Foundation (WCF) 服务操作(这是 WCF 用于表示方法的术语)是异步过程。与其他异步过程一样,您可以提供在请求完成时调用的成功回调函数。您还可以提供失败回调函数以处理错误。有关 Windows Communication Foundation (WCF) 服务以及在 ASP.NET 中承载它们的更多信息,请参见 ASP.NET AJAX Integration and JSON Support (ASP.NET AJAX 集成和 JSON 支持)。

下面的示例演示如何生成 WCF 服务,并通过在网页脚本中使用客户端脚本来调用其方法。该示例的第一部分演示如何通过客户端脚本进行服务调用。

<%@ Page Language="C#" AutoEventWireup="true"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<style type="text/css">
body { font: 11pt Trebuchet MS;
font-color: #000000;
padding-top: 72px;
text-align: center }

.text { font: 8pt Trebuchet MS }
</style>
<title>Simple WCF Service Page</title>

</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference
Path="SimpleService.svc/ws"/>
</Services>
<Scripts>
<asp:ScriptReference Path="service.js" />
</Scripts>
</asp:ScriptManager>

<div>
<h2>Simple WCF Service</h2>
<input type='button' name="clickme" value="Greetings"
onclick="javascript:OnClick()" /> &nbsp; &nbsp;
<input type='button' name="clickme2" value="Greetings2"
onclick="javascript:OnClick2()" />
<hr/>
<div>
<span id="Results"></span>
</div>
</div>

</form>
</body>
</html>


该示例的下一部分演示网页用于调用 Web 服务的客户端脚本。

var ServiceProxy;

function pageLoad()
{
ServiceProxy = new ISimpleService();
ServiceProxy.set_defaultSucceededCallback(SucceededCallback);
}

function OnClick()
{
// var myService = new ISimpleService();
ServiceProxy.HelloWorld1("George");
}

function OnClick2()
{
var dc = new DataContractType();
dc.FirstName = "George";
dc.LastName = "Washington";
ServiceProxy.HelloWorld2(dc);
}

// This is the callback function that
// processes the Web Service return value.
function SucceededCallback(result, userContext, methodName)
{
var RsltElem = document.getElementById("Results");
RsltElem.innerHTML = result + " from " + methodName + ".";
}
if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();


该示例接下来的部分演示网页所调用的 Web 服务。

using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Activation;

// This a WCF service which consists of a contract,
// defined below as ISimpleService, and DataContractType,
// a class which implements that interface, see SimpleService,
// and configuration entries that specify behaviors associated with
// that implementation (see <system.serviceModel> in web.config)

namespace Aspnet.Samples
{
[ServiceContract()]
public interface ISimpleService
{
[OperationContract]
string HelloWorld1(string value1);
[OperationContract]
string HelloWorld2(DataContractType dataContractValue1);
}

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SimpleService : ISimpleService
{
public SimpleService()
{ }

public string HelloWorld1(string value1)
{
return "Hello " + value1;
}
public string HelloWorld2(DataContractType dataContractValue1)
{
return "Hello " + dataContractValue1.FirstName +
" " + dataContractValue1.LastName;
}
}

[DataContract]
public class DataContractType
{
string firstName;
string lastName;

[DataMember]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
[DataMember]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}

}


 
原文地址:https://www.cnblogs.com/freeton/p/1719774.html