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

使用 jQuery 消费 ASP.NET MVC JSON 服务

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (5投票s)

2011 年 7 月 21 日

CPOL

6分钟阅读

viewsIcon

41510

如何使用 jQuery 消费 ASP.NET MVC JSON 服务

引言

自 ASP.NET 问世以来,Web 服务一直是任何专业 Web 开发人员工具集中的重要组成部分。从 .NET 3.5 开始,Web 服务变得更加有用,因为可以使用 JavaScript 和 ASP.NET AJAX 从浏览器异步调用 Web 服务。

然而,在过去的两年里,替代性的 ASP.NET MVC 框架因其对 MVC 设计模式的良好实现以及对 Web 标准和前沿 Web 技术的遵循,吸引了开发社区越来越多的关注。

对于许多习惯了 Web 服务(特别是结合 ASP.NET AJAX 框架)的经验丰富的 ASP.NET 开发人员来说,一个自然的问题出现了:如何使用 ASP.NET MVC 框架及其天然的 JavaScript 伴侣 jQuery 来实现类似的方法?

ASP.NET MVC JSON 服务

首先,ASP.NET MVC 中没有 Web 服务的概念,但实现其功能等效物非常容易。任何返回数据而不是 HTML 格式页面的 Controller Action 方法都可以被视为 Web 方法的等效物并相应地使用。从这个角度来看,一组返回格式正确的 JSON 响应的 Controller Action 方法,我称之为MVC JSON 服务。下面是一个简单的例子

public class JsonServicesController : Controller
{
  ...
  public JsonResult MyJsonMethod()
  {
      // ... acquire an instance of an object
      return Json(data);
  }
  ...
}
</script>

上述代码在正确实现后,应该返回 `data` 对象的 JSON 表示,这说明了实现 MVC JSON 服务方法是多么容易。

安全

默认情况下,JSON 服务方法在被 HTTP GET 请求调用时会抛出异常。这种行为与普通 ASP.NET Web 服务方法的行为一致,后者也不接受 GET 请求。这也应被视为一项最佳实践,即仅通过 HTTP POST 请求调用 JSON 服务方法。为了实现这一点,应该将 [HttpPost] 属性应用于 JSON 服务方法。如果您想了解更多关于安全注意事项的信息,请阅读这篇帖子

另一个考虑因素是身份验证/授权。与任何其他 Controller Action 方法类似,应用于 JSON 服务方法的 [Authorize] 属性控制该方法只能由经过身份验证且具有适当授权(如果需要)的用户调用。

现在,经过修正的 JSON 服务方法看起来像这样

public class JsonServicesController : Controller
{
  ...
  // uncomment below if authentication required
  //[Authorize]
  [HttpPost]
  public JsonResult MyJsonMethod()
  {
      // ... acquire an instance of an object
      return Json(data);
  }
  ...
}

如何使用 jQuery 调用 MVC JSON 服务方法

JSON 服务最流行的用途之一是从 JavaScript 异步调用它们,然后使用返回的数据更新 HTML 内容。使用普通的 ASP.NET 和 ASP.NET AJAX,可以轻松完成此类任务,因为所有必需的 JavaScript 代码都会自动生成并在页面上引用。然而,这种便利是以更大的负载和更长的加载时间为代价的,因为许多额外的脚本需要在页面上引用。

在 ASP.NET MVC 中,天然的 JavaScript 环境是 jQuery 库,它包含了完成任务所需的一切。请看下面的代码示例

  function getMyObject(onSuccess) {
    $.ajax({
       type: "POST",
       contentType: "application/json;charset=utf-8",
       url: "/JsonService/MyJsonMethod",
       data: "{}",
       dataType: "json",
       success: onSuccess
    });
  }

我们使用 jQuery.ajax 方法向我们的 JSON 服务方法发出异步 POST 请求。注意 contentTypedataType 属性,它们负责识别我们正在请求和期望返回 JSON 格式的数据。url 属性定义了我们 JSON 服务方法的 URL,该 URL 基于标准的 ASP.NET MVC 路由规则构建。success 参数的值是一个回调函数名,当请求成功完成时将被调用。

输入参数

服务方法很少在没有参数的情况下被调用。对于一个或两个简单参数,我们可以依赖 ASP.NET MVC 路由自动参数映射功能,该功能将自动从 URL 中提取参数,然后将其传递给服务方法。看这个例子。

