【发布时间】:2014-10-24 00:20:25
【问题描述】:
ng-resource 返回一个具有以下默认资源操作的对象
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
我不确定从 AngularJS 的 REST WebApi 端点查询数据的最佳方法,但我已经在服务器端实现了 Predicate Builder 以便使用 Linq 查询我的数据库。我有一个名为“Search()”@/api/Product/Search 的(POST)端点,它将接受一个 searchCriteria JSON 对象,该对象被反序列化,馈送到 Linq 谓词构建器,并针对 dbContext 执行。我的 WebApi2 控制器的结构是这样的,使用新的路由属性功能:
[RoutePrefix("Product")]
public class ProductController : ApiController
{
[HttpGet]
[Route("")]
public IEnumerable<Product> Get()
{
try
{
return _productBL.Get();
}
catch
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
[HttpGet]
[Route("{productId}")]
public Product Get(string productId)
{
try
{
var product= _externalWorkStepBL.GetById(productId);
if (product== null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
catch (Exception)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
[HttpPost]
public HttpResponseMessage Post([FromBody]Product product)
{
try
{
_productBL.Insert(product);
var response = Request.CreateResponse(HttpStatusCode.Created, product);
response.Headers.Location = new Uri(Request.RequestUri, string.Format("Product/{0}", product.workItemID));
return response;
}
catch
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
}
[HttpPost]
[Route("Search")]
public IEnumerable<Product> Where([FromBody] SearchCriteria searchCriteria)
{
if (searchCriteria == null || (searchCriteria.FieldContainsList == null || searchCriteria.FieldEqualsList == null || searchCriteria.FieldDateBetweenList == null))
{
throw new HttpRequestException("Error in, or null, JSON");
}
return _productBL.Where(searchCriteria);
}
[HttpPut]
[Route("")]
public HttpResponseMessage Put([FromBody]Productproduct)
{
try
{
_productBL.Update(product);
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Headers.Location = new Uri(Request.RequestUri, string.Format("Product/{0}", product.Id));
return response;
}
catch ()
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
[HttpDelete]
[Route("{productId}")]
public void Delete(string productId)
{
HttpResponseMessage response;
try
{
_productBL.Delete(productId);
response = new HttpResponseMessage(HttpStatusCode.NoContent);
response.Headers.Location = new Uri(Request.RequestUri, string.Format("Product/"));
}
catch (Exception)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
}
在客户端,我将 $resource 包装在一个名为 $myResource 的工厂中,并添加了一个 PUT 方法。然后我将 $myResource 用于我的其他工厂,如下所示:
var app = angular.module('App', ['ngResource'])
.factory('$myResource', ['$resource', function ($resource) {
return function (url, paramDefaults, actions) {
var MY_ACTIONS = {
'update': { method: 'PUT' }
};
actions = angular.extend({}, MY_ACTIONS, actions);
return $resource(url, paramDefaults, actions);
}
}])
.service('ProductFactory', ['$myResource', function ($myResource) {
return $myResource('/api/Product/:productId')
}]);
这很好用,但现在我想添加我的搜索端点。 Angular documentation for ng-Resource 声明可以在操作方法中覆盖 url,但我不清楚如何执行此操作。我可以将“搜索”操作添加到 $myResource,但是如何修改 ProductFactory 中的 url?
.factory('$myResource', ['$resource', function ($resource) {
return function (url, paramDefaults, actions) {
var MY_ACTIONS = {
'update': { method: 'PUT' },
'search': { method: 'POST','params': { searchCriteria: '@searchCriteria' }, isArray: true }
};
actions = angular.extend({}, MY_ACTIONS, actions);
return $resource(url, paramDefaults, actions);
}
}])
按照目前的情况,调用 ProductFactory.search(searchCriteria) 会发送一个带有正确 JSON 的 POST 请求,但会发送到错误的 URL“/api/Product”。我需要它发布到“/api/Product/Search”。如何修改 $myResource 以使用“api/xxx/Search”,其中 xxx 是控制器名称?
【问题讨论】:
标签: angularjs asp.net-web-api2 ngresource