AngularJS $resource 在 Web Api 中搜索项目的工作示例
Posted
技术标签:
【中文标题】AngularJS $resource 在 Web Api 中搜索项目的工作示例【英文标题】:Working example of AngularJS $resource searching items in Web Api 【发布时间】:2014-05-28 15:22:28 【问题描述】:我正在学习如何使用 AngularJS 的 $resource 来调用 Web Api 后端。我想将对象层次结构作为标准传递并取回IEnumerable<Program>
。以下是条件示例:
$scope.criteria =
Categories:[
Name: "Cat1",
Options: [
Text: "Opt1", Value: true,
Text: "Opt2", Value: false
]
,
Name: "Cat2",
Options: [
Text: "Opt3", Value: true,
Text: "Opt4", Value: false
]
]
我在服务器上用 C# 定义了相同的对象。
public class CriteriaModel
public IEnumerable<CriteriaCategory> Categories get; set;
public class CriteriaCategory
public string Name get; set;
public IEnumerable<CriteriaOption> Options get; set;
public class CriteriaOption
public string Text get; set;
public bool Value get; set;
这是我配置 $resource 的方式:
angular.module('my.services')
.factory('api', [
'$resource',
function ($resource)
return
Profile: $resource('/api/profile/:id', id: '@id' ),
Settings: $resource('/api/settings/:id', id: '@id' ),
Program: $resource('/api/program/:id', id: '@id' )
;
]);
我这样称呼它:
api.Program.query( criteria: $scope.criteria , function (response)
$scope.programs = response;
);
无论我尝试什么,要么得到null
作为标准参数,要么根本不执行操作。我不知道问题出在 angular、web api 还是两者兼而有之。这是操作:
public class ProgramController : ApiController
public IEnumerable<Program> GetByCriteria([FromUri]CriteriaModel criteria)
// Either criteria is null or this action doesn't even get
// executed depending on what I try.
有人可以帮我找到一个使用 AngularJS $resource 和 Web Api 搜索和返回项目的工作示例吗?
【问题讨论】:
【参考方案1】:您将需要一个自定义模型绑定器。从what I understand FromUri
将不会处理复杂的嵌套类型或$resource
将放入查询字符串的json。
模型绑定器:
public class CriteriaModelBinder : IModelBinder
public bool BindModel(
HttpActionContext actionContext,
ModelBindingContext bindingContext
)
if (bindingContext.ModelType != typeof (CriteriaModel))
return false;
var value = bindingContext.ValueProvider.GetValue("Categories");
if (value == null)
return false;
var categoryJson = value.RawValue as IEnumerable<string>;
if (categoryJson == null)
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Categories cannot be null.");
return false;
var categories = categoryJson
.Select(JsonConvert.DeserializeObject<CriteriaCategory>)
.ToList();
bindingContext.Model = new CriteriaModel Categories = categories;
return true;
控制器:
[RoutePrefix("api/program")]
public class ProgramController : ApiController
[Route("getbycriteria")]
[HttpGet]
public HttpResponseMessage GetByCriteria(
[ModelBinder(typeof(CriteriaModelBinder))]CriteriaModel criteria
)
return new HttpResponseMessage(HttpStatusCode.OK);
角度控制器:
angular.module('myApp').
controller('HomeController', function($scope, $resource)
var Program = $resource('/api/program/:id', ,
getByCriteria:
url: '/api/program/getbycriteria',
method: 'GET',
isArray: true
);
var program = new Program();
var criteria =
Categories: [
Name: "Cat1",
Options: [
Text: "Opt1", Value: true ,
Text: "Opt2", Value: false
]
,
Name: "Cat2",
Options: [
Text: "Opt3", Value: true ,
Text: "Opt4", Value: false
]
]
;
$scope.submit = function ()
console.log(program);
program.$getByCriteria(criteria);
;
);
编辑:
这里是POST
:
控制器:
[RoutePrefix("api/program")]
public class ProgramController : ApiController
[Route("getbycriteria")]
[HttpPost]
public HttpResponseMessage GetByCriteria(CriteriaModel criteria)
return new HttpResponseMessage(HttpStatusCode.OK);
角度:
angular.module('myApp').
controller('HomeController', function($scope, $resource)
var Program = $resource('/api/program/:id', ,
getByCriteria:
url: '/api/program/getbycriteria',
method: 'POST',
isArray: true
);
var program = new Program();
program.Categories = [
Name: "Cat1",
Options: [
Text: "Opt1", Value: true ,
Text: "Opt2", Value: false
]
,
Name: "Cat2",
Options: [
Text: "Opt3", Value: true ,
Text: "Opt4", Value: false
]
];
$scope.submit = function ()
console.log(program);
program.$getByCriteria();
;
);
【讨论】:
因此,如果我在 $resource 中创建了一个新操作,该操作执行 POST 并将 [FromUri] 从参数中移除,是否可以在无需创建自定义模型绑定器的情况下处理它? 默认模型绑定器在请求正文中查找 JSON。$resource
是 RESTful 并在查询字符串中发送 JSON。不匹配是您需要使用模型绑定器或使用 $http
的原因。
等等,我很困惑。您可以根据文档使用“POST”方法在 $resource 上指定新操作。您是说它忽略了这一点并将其放在查询字符串中吗?
是的,您可以将操作更改为POST
,除非您需要将Categories
直接附加到program
对象。
我建议不要使用POST
,除非您打算进行有副作用的操作。以上是关于AngularJS $resource 在 Web Api 中搜索项目的工作示例的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AngularJS $resource 中使用路径变量而不是请求参数