假设我们想调用一个带有单个参数 "id" 的 JSON 服务方法,该参数用于在服务器端获取我们的数据对象。首先,我们在 global.asax.cs 文件中定义相应的路由规则

  public static void RegisterRoutes(RouteCollection routes)
  {
     ...
     routes.MapRoute(
          "JsonService",
          "{controller}/{action}/{id}",
          new { controller = "JsonServices", action = "GetData", 
              id = UrlParameter.Optional } 
     );
     ...
  }

接下来,我们将有一个带有参数的 JSON 服务方法

public class JsonServicesController : Controller
{
  ...
  // uncomment below if authentication required
  //[Authorize]
  [HttpPost]
  public JsonResult MyJsonMethod(string id)
  {
      // ... acquire an instance of an object
      return Json(data);
  }
  ...
}

当我们使用类似 "JsonServices/MyJsonMethod/123456" 的 URL 调用我们的 JSON 服务方法时,该方法将自动接收一个 string 值 "123456" 作为 id 参数。

这很简单。那么,如果我们想传递一个复杂对象作为参数,而又不能使用 URL 呢?在这种情况下,我们只需使用 jQuery.ajax 方法中的 data 属性,将 JSON 字面量作为 string 传递,代表我们的复杂参数

  function getMyObject(onSuccess) {
    $.ajax({
       type: "POST",
       contentType: "application/json;charset=utf-8",
       url: "/JsonService/MyJsonMethod",
       data: '{"id":"123456", "title":"object title"}',
       dataType: "json",
       success: onSuccess
    });
  }

现在我们需要修改我们的 JSON 服务方法以正确接收参数。

public class JsonServicesController : Controller
{
  ...
  // uncomment below if authentication required
  //[Authorize]
  [HttpPost]
  public JsonResult MyJsonMethod(MyObject param)
  {
      // ... acquire an instance of an object
      return Json(data);
  }
  ...
}

我们需要定义一个 MyObject 类,如下所示

  [Serializable]
  public class MyObject {
      public string Id { get; set; }
      public string Title { get; set; }
  }

请注意,该类被标记为 [Serializable] 属性,并且 public 属性的名称与我们在 jQuery.ajax 函数调用中的 JSON 参数 string 中使用的名称完全匹配。这足以让 ASP.NET MVC 框架在后台完成所有工作,并为我们的 JSON 服务方法提供正确的参数值。很容易看到这种异步 AJAX 调用与普通的表单 POST 请求之间的相似性,唯一的区别是客户端的参数是以 JSON 字面量字符串的形式提供的。

消费返回的数据

我们的最终目标是接收一个 JSON 格式的数据,然后可以使用 JavaScript 来消费它,我们希望通过充分利用 ASP.NET MVC 框架和 jQuery 库的能力来最大限度地减少工作量。到目前为止,我们已经成功地向服务器端的 JSON 服务方法发出了请求,下一步就是消费返回的数据。我们已经将 onSuccess JavaScript 函数作为 jQuery.ajax 方法的回调函数提供,我们应该在所有想要的数据处理中使用它。

  function onSuccess(data) {
    //example of a simple data processing
    var message = data.ResultMessage;
    $("#resultMessage").html(message);
  }

当 AJAX 请求完成时,将调用 onSuccess 函数,并接收一个参数 data,这是我们期望的结果。data 已经是一个常规的 JavaScript 对象,它已经被从 JSON 字符串反序列化,我们可以按预期使用它。它完全对应于我们从 JSON 服务方法返回的服务器端 data 对象。请注意,与 ASP.NET AJAX 的常规 Web 服务调用不同,返回的对象没有被包装在 "d" 属性中,因此无需额外处理。

关于 DateTime 的说明

如果返回的对象包含一个 DateTime 类型的属性,MVC 框架会以特定的形式返回它,这在客户端使用之前需要一些初步处理。下面的一个简单函数可以将 MVC 框架返回的值转换为标准的 JavaScript Date 对象

  function toDate(dateValue) {
      return eval('new' + dateValue.replace(/\//g, ' '));
  }

阅读这篇帖子并在互联网上搜索,以更好地理解 DateTime 值格式在 JSON 格式消息中返回时的转换机制。

结论

在本文中,我们学习了如何使用 ASP.NET MVC 框架实现 JSON 服务,以及如何使用 jQuery 库从 JavaScript 异步调用 JSON 服务方法。

© . All rights reserved.