我有一个非常标准的WebApi,它可以执行一些基本的CRUD操作。
我正在尝试添加一些不同类型的查找,但不太确定它应该如何完成。
这是我目前的FoldersController
public class FoldersController : ApiBaseController
{
//using ninject to pass the unit of work in
public FoldersController(IApiUnitOfWork uow)
{
Uow = uow;
}
// GET api/folders
[HttpGet]
public IEnumerable<Folder> Get()
{
return Uow.Folders.GetAll();
}
// GET api/folders/5
public Folder Get(int id)
{
return Uow.Folders.GetById(id);
}
// POST api/folders
public HttpResponseMessage Post(Folder folder)
{
Uow.Folders.Add(folder);
Uow.Commit();
var response = Request.CreateResponse(HttpStatusCode.Created, folder);
// Compose location header that tells how to get this Folder
response.Headers.Location = new Uri(Url.Link(WebApiConfig.DefaultRoute, new { id = folder.Id }));
return response;
}
// PUT api/folders
public HttpResponseMessage Put(Folder folder)
{
Uow.Folders.Update(folder);
Uow.Commit();
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
// DELETE api/folders/5
public HttpResponseMessage Delete(int id)
{
Uow.Folders.Delete(id);
Uow.Commit();
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
}我想要做的是添加一个如下所示的方法
public IEnumerable<Folder> GetChildFolders(int folderID)
{
return Uow.Folders.GetChildren(folderID);
}因为我已经有了标准的Get方法,所以我不太确定该怎么做。
我最初认为可以添加一个新的route..something,如下所示
routes.MapHttpRoute(
name: "ActionAndIdRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: null,
constraints: new { id = @"^/d+$" } //only numbers for id
);只需向我的[ActionName("GetChildren")]方法添加类似ActionName注释的内容
但那并没有飞起来。
我在正确的轨道上吗?我如何在不添加其他控制器的情况下做这样的事情?
发布于 2013-05-17 15:59:54
你可能不喜欢这个答案,但我觉得它是正确的。WebAPI被设计为每个实体类型只有5个调用,GET (一个项目/列表项),POST,PUT和DELETE。这允许REST URL,如文件夹/Get/5、文件夹/Get等。
现在,在您的场景中,您需要ChildFolders,我可以理解它们不是不同的对象,但它们在REST (ChildFolders/Get)等方面是不同的实体。我觉得这应该是另一个WebAPI控制器。
有一些方法可以修补Http路由来管理这一点,但我认为这不是Web API设计的工作方式,它强制您遵循REST数据逐个实体类型的协议……否则,为什么不直接使用AJAX调用的.NET MVC控制器呢?
发布于 2013-10-21 23:08:46
正如克里斯所说,WebAPI背后的想法是遵循REST模式。考虑到这一点,您可以决定如何将您的域映射到该模式。如果子文件夹就是文件夹,并且使用相同的内部逻辑,那么将Get放入FoldersController中可能是非常有意义的。如果不是,或者如果您想对子文件夹执行所有的REST方法,那么创建一个ChildFoldersController可能更有意义。
现在你的应用已经被合理地组织起来了,你可以考虑路由了。WebAPI现在支持属性路由。如果将这一行添加到您的WebApiConfig.Register -- config.MapHttpAttributeRoutes(); --如下所示:
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
);然后你可以把你的路线放在动作本身上:
[HttpGet]
[Route("folders/{folderID}/children")] // <-- notice the route here
public IEnumerable<Folder> GetChildFolders(int folderID)
{
return Uow.Folders.GetChildren(folderID);
}现在,您对路径"folders/{folderID}“的所有REST调用都将使用默认路由,而该路由上包含"/children”的任何gets都将执行该操作。它还使API的调用者非常清楚调用的行为。
您也可以使用普通路由模式执行此操作:
// default route
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// folder children route
config.Routes.MapHttpRoute(
name: "FolderChildrenApi",
routeTemplate: "api/folders/{folderID}/children",
defaults: new { controller = "Folders", action = "GetChildFolders" }
);如果您有其他有子资源的资源,您还可以将控制器作为变量留在该自定义路由中,并且您仍然可以将该操作放在一个单独的控制器中,该控制器还可以处理对路由“子文件夹/{folderID}”的调用。
路由非常灵活。只要确保它的设计对于api调用者和维护软件的人(包括您)来说都是有意义的。
下面是一些属性路由信息:Attribute Routing in WebAPI 2
发布于 2013-05-17 00:35:51
一种方法是编写特定于GetChildFolders操作的新路由。
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi-GetChildFolders",
routeTemplate: "api/{controller}/GetChildFolders/{id}",
defaults: new { action = "GetChildFolders" }
);https://stackoverflow.com/questions/16591859
复制相似问题