使用 AngularJS 的 $resource 连接 WebAPI Controller
ASP.NET Web API 是 .NET 平台创建 REST 风格的 HTTP 服务的理想框架, REST 风格的 HTTP 服务可以被多种客户端使用, 包括浏览器和移动设备, 使用 REST 风格的 HTTP 服务也越来越多。
由于 REST 服务的逐渐流行, 越来越多的客户端类库都提供了 REST 服务的专用类库, AngularJS 也不例外, 提供了 $resource
来实现 REST 服务的支持。
在 AngularJS 的文档中, 对 $resource
的描述如下:
A factory which creates a resource object that lets you interact with RESTful server-side data sources.
接下来就介绍如何使用 AngularJS 的 $resource
对接 ASP.NET Web API 创建的 REST 服务。
假设我们有下面一个 Category
实体类:
public class Category {
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
}
CategoriesController
类实现了基本的 CURD 操作, 代码如下:
public class CategoriesController : ApiController {
private static readonly IList<Category> Data;
// GET ~/api/categories
public IHttpActionResult GetAll() {
return Ok(Data);
}
// GET ~/api/categories/{id:int}
public IHttpActionResult Get(int id) {
var c = Data.FirstOrDefault(cat => cat.CategoryId == id);
if (c == null) {
return NotFound();
}
return Ok(c);
}
// POST ~/api/categories
public IHttpActionResult Post(Category category) {
category.CategoryId = Data.Count 1;
Data.Add(category);
var response = Request.CreateResponse(category);
var url = Url.Link("DefaultApi", new { id = category.CategoryId });
response.Headers.Location = new Uri(url);
return ResponseMessage(response);
}
// PUT ~/api/categories/{id:int}
public IHttpActionResult Put([FromUri]int id, [FromBody]Category category) {
var cat = Data.FirstOrDefault(c => c.CategoryId == id);
if (cat == null) {
return NotFound();
}
cat.CategoryName = category.CategoryName;
cat.Description = category.Description;
return Ok(cat);
}
// DELETE ~/api/categories/{id:int}
public IHttpActionResult Delete(int id) {
var cat = Data.FirstOrDefault(c => c.CategoryId == id);
if (cat != null) {
Data.Remove(cat);
}
return StatusCode(System.Net.HttpStatusCode.NoContent);
}
}
实现的 REST 服务描述如下:
方法 | 地址 | 描述 |
---|---|---|
GET | ~/api/categories | Get all categories |
GET | ~/api/categories/{id:int} | Get category by id |
POST | ~/api/categories/ | Create a new category |
PUT | ~/api/categories/{id:int} | Update an exist category |
DELETE | ~/api/categories/{id:int} | Delete category by id |
AngularJS 提供了 resource 服务来创建具有高级行为的对象和 REST 服务交互, 从而不需要在使用底层的 http 服务。
$resource
的基本用法如下:
$resource(url, [paramDefaults], [actions], options);
参数说明如下:
- url REST 服务的地址, 如果URL有参数, 则在参数名之前添加
:
, 比如:/user/:username
; - paramDefaults , 用 json 形式表示的 url 参数的默认值, 比如上面的
/user/:username
, 可以设置默认值为:{ username: 'anonymous' }
, 则默认会生成下面的 URL:/user/anonymous
; 如果参数的默认值是函数, 在请求时会执行函数以求得默认值;如果参数值是以@
开头的, 则表示要从请求发送的 json 对象中提取对应的属性值, 比如参数默认值为{ username: '@username' }
, 则会讲发送对象的username
属性填充到 URL 中; - actions 额外的 HTTP 动作, 具体请参考 $http.config;
- options 可选项, 只支持
stripTrailingSlashes
, 配置是否将 URL 结尾的/
移除;
$resource 返回的对象默认支持下列动作:
代码语言:javascript复制{
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
因此, 针对前面创建的 REST 服务, 还需要一个使用 PUT
的 update
动作, 客户端代码如下:
var categories = $resource('/api/categories/:id', { id: '@id' }, {
update: {
method: 'PUT'
}
});
使用起来也是非常方便的, 比如:
代码语言:javascript复制// get all categories from server
categories.query(function(data) {
// play with data in the call back;
});
// get one category
var cat = categories.get({id: 1}, function() {
cat.Description = 'a nice description';
cat.$update();
});
当然, 也可以使用 promise
风格的回调函数, 比如:
// get all categories with promise
categories.query().promise.then(function(data) {
// play with data in promise.then
})
.fail(function(http) {
// show http error here.
});