2014-08-29 24 views
3

NG-資源返回一個對象具有以下默認資源行動

{ '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); 
      } 
     } 
    } 

在客戶端,我包裹在一個工廠名爲$ 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中的網址?

.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 /產品」。我需要它發佈到「/ api/Product/Search」。如何修改$ myResource使用「api/xxx/Search」,其中xxx是控制器名稱?

回答

4

沒關係!沒想到這個工作,但它確實。

.factory('$myResource', ['$resource', function ($resource) { 
      return function (url, paramDefaults, actions) { 
       var searchUrl = url + "/Search/:searchCriteria" 
       var MY_ACTIONS = { 
        'update': { method: 'PUT' },  //add update (PUT) method for WebAPI endpoint 
        'search': { method: 'POST', url : searchUrl,'params': { searchCriteria: '@searchCriteria' }, isArray: true }  //add Search (POST) 
       }; 
       actions = angular.extend({}, MY_ACTIONS, actions); 
       return $resource(url, paramDefaults, actions); 
      } 
     }])