API Controller with custom action - c#

I need to have a custom action for my api controller like api/{controller}/{action}/{id}
This is my config
config.Routes.MapHttpRoute(
name: "DefaultMethodApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "Browse", id = RouteParameter.Optional }
);
This hit the default route /api/dropzone/1
But i try to hit /api/dropzone/browse/1 by the "ApiByAction" configuration, but it doesnt work.

The order of your route definitions is important, make sure you respect it, because they are evaluated in the same order in which you declared them:
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { action = #"^(?!\d)[a-z0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "DefaultMethodApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Also notice that you might need to specify a constraint for the {action} token in the first route definition.

Related

Route Config with multiple custom actions in web api

So I have GET-methods in two different controllers that does not seem to work at the same time. My route config looks like this:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "GetGroupsFromSection",
routeTemplate: "api/{controller}/{action}/{sectionId}"
);
config.Routes.MapHttpRoute(
name: "ReturnCountForGroup",
routeTemplate: "api/{controller}/{action}/{groupIdCount}"
);
}
With this config, the first route(GetGroupsFromSection) works, but not the other one. If I switch them up so the ReturnCountForGroup is first, then that one works but not the other.
This is the methods
In the GroupController:
[HttpGet]
public IEnumerable<Group> GetGroupsFromSection(int sectionId)
{
var allGroups = groupRepository.SearchFor(s => s.SectionId == sectionId).ToList();
return (IEnumerable<Group>)allGroups;
}
And here is the other one from the ActivationCode-controller:
[HttpGet]
public int ReturnCountForGroup(int groupIdCount)
{
var count = dataContext.ActivationCode.Count(c => c.GroupId == groupIdCount);
return count;
}
GetGroupsFromSection is getting a 200 ok. But the ReturnCountForGroup get this error-message:
"MessageDetail": "No action was found on the controller 'ActivationCode' that matches the request."
There are conflicting routes which need to be made more specific for a route match to be made. Also the order of how routes are added to the route table is important. More generic routes need to be added after more specific/targeted routes.
config.Routes.MapHttpRoute(
name: "GetGroupsFromSection",
routeTemplate: "api/Group/{action}/{sectionId}",
defaults: new { controller = "Group" }
);
config.Routes.MapHttpRoute(
name: "ReturnCountForGroup",
routeTemplate: "api/ActivationCode/{action}/{groupIdCount}",
defaults: new { controller = "ActivationCode" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

Unable to Create a method with Custom Name in Asp.Net Web API?

I have a controller Named "Product" in which I am writing a Method with custom Name "CategorizedProducts" as shown in this
SCREENSHOT. I have not decorated it with [HttpGet]. When I request this action/method in chrome, THIS error is occurred. Routes from WebAPIConfig.cs are given below:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Below two Routes are also there in Routes.cs file:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = UrlParameter.Optional }
);
Please help me how to get rid of this error and successfully get data by using CategorizedProducts Method name.
Thanks

Call Api without custom route

I can call Api with custom route.
(url: 'api/WorkItem/1/GetOne')
[HttpGet]
[Route("api/WorkItem/{id}/GetOne")]
public async Task<IEnumerable<WorkItemDto>> GetOne(int id)
{
//...
}
But I cant call same api if I remove custom route:
This is my route definsion:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional }
);
I expect this to work without custom route but it does not.
I get 404-NotFound.
What am I doing wrong?
Map route two times. first with action and second time without
config.Routes.MapHttpRoute(
name: "WithAction",
routeTemplate: "api/{controller}/{id}/{action}"
);
config.Routes.MapHttpRoute(
name: "DefaultId",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

How to access web api method by using WebapiConfig?

i would like to access below methods but i can not access "http://www.test.com:46707/rpc/RealmStatus/RealmByPopulationName/2/Vindication"
[ActionName("RealmByPopulationName")]
public IEnumerable<MyRealmStatus> GetRealmsByBattleGroupName(int regionid, string battlegroupname)
{
//dosomething...
}
My webApiConfig.cs below
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{regionid}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "GetData",
routeTemplate: "api/{controller}/{regionid}/{id}"
);
config.Routes.MapHttpRoute(
name: "RpcApi",
routeTemplate: "rpc/{controller}/{action}/{regionid}",
defaults: new { action = "Get" }
);
config.Routes.MapHttpRoute(
name: "RpcApi2",
routeTemplate: "rpc/{controller}/{action}/{regionid}/{quality}/",
defaults: new { action = "Get" }
);
config.Routes.MapHttpRoute(
name: "RpcApi3",
routeTemplate: "rpc/{controller}/{action}/{regionid}/{battlegroupname}/",
defaults: new { action = "Get" }
);
}
}
Error occurs i can not access GetRealmsByBattleGroupName
Result of "http://www.test.com:46707/rpc/RealmStatus/RealmByPopulationName/2/Vindication" :
<Error>
No HTTP resource was found that matches the request URI 'http://www.test.com:46707/rpc/RealmStatus/RealmByPopulationName/2/Vindication'.
No action was found on the controller 'RealmStatus' that matches the request.
Your call is going to match this route first:
config.Routes.MapHttpRoute(
name: "RpcApi2",
routeTemplate: "rpc/{controller}/{action}/{regionid}/{quality}/",
defaults: new { action = "Get" }
);
Therefore your API is looking for a method on the RealmStatus controller that matches the following signature:
[ActionName("RealmByPopulationName")]
GetRealmsByBattleGroupName(int regionid, string quality)
If quality is a number you could differentiate the routes by adding the following constraint:
config.Routes.MapHttpRoute(
name: "RpcApi2",
routeTemplate: "rpc/{controller}/{action}/{regionid}/{quality}/",
defaults: new { action = "Get" },
constraints: new { id = #"(^\d+$)" }
);

MVC Web Api Route with default action not working

In my TestController I have the following:
[HttpGet]
public IEnumerable<String> Active()
{
var result = new List<string> { "active1", "active2" };
return result;
}
[HttpGet]
public String Active(int id)
{
var result = new List<string> { "active1", "active2" };
return result[id];
}
In RouteConfig the mapping is:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "", id = RouteParameter.Optional });
In a browser the following request works:
api/test/active/1
But this returns a Internal Server Error:
api/test/active
What do you have to do to return a action that may or maynot have a parameter in a similar manner to the default Get?
Update 1
As Cuong Le suggested, changing the ordering of routes helped, the routes are now:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I had to remove action = "" from the ActionApi route otherwise the standard Get on the other controllers stopped working (i.e. api/values)
api/test/active is now resolving, but I now get a 500 Internal Server Error for /api/test is it possile to have both resolves, so api/test would return "all" and /test/active only return "some"?
It is probably getting confused since you have two methods named action. Try deleting or renaming one of them and see if that works.
One way to do it is to provide a default value for the parameter,
[HttpGet]
public String Active(int id = 0)
{
var result = new List<string> { "active1", "active2" };
if (id == 0) {
return result;
} else {
return result[id];
}
}

Categories

Resources