RESTful API controller/route 问题
RESTful API controller/route issue
我使用 VS 2013 创建了一个简单的 MVC/Web Api 应用程序。它有照片型号:
public class Photo
{
public int Id{ get; set; }
public string Name{ get; set; }
public DateTime DateTimeOriginal { get; set; }
}
和一个光电控制器:
Photo[] photos = new Photo[]
{
new Photo { Id= 1, Name= "Mary B.", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:01:22 PM")},
new Photo { Id = 2, Name= "Martin M.", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:13:09 PM" )},
new Photo { Id = 3, Name= "Sparky", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:31:22 PM")}
};
public IEnumerable<Photo> GetAllPhotos()
{
return photos;
}
public IHttpActionResult GetPhoto(int id)
{
var photo = photos.FirstOrDefault((p) => p.Id == id);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
public IHttpActionResult GetPhoto(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
}
//I added this to see if this helps with the routing. It didn't
public IHttpActionResult GetName(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
这会编译,我可以发出这样的 Web 请求:
http://localhost:59628/api/photos
我会取回一组照片元素。
我可以发出这样的网络请求:
http://localhost:59628/api/photos/2
然后我会返回 ID =2 的元素
但是
http://localhost:59628/api/photos/"Mary B"
或
Name="Mary B"
或
/GET/Name/Mary B
或
/api/photos/name/Mary B
它 returns 一个错误。
所以我的第一个问题是为什么?如何按名称查询照片服务?
第二个问题:我在路由配置中看到了信息,但即使我将其添加到 PhotosController:
[Route("photos/{photo}/Name")]
[HttpGet]
public IHttpActionResult GetName(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
我收到了 404。为什么?
配置路由以便 api 知道如何处理资源请求。
404 Not Found
当 api 找不到基于配置请求的资源时返回
如果计划使用属性路由,请确保在 WebApiConfig.cs
文件中配置它,如
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
对于属性路由,PhotosController
需要更新
[RoutePrefix("api/photos")]
public class PhotosController : ApiController {
Photo[] photos = new Photo[]
{
new Photo { Id= 1, Name= "Mary B", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:01:22 PM")},
new Photo { Id = 2, Name= "Martin M", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:13:09 PM" )},
new Photo { Id = 3, Name= "Sparky", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:31:22 PM")}
};
//GET api/photos
[HttpGet]
[Route("")]
public IEnumerable<Photo> GetAllPhotos() {
return photos;
}
//GET api/photos/5
[HttpGet]
[Route("{id:int}")]
public IHttpActionResult GetPhoto(int id) {
var photo = photos.FirstOrDefault((p) => p.Id == id);
if (photo == null) {
return NotFound();
}
return Ok(photo);
}
//GET api/photos/name/Mary B
[HttpGet]
[Route("name/{name}")]
public IHttpActionResult GetPhotoByName(string name) {
var photo = photos.FirstOrDefault((p) => p.Name == name);
if (photo == null) {
return NotFound();
}
return Ok(photo);
}
}
我使用 VS 2013 创建了一个简单的 MVC/Web Api 应用程序。它有照片型号:
public class Photo
{
public int Id{ get; set; }
public string Name{ get; set; }
public DateTime DateTimeOriginal { get; set; }
}
和一个光电控制器:
Photo[] photos = new Photo[]
{
new Photo { Id= 1, Name= "Mary B.", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:01:22 PM")},
new Photo { Id = 2, Name= "Martin M.", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:13:09 PM" )},
new Photo { Id = 3, Name= "Sparky", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:31:22 PM")}
};
public IEnumerable<Photo> GetAllPhotos()
{
return photos;
}
public IHttpActionResult GetPhoto(int id)
{
var photo = photos.FirstOrDefault((p) => p.Id == id);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
public IHttpActionResult GetPhoto(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
}
//I added this to see if this helps with the routing. It didn't
public IHttpActionResult GetName(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
这会编译,我可以发出这样的 Web 请求:
http://localhost:59628/api/photos
我会取回一组照片元素。
我可以发出这样的网络请求:
http://localhost:59628/api/photos/2
然后我会返回 ID =2 的元素
但是
http://localhost:59628/api/photos/"Mary B"
或
Name="Mary B"
或
/GET/Name/Mary B
或
/api/photos/name/Mary B
它 returns 一个错误。
所以我的第一个问题是为什么?如何按名称查询照片服务?
第二个问题:我在路由配置中看到了信息,但即使我将其添加到 PhotosController:
[Route("photos/{photo}/Name")]
[HttpGet]
public IHttpActionResult GetName(string Name)
{
var photo = photos.FirstOrDefault((p) => p.Name== Name);
if (photo == null)
{
return NotFound();
}
return Ok(photo);
}
我收到了 404。为什么?
配置路由以便 api 知道如何处理资源请求。
404 Not Found
当 api 找不到基于配置请求的资源时返回
如果计划使用属性路由,请确保在 WebApiConfig.cs
文件中配置它,如
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
对于属性路由,PhotosController
需要更新
[RoutePrefix("api/photos")]
public class PhotosController : ApiController {
Photo[] photos = new Photo[]
{
new Photo { Id= 1, Name= "Mary B", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:01:22 PM")},
new Photo { Id = 2, Name= "Martin M", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:13:09 PM" )},
new Photo { Id = 3, Name= "Sparky", DateTimeOriginal = Convert.ToDateTime("May 18, 2015 2:31:22 PM")}
};
//GET api/photos
[HttpGet]
[Route("")]
public IEnumerable<Photo> GetAllPhotos() {
return photos;
}
//GET api/photos/5
[HttpGet]
[Route("{id:int}")]
public IHttpActionResult GetPhoto(int id) {
var photo = photos.FirstOrDefault((p) => p.Id == id);
if (photo == null) {
return NotFound();
}
return Ok(photo);
}
//GET api/photos/name/Mary B
[HttpGet]
[Route("name/{name}")]
public IHttpActionResult GetPhotoByName(string name) {
var photo = photos.FirstOrDefault((p) => p.Name == name);
if (photo == null) {
return NotFound();
}
return Ok(photo);
}
}