MVC API路由当多个GET操作是present [英] MVC API Routing When Multiple Get Actions Are Present
问题描述
似乎有一千人询问关于堆栈溢出同样的问题,但似乎没有成为一个单一的解决这个问题。我要再问吧...
There seems to be a thousand people asking the same question on stack overflow, but there doesn't seem to be a single solution to this problem. I am going to ask it again...
我有了以下操作的API控制器:
I have an API controller that has the following actions:
// GET api/Exploitation
public HttpResponseMessage Get() {
var items = _exploitationRepository.FindAll();
var mappedItems = Mapper.Map<IEnumerable<Exploitation>, IEnumerable<ExploitationView>>(items);
var response = Request.CreateResponse<IEnumerable<ExploitationView>>(HttpStatusCode.OK, mappedItems);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { }));
return response;
}
// GET api/Exploitation/5
[HttpGet, ActionName("Get")]
public HttpResponseMessage Get(int id) {
var item = _exploitationRepository.FindById(id);
var mappedItem = Mapper.Map<Exploitation, ExploitationView>(item);
var response = Request.CreateResponse<ExploitationView>(HttpStatusCode.OK, mappedItem);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = id }));
return response;
}
// GET api/Exploitation/GetBySongwriterId/5
[HttpGet, ActionName("GetBySongwriterId")]
public HttpResponseMessage GetBySongwriterId(int id) {
var item = _exploitationRepository.Find(e => e.Song.SongWriterSongs.Any(s => s.SongWriterId == id))
.OrderByDescending(e => e.ReleaseDate);
var mappedItem = Mapper.Map<IEnumerable<Exploitation>, IEnumerable<ExploitationView>>(item);
var response = Request.CreateResponse<IEnumerable<ExploitationView>>(HttpStatusCode.OK, mappedItem);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = id }));
return response;
}
// GET api/Exploitation/GetBySongwriterId/5
[HttpGet, ActionName("GetBySongId")]
public HttpResponseMessage GetBySongId(int id) {
var item = _exploitationRepository.Find(e => e.SongId == id)
.OrderByDescending(e => e.ReleaseDate);
var mappedItem = Mapper.Map<IEnumerable<Exploitation>, IEnumerable<ExploitationView>>(item);
var response = Request.CreateResponse<IEnumerable<ExploitationView>>(HttpStatusCode.OK, mappedItem);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = id }));
return response;
}
在我APIConfig我已经定义了以下路线:
In my APIConfig I have defined the following routes:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional },
constraints: new { id = @"\d+" }
);
我发现我可以访问以下操作没有问题:
/ API /开发
/ API /开发/ getbysongwriterid / 1
/ API /开发/ getbysongid / 1
I am finding that I can access the following actions no problem: /api/exploitation /api/exploitation/getbysongwriterid/1 /api/exploitation/getbysongid/1
当我试图访问/ API /开发/ 1我得到这个例外
When I try to access /api/exploitation/1 I get this exception
"Multiple actions were found that match the request: System.Net.Http.HttpResponseMessage Get(Int32) on type Songistry.API.ExploitationController System.Net.Http.HttpResponseMessage GetBySongwriterId(Int32)" exception.
有人能看到什么是错我的路线?还是错别的东西?
Can anyone see what is wrong with my routes? Or wrong with something else?
推荐答案
我已经找到一个优雅的解决这个问题。
I have found an elegant solution to the problem.
我修改了ApiRouteConfig有以下途径:
I modified my ApiRouteConfig to have the following routes:
config.Routes.MapHttpRoute(
name: "DefaultGetApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Get" },
constraints: new { id = @"\d+", httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"\d+" }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional }
);
现在我可以访问:
/api/exploitation
/api/exploitation/1
/api/exploitation/getbysongid/1
/api/exploitation/getbysongwriterid/1
我并不需要修改我的控制器操作这个新的路由配置在所有的工作。
I did not need to modify my controller actions to work with this new routing config at all.
如果你有多个PUT或POST操作,你可以在创建看着新航线如下:
If you had multiple PUT or POST actions you could the create new routes that looked as follows:
config.Routes.MapHttpRoute(
name: "DefaultGetApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Put" },
constraints: new { id = @"\d+", httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
);
config.Routes.MapHttpRoute(
name: "DefaultGetApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Delete" },
constraints: new { id = @"\d+", httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
);
我希望这个答案可以帮助大家,因为这似乎是人有一个共同的问题。
I hope that this answer helps everyone as this seems to be a common issue that people are having.
这篇关于MVC API路由当多个GET操作是present的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!