URL中的Web API嵌套资源

时间:2013-05-13 01:34:12

标签: asp.net url asp.net-web-api

我正在创建我的第一个ASP.NET Web API。我试图遵循标准的REST URL。我的API会返回搜索结果记录。我的网址应为 -

../api/categories/{categoryId}/subcategories/{subCategoryId}/records?SearchCriteria

我计划使用oData进行搜索,并使用IIS进行基本/摘要式身份验证。我的问题在于嵌套资源。在我返回搜索结果之前,我需要检查用户是否可以访问此类别和子类别。 现在我开始创建我的Visual Studio 2012 - MVC4 / Web API项目。在App_Start文件夹中,我认为有两个文件是URL和资源相关的顺序。

1.RouteConfig.cs

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

2.WebApiConfig.cs

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

使用此模型,如果我的URL是../api/records?SearchCriteria,它可以正常工作,但它不是我上面提到的URL设计。我知道我必须做更多的阅读,但到目前为止还没有找到正确的文章。需要您的建议如何实现我的URL以及这两个文件需要进行哪些更改。或者,我在这里缺少一些其他配置吗?提前谢谢。

2 个答案:

答案 0 :(得分:3)

Asp.net Web API 2提供开箱即用的属性路由。您可以在单个操作方法或全局级别定义Route

E.g:

[Route("customers/{customerId}/orders/{orderId}")]
public Order GetOrderByCustomer(int customerId, int orderId) { ... }

您还可以使用[RoutePrefix]属性

为整个控制器设置公共前缀
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
    // GET api/books
    [Route("")]
    public IEnumerable<Book> Get() { ... }

    // GET api/books/5
    [Route("{id:int}")]
    public Book Get(int id) { ... }
}

您可以访问this链接,以获取有关Web API 2中属性路由的更多信息。

答案 1 :(得分:2)

假设您有一个名为 categories 的控制器,您的WebApiConfig.cs可能会有这样的路由以匹配您想要的URL(我个人会将 / records 部分保留下来):

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{categoryId}/subcategories/{subCategoryId}",
    defaults: new { controller = "categories", categoryId = somedefaultcategory, 
        subCategoryId = RouteParameter.Optional }
);

并且方法可能如下所示:

// search a single subcategory
public IQueryable<SearchRecord> Get(int categoryId, int subCategoryId = 0, string SearchCriteria = "")
{        
    // test subCategoryId for non-default value to return records for a single 
    // subcategory; otherwise, return records for all subcategories
    if (subCategoryId != default(int))
    {
    }
}

但是,如果你只想返回类别而不是子类别怎么办?在第一个更通用的路线后,你需要一个额外的路线:

config.Routes.MapHttpRoute(
    name: "Categories",
    routeTemplate: "api/{controller}/{categoryId}",
    defaults: new { controller = "categories", categoryId = RouteParameter.Optional }
);

有两种方法,如:

// search a single category
public IQueryable<SearchRecord> Get(int categoryId, string SearchCriteria = "")
{
}
// search all categories
public IQueryable<SearchRecord> Get(string SearchCriteria = "")
{
}