Building on the answer from Yishai, I think changing your routes to the following should work for your scenario:
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Default" },
constraints: new { id = @"\d*" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{action}",
defaults: null,
constraints: new { action = @"[a-zA-Z]+" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi3",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: null,
constraints: new { id = @"\d+", action = @"[a-zA-Z]+" }
);
Then on your default actions place an ActionName attribute.
public class DocumentController : ApiController
{
[ActionName("Default")]
[HttpGet]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is GET");
}
[HttpGet]
public HttpResponseMessage Metadata()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is Metadata");
}
[ActionName("Default")]
[HttpGet]
public HttpResponseMessage Get(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET with ID");
}
[ActionName("Default")]
[HttpPost]
public HttpResponseMessage Post([FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is Post");
}
[ActionName("Default")]
[HttpPut]
public HttpResponseMessage Put(int id, [FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is PUT");
}
[HttpGet]
public HttpResponseMessage Tags(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET TAGS");
}
[HttpPost]
public HttpResponseMessage Tags(int id, [FromBody] IEnumerable<TagDefinitionDTO> tagDefinitions)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is POST TAGS");
}
}
As mentioned, Web API 2 is a much better way to go.