65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 jQuery AJAX 在 ASP.NET 中调用客户端服务器方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (28投票s)

2011年8月11日

CPOL

6分钟阅读

viewsIcon

193926

downloadIcon

5282

本文介绍如何在 ASP.NET 应用程序中使用 jQuery 调用服务器方法,包括无参数、简单参数和复杂参数(JSON 对象)的情况。

引言

在本文中,我将演示三种使用 jQuery AJAX 从客户端调用 C# (ASP.NET) 编写的服务器端方法的不同方法。

背景

众所周知,我们在网站中使用 AJAX 来提高性能。jQuery 是目前最新且使用最广泛的 JavaScript 库。我见过许多使用 jQuery 的网站,并对其提供的功能印象深刻,因此我想自己也开始使用 jQuery。

我将从客户端调用服务器方法的概念分为三类:

  1. 调用无参数的服务器方法并获取响应。
  2. 调用带有简单参数(整数或字符串值)的服务器方法并获取响应。
  3. 调用带有复杂参数(JSON 对象)的服务器方法并获取响应。

这些类别之间只有非常微小的差异,但我发现人们通常会在这里卡住,并花费大量时间来弄清楚这些差异。虽然我随文章附带了一个运行正常的示例,但我建议按照下面的步骤来创建示例,以便一切都清楚明了。

创建示例应用程序的步骤

创建 ASP.NET 网站

A1.JPG

在应用程序中创建一个名为“Scripts”的文件夹,并添加对“System.Web.Extensions.dll”的引用(此 DLL 存在于随附的示例代码中)。

现在,将以下 jQuery 文件添加到“Scripts”文件夹中:

  1. jquery-1.6.2.jsjquery-1.6.2.min.js
  2. jquery.json-2.2.jsjquery.json-2.2.min.js

建议使用 min 版本。您可以从示例中获取这些文件,或从 www.jquery.com 下载。

现在,在 Scripts 文件夹中添加一个新的 JavaScript 文件,我们将在此文件中编写脚本,并给它任意名称;我将其命名为“MyJQuery.js”。

到目前为止,我们只完成了初始设置。现在让我们开始编码。

MethodInvokeWithJQuery.aspx

head 部分添加对 .js 文件的引用,并添加要使用的样式。

<script type="text/javascript" 
   language="javascript" 
   src="Scripts/jquery-1.6.2.min.js"></script>
<script type="text/javascript" 
  language="javascript" 
  src="Scripts/jquery.json-2.2.min.js"></script>
<script type="text/javascript" 
  language="javascript" 
  src="Scripts/MyJQuery.js"></script>

<style type="text/css">
     body
     {
         font-family:Arial;
         font-size:.93em;
     }
        
     #tblAjaxDemo p
     {
         border:1px solid #EEE;
         background-color:#F0F0F0;
         padding:3px;
     }
       
     #tblAjaxDemo p span
     {
         color:#00F;
         display:block;
         font:bold 21px Arial;
         float:left;
         margin-right:10px;
     }
</style>

现在添加控件。我在页面上添加了三个按钮和三个 div 元素,如下所示:

<div>
<h1>
Demo page: Server Side Method Call Demo using JQuery and ASP.Net
</h1>
<p>
This page is a demo for calling server side methods using ajax capabilities of jquery.
</p>
<p style="margin: 20px 0; background-color: #EFEFEF; 
          border:1px solid #EEE; padding: 3px;">
Author: Praveen Meghwal
</p>
<table id="tblAjaxDemo" width="100%" 
  cellpadding="1" cellspacing="0" border="0">
<tr style="height: 10px;">
<td colspan="2" align="right"> 
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>1</span>This is button will call server side 
    method from JQuery and get response from server.
</p>
</td>
</tr>
<tr valign="top">
<td style="width: 30%;">
<asp:Button ID="btnTest" runat="server" Text="Click Me" />
</td>
<td style="width: 70%;">
<div id="myDiv" style="font-family:Arial; color: Red;">
</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr style="size: 2; color: Navy;" />
</td>
</tr>
<tr style="height: 20px;">
<td colspan="2"> 
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>2</span>This is button will call server side method from JQuery 
  along with parameter and get response from server. In this approach 
  only numeric value parameters are accepted. 
  Here I am passing numeric value 2 as parameter.
</p>
</td>
</tr>
<tr valign="top">
<td>
<asp:Button ID="btnTest2" runat="server" Text="Click Me" />
</td>
<td>
<div id="myDiv2" style="font-family:Arial; color: Red;">
</div>
</td>
</tr> 
<tr>
<td colspan="2">
<hr style="size: 2; color: Navy;" />
</td>
</tr>
<tr style="height: 20px;">
<td colspan="2"> 
</td>
</tr>
<tr>
<td colspan="2">
<p>
<span>3</span>This is button will call server side method from JQuery sendig complex
datatype (JSON object) to server and get response from server.
</p>
</td>
</tr>
<tr valign="top">
<td>
<asp:Button ID="btnTest3" runat="server" Text="Click Me" />
</td>
<td>
<div id="myDiv3" style="font-family:Arial; color: Red;">
</div>
</td>
</tr>
</table>
</div >

ASPX 部分已完成,现在让我们转到 .cs 文件(即 C# 代码)。

MethodInvokeWithJQuery.aspx.cs

MethodInvokeWithJQuery.aspx.cs 中,我添加了三个 WebMethod,我们将使用 jQuery 从客户端调用它们。我还添加了一个名为 Employee 的类,该类可以被视为我们在此演示中使用的 JavaScript 对象的服务器端副本。还有一个方法用于将客户端复杂对象转换为服务器端等效对象。

Employee 类:创建此类是为了模拟从客户端传递的 JavaScript 对象。

public class Employee{
    private string _firstName;
    private string _lastName;
    private string _technology;
    private int _age;
    public string FirstName
    {
        get
        { return _firstName; }
        set
        { _firstName = value; }
    }
    public string LastName
    {
        get
        { return _lastName; }
        set
        { _lastName = value; }
    }
    public string Technology
    {
        get
        { return _technology; }
        set
        { _technology = value; }
    }
    public int Age
    {
        get
        { return _age; }
        set
        { _age = value; }
    }
}

WebMethods:这些方法将使用 jQuery 从客户端调用。为了向方法添加 WebMethod 属性,请在命名空间部分添加“using System.Web.Script.Services;”。

[WebMethod]
public static string MethodWithNoParameter()
{
    return "Message from server.";
}
[WebMethod]
public static string MethodWithNumericParameter(string strParam)
{
    return "Parameter sent to server from client side is "
           + strParam;
}
[WebMethod]
public static string MethodWithComplexParameter(object jsonParam)
{
    Employee objEmployee = GetEmployee(jsonParam);
    return "Parameter sent to server from client side as " + 
           "follows:<br/>First Name => " + 
           objEmployee.FirstName + "<br/>Last Name => " + 
           objEmployee.LastName + "<br/>Technology=> " + 
           objEmployee.Technology + "<br/>Age => " + objEmployee.Age;
}

GetEmployee 方法:此方法会将 JavaScript 对象解析为服务器端等效对象。

public static Employee GetEmployee(object employee)
{
    Employee objEmployee = new Employee();
    Dictionary<string, object> tmp = (Dictionary<string, object>)order;
    object objFirstName = null;
    object objLastName = null;
    object objTechnology = null;
    object objAge = null;
    tmp.TryGetValue("FirstName", out objFirstName);
    tmp.TryGetValue("LastName", out objLastName);
    tmp.TryGetValue("Technology", out objTechnology);
    tmp.TryGetValue("Age", out objAge);
    objEmployee.FirstName = objFirstName.ToString();
    objEmployee.LastName =
    objLastName.ToString();
    objEmployee.Technology =
    objTechnology.ToString();
    objEmployee.Age = objAge.ToString();
    return objEmployee;
}

在此文件中,我们将添加运行应用程序所需的 JavaScript 代码,例如:将事件绑定到 ASPX 页面上的按钮,并设置调用服务器端方法所需的 AJAX 属性。

以下是 JavaScript 代码:

var Employee = function(fName, lName, technology, age) 
{
    this.FirstName = fName;
    this.LastName = lName;
    this.Technology = technology;
    this.Age = age;
}
$(document).ready (
function () 
{
try
{
$('#btnTest').click
(
function () 
{
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNoParameter",
data: "{}",
contentType: "application/json;
charset=utf-8",
dataType:"json",
async: true,
cache: false,
success: function (msg) 
{
$('#myDiv').text(msg.d); 
},
error: function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
$('#btnTest2').click
(
function () 
{
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNumericParameter",
data: "{'strParam' : 2}",
contentType: "application/json;
charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function
(msg) 
{
$('#myDiv2').text(msg.d); 
},
error:
function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
$('#btnTest3').click
(
function () 
{
var jsEmp = new Employee("Praveen", "Meghwal", "Microsoft Dotnet", 31);
var jsonText = $.toJSON(jsEmp);
$.ajax (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithComplexParameter",
data: "{'jsonParam' : " + jsonText + "}",
contentType: "application/json;
charset=utf-8",
dataType: "json",
async:
true,
cache: false,
success: function (msg) 
{
$('#myDiv3').html(msg.d); 
},
error: function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
}
);
return false;
}
);
}
catch(err)
{
alert(err);
}
}
);

现在让我们逐行查看代码。

在顶部,我们定义了 JavaScript 对象 Employee,它具有与服务器端相同的四个属性。

var Employee =function(fName, lName, technology, age) 
{
    this.FirstName = fName;
    this.LastName = lName;
    this.Technology = technology;
    this.Age = age;
}

然后,我们使用 document.ready() 函数,以便在页面的 DOM 可用进行操作后对控件执行操作。

$(document).ready();

document.ready() 函数中,我为所有三个按钮绑定了点击事件。在绑定时,我使用了 jQuery 的 ajax() 方法。在此方法中,我指定了不同的参数值,包括要调用哪个服务器端方法。

$.ajax  (
{
type: "POST",
url: "MethodInvokeWithJQuery.aspx/MethodWithNoParameter",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function
(msg) 
{
$('#myDiv').text(msg.d);
},
error: function (x, e)
{
alert("The call to the server side failed. "+ x.responseText);
}
}
);

以上是第一个按钮的 ajax 方法声明。在这里,在 url 属性中,我们指定要调用的服务器端方法名,后跟页面名。在 data 属性中,我们设置要传递给方法的参数值。对于第一个按钮,我们不传递任何参数,所以我们只在这里添加了“{}”。但是对于第二个和第三个按钮,您会看到我分别使用了 [data: "{'strParam' : 2}"][data: "{'jsonParam' : " + jsonText + "}"]

现在让我们看看第二种和第三种方法有什么区别。

如果您将内置数据类型值作为参数传递,第二种方法将正常工作。例如:[data: "{'strParam' : 2}"][data: "{'strParam' : ‘string value’}"]

那么,如果我们想传递用户定义的 JavaScript 对象作为参数怎么办?在这种情况下,我们将不得不使用第三种方法,即 [data: "{'jsonParam' : " + jsonText + "}"]。这里,变量 jsonText 是我们创建的 JavaScript 对象的字符串表示。查看第三个按钮的绑定代码,我写了以下几行:

var jsEmp = new Employee("Praveen", "Meghwal", "Microsoft Dotnet", 31);
var jsonText = $.toJSON(jsEmp);

这里我们使用了 jQuery 的 $.toJSON () 方法,将其转换为等效的字符串表示。为了使用此方法,我添加了对 jQuery 文件“jquery.json-2.2.min.js”的引用。我们也可以使用 JSON.stringify() 方法,但只有在浏览器内置 JSON 支持的情况下,JSON 才可用。

success 属性中,我们指定在成功完成对服务器的异步调用后要调用的客户端脚本。在 error 属性中,我们指定在发生任何错误时要调用的客户端脚本。

编码部分已完成。现在运行应用程序,检查代码是否正常运行。如果您收到显示错误的警报,请转到 web.config 文件,并在 configuration 下的 System.Web 标签。它应该如下所示:

<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
   \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <!--
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, 
                       Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>
    </compilation>
    <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
    <authentication mode="Windows"/>
    <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.
 
        <customErrors mode="RemoteOnly"
               defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" 
                  redirect="NoAccess.htm" />
            <error statusCode="404" 
                 redirect="FileNotFound.htm" />
        </customErrors>
        -->
    <!-- Start Settings for AJAX-->
    <httpHandlers>
      <remove verb="*" path="*.asmx"/>
      <add verb="*" path="*.asmx" validate="false" 
        type="System.Web.Script.Services.ScriptHandlerFactory, 
               System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
               PublicKeyToken=31BF3856AD364E35"/>
      <add verb="*" path="*_AppService.axd" validate="false" 
        type="System.Web.Script.Services.ScriptHandlerFactory,
              System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
              PublicKeyToken=31BF3856AD364E35"/>
      <add verb="GET,HEAD" path="ScriptResource.axd" 
        type="System.Web.Handlers.ScriptResourceHandler,
              System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
              PublicKeyToken=31BF3856AD364E35" validate="false"/>
    </httpHandlers>
    <httpModules>
      <add name="ScriptModule" 
         type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
               Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>
    <!-- End Settings for AJAX-->
  </system.web>
</configuration>

如果您的 web.config 文件与显示的不同,请在 httpHandlershttpModule 标签中按照 web.config 中的说明添加内部标签。

输出

A2.JPG

关注点

我在实现带有复杂参数的服务器方法调用上浪费了很多时间。我在网上搜索帮助,但到处都找到的是将 $.toJSON(jsEmp) 返回的 JSON 文本作为参数传递给服务器端的解决方案。我尝试过但对我不起作用。然后我想到使用第二种方法中用于将内置类型参数发送到服务器端的技术。我以为 $.toJSON(jsEmp) 函数可以将 JSON 转换为字符串表示,因此第二种方法应该有效,然后我尝试了 [data: "{'jsonParam' : " + jsonText + "}" ] 并成功了。

历史

First version.

© . All rights reserved.