7

I have a controller called News in my WebAPI project, I have two default actions called Get that handled the following URL's:

/api/News <- this returns a list of news /api/News/123 <- this returns a specific news item by id.

All straightforward so far and obviously the default route handles these scenarios. I next want to have a URL that looks like this:

/api/News/123/Artists <- will return all artists related to the specified news item.

Now I am fairly news to ASP.Net MVC and WebAPI so this is the first time I have had to deal with routing. I have modified my default route to look like this:

routes.MapRoute(
            name: "Default",
            url: "{controller}/{id}/{action}",
            defaults: new { controller = "News", action = "Get", id = UrlParameter.Optional }

So here I have moved the {action} to the end of the URL and I have added a Artists method to my News controller. This still works with the first two scenarios but returns a 404 for the third scenario.

Obviously the routing isn't working for /api/News/123/Artists but I have no idea why.

I can't seem to find any examples of people using WebAPI like this which makes me think I am doing something fundamentally wrong.

Any help would be appreciated.

3 Answers 3

8

The issue is, that you are trying to acces Web API but mapping the ASP.NET MVC

this is a mapping you need:

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

And it should be done in the App_Start \ WebApiConfig (if using the default template settings)

Example of the methods (in your news API controller):

// GET api/values/5
public string Get(int id)
{
  return "value " + id;
}

// GET api/values/5
[HttpGet]
public string Artist(int id)
{
  return "artist " + id;
}
Sign up to request clarification or add additional context in comments.

1 Comment

AH! Your right, I immediately went to the RouteConfig class and not the WebApiConfig class. Put this down to a WebAPI rookie mistake :)
3

The AttributeRouting should be a good solution. It can be installed by Nuget, and the document is here.

Some examples

public class SampleController : Controller
{
    [GET("Sample")]
    public ActionResult Index() { /* ... */ }
                    
    [POST("Sample")]
    public ActionResult Create() { /* ... */ }
                    
    [PUT("Sample/{id}")]
    public ActionResult Update(int id) { /* ... */ }
                    
    [DELETE("Sample/{id}")]
    public string Destroy(int id) { /* ... */ }
    
    [Route("Sample/Any-Method-Will-Do")]
    public string Wildman() { /* ... */ }

    [GET("", ActionPrecedence = 1)]
    [GET("Posts")]
    [GET("Posts/Index")]
    public ActionResult Index() { /* ... */ }

    [GET("Demographics/{state=MT}/{city=Missoula}")]
    public ActionResult Index(string state, string city) { /* ... */ }
}

It works very well about custom routing.

Update

In asp.net WebApi 2, AttributeRouting is included inside by native. It has some history, the first version, asp.net WebApi 1, is weak about routing annotations.

And then, asp.net WebApi 2 is released, the AttributeRouting is included by native. So, that open project is not maintained anymore, said in GitHub page.

In microsoft blog, the section Independent Developer Profile – Tim McCall – Attribute Routing in MVC and Web API 2 said about the history too.

2 Comments

Down voted for recommending a third party solution to solve a simple misunderstanding with the framework. It works fine OOTB.
1

In routing Action is the action name on the method that you want to route to .That action name should be in the attribute used on the method.

 [HttpGet]
 [ActionName("CustomAction")]
public HttpResponseMessage MyNewsFeed(Some params)
{ return Request.CreateResponse(); }

Now your route should look like this

routes.MapRoute(
        name: "Default",
        url: "{controller}/{id}/{action}",
        defaults: new { controller = "News", action = "CustomAction", id = UrlParameter.Optional 

Let me know if this helps.

Comments

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.