我被分配为应用程序开发WebAPI控制器(之前从未使用过的东西)。一切都很顺利,有一些基本的请求,如GetAllUsers(int id)只是出于测试原因 - 配置本身很好。
现在问题就在这里。我有一个方法
GetAllItems(Carrier carrier)
其中Carrier是一个具有许多不同参数的类。由于我们已经在数据库中有一些Carrier实例用于测试目的,我尝试过查询数据库,根据ID(GUID)属性选择Carrier实例,但没有结果。
有没有办法在输入参数是对象时测试GET请求,而不是手动测试单个值(例如int ID),测试方法或某种测试输入参数?
编辑:感谢大家的反馈,我的问题的解决方案实际上比我预期的要容易得多。我绝对喜欢向你们所有人投票,虽然不幸的是我的声誉太低了(我是stackoverflow的新手),所以我不得不在不久的将来回到这一点。干杯:)
答案 0 :(得分:19)
据我了解您的问题,您希望能够直接在网址中传递运营商的属性,而不是在您的请求正文中传递。
例如:
[GET] http://localhost/entities?id=000000000000000
你的控制器方法就是这个
GetAllItems(Carrier carrier)
承运人拥有Id(Guid)财产:
class Carrier {
public Guid Id { get; set; }
public string Name { get; set; }
}
Carrier是WebApi模型绑定方面的复杂对象。
模型绑定的默认行为是:
默认情况下,Web API使用以下规则绑定参数: 如果参数是“简单”类型,则Web API会尝试从URI获取值。简单类型包括.NET基元类型(int,bool,double等),以及TimeSpan,DateTime,Guid,decimal和string,以及具有可以从字符串转换的类型转换器的任何类型。 (稍后将详细介绍类型转换器。) 对于复杂类型,Web API尝试使用媒体类型格式化程序从邮件正文中读取值。
请参阅:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
期望与URL中的复杂对象进行模型绑定不是WebApi的默认行为。
如果您希望控制器方法从URL中对复杂对象进行建模绑定,则必须告诉它。
GetAllItems([FromUri] Carrier carrier)
使用FromUri绑定指示器,您可以使用URL中的复杂模型绑定
现在,您甚至可以在URL中添加更多属性映射:
[GET] http://localhost/entities?id=000000000000000&name=ABC
GetAllItems将收到一个填充有以下内容的Carrier对象: carrier.Id = 0000-00000000000-000; carrier.Name =“ABC”
答案 1 :(得分:4)
此处存在路由问题以及一些误解。
WebApi的默认路由是:
routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
这与某些惯例一起:
当您的命名约定与WepApi约定不一致时,您需要指定方法,操作名称等。
您的路线也是如此。如果您没有定义其他路由,则只有遵循约定和默认路由的操作才会受到限制。
例如:
public IEnumerable<Carrier> GetAll(){
//this will get called when using the route: /api/carriers/
}
public IEnumerable<Carrier> Get(string id){
//this will be called when using the route: /api/carriers/1
//where 1 is the carrier id
}
将在CarrierController中工作,因为它们都与约定和路径一致。
现在,如果您需要一个返回承运人所有物品的方法,您将需要这种方法:
[ActionName("getItems")]
public IEnumerable<Item> GetAllItems(string id){
//where id is the carrierid
var carrierId = id;
//because you are specifying the ActionName to getItems this will match the following route:
// /api/carriers/getItems/1
}
另一种选择是创建一个ItemsController,并添加一个基于carrierId返回项目列表的动作,这在概念上可能更好,但路由原理是相同的。