5

I am creating my first ASP.NET web API. I am trying to follow the standard REST URLs. My API would return the search result records. My URL should be –

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

I am planning to use oData for searching and Basic / Digest Authentication over IIS. My problem is in the nested resources. Before I return the search results, I need to check whether the user has access to this category and sub category. Now I created my Visual Studio 2012 – MVC4 / Web API project to start with. In the App_Start folder, there are 2 files that I believe are URL and order of resource related.

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 }
);

With this model, it works fine if my URL is ../api/records?SearchCriteria but it is not my URL design mentioned above. I understand that I have to do little more reading but so far not able to find the correct article. Need your advice on how to achieve my URL and what changes are needed in these 2 files. Alternatively, are there some other configuration that I am missing here? Thanks in advance.

2 Answers 2

3

Asp.net Web API 2 provides Attribute routing out of the box. You can define Route on individual action method or at global level.

E.g:

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

You can also set a common prefix for an entire controller by using the [RoutePrefix] attribute:

[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) { ... }
}

You can visit this link for more information on Attribute routing in Web API 2.

2

Assuming you have a controller named categories, Your WebApiConfig.cs could have a route like this to match your desired url (I would personally leave the /records portion off):

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

and a method could look like this:

// 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))
    {
    }
}

But, what if you want to also return just the categories and not subcategories? You'd need an additional route after the first one that is more generic:

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

with two methods like:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.