Using custom URL routing for WebAPI after changing from WebApi 2 + MVC to Umbraco
Hello,
I'm pretty new into using Umbraco.
I'm a computer science student who took over a project that formerly used ASP.Net WebApi2 in combination with MVC, but they merged the project with Umbraco.
Right now I'm facing the problem, that we have a mobile app that should be connected via and API.
right now the urls look like this: "umbraco/api/Items/getListItems/{id:int}".
and working perfectly fine
personally I want to remove the /umbraco/ so it begins with /api/.
But my real struggle is that I want to have a second (2) additional parameters for only one method in one of my controllers.
Like: "/api/Items/action/{categoryID}/{userid}"
As far as I could see there is both a AppStart/RouteConfig.cs & AppStart/WebApiConfig.cs
RouteConfig.cs contains:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
But as I found out changes have 0 affect on my routes. Not even a customized second entry or modifiyng the default route seems to make a difference.
I know from earlier projects that I could directly in the controller action say:
[System.Web.Http.Route("api/Items/getListItems/{id:int}")] and/or override default route by saying "~/api/..." but I guess they don't affect Umbraco's way to route.
In the Global.asax I could see that it still uses the old MVC settings:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Following guides saying I have to use:
public class MvcApplication : Umbraco.Web.UmbracoApplication
{
protected override void OnApplicationStarted(object sender, EventArgs e)
{
base.OnApplicationStarted(sender, e);
AreaRegistration.RegisterAllAreas();
}
}
just gives me the error "No suitable method found to override".
I should probably mention that the "Global.asax" is using the namespace "xxMVC" together with umbraco related files, while the WebAPI is using its own namespace "xxWebServices" and implementing the UmbracoApiController
public class Controllername : UmbracoApiController
(idk if thats needed or if I just can use the default controller)
I would be glad if someone knows a solution that could work.
sometimes I realy ask myself what the heck I'm doing.
I followed your suggestion giving it another try now with a new controller and voila, it works like a charm :)
I'm now even finally able to have more than one additional url paramter if it's needed.
Thanks for your help and time.
I have one last question. I'm now calling GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
directly in my controller like the documentation did (Copy & Paste).
The only thing I saw is, that this will affect every controller in this particular namespace. This isnt a big deal, since I wanted to remove the /umbraco/ in my urls.
But do u have a cleaner sugestion how I can implement
Because right now it looks hmm idk what to call it, but it looks not pretty that one controller contains a part, other controllers arent containing.
Is there a better way/solution u would suggest, or is it normal to create a "DefaultController" that then contains the "GlobalConf...".
and I would insert that component to be the 'first' in the stack.
The example is sort of munged, I wouldn't have the 'ProductsController' in the same file as the AttributeRoutingComponent!
So normally I would have a folder called 'Composition' and within that a folder called 'Components'
I'd create a file called 'RegisterComponents.cs' and I'd use this to register any Components that I'm using to extend Umbraco eg:
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class RegisterComponents : IComposer
{
public void Compose(Composition composition)
{
composition.Components().Insert<AttributeRoutingComponent>(); ;
}
}
then in the Components folder, I'd have the AttributeRoutingComponent:
public class AttributeRoutingComponent :IComponent
{
public void Initialize()
{
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
}
public void Terminate()
{
}
}
And then all my API controllers I'd have 'elsewhere', usually inside a folder called Api, inside another folder called Controllers and I'd have one file for each controller...
Hehe thanks, thats definitely neater & such a approach is what I had in mind.
My controllers are all in a folder called controllers.
I was just curious if it would have been a normal approach to place it in the controller itself, or like u suggested in another separate folder. But yea, placing it separate makes most sence.
Using custom URL routing for WebAPI after changing from WebApi 2 + MVC to Umbraco
Hello,
I'm pretty new into using Umbraco. I'm a computer science student who took over a project that formerly used ASP.Net WebApi2 in combination with MVC, but they merged the project with Umbraco.
Right now I'm facing the problem, that we have a mobile app that should be connected via and API.
right now the urls look like this: "umbraco/api/Items/getListItems/{id:int}". and working perfectly fine
personally I want to remove the /umbraco/ so it begins with /api/. But my real struggle is that I want to have a second (2) additional parameters for only one method in one of my controllers.
Like: "/api/Items/action/{categoryID}/{userid}"
As far as I could see there is both a AppStart/RouteConfig.cs & AppStart/WebApiConfig.cs
RouteConfig.cs contains:
and WebApiConfig:
But as I found out changes have 0 affect on my routes. Not even a customized second entry or modifiyng the default route seems to make a difference.
I know from earlier projects that I could directly in the controller action say: [System.Web.Http.Route("api/Items/getListItems/{id:int}")] and/or override default route by saying "~/api/..." but I guess they don't affect Umbraco's way to route.
In the Global.asax I could see that it still uses the old MVC settings:
Following guides saying I have to use:
just gives me the error "No suitable method found to override".
I should probably mention that the "Global.asax" is using the namespace "xxMVC" together with umbraco related files, while the WebAPI is using its own namespace "xxWebServices" and implementing the UmbracoApiController
(idk if thats needed or if I just can use the default controller)
I would be glad if someone knows a solution that could work.
Thanks in advance!
Regards Pierre
Hi Pierre
Could you use attribute routing for your API - see an example here:
https://our.umbraco.com/documentation/reference/routing/webapi/#using-mvc-attribute-routing-in-umbraco-web-api-controllers
regards
Marc
Hey Marc,
thanks for your response. I'm sorry that I'm replying that late, but had a lot of stuff to do.
Yes I already had a look at hat documentation, but sadly it doesnt seem to work.
Regards Pierre
Hi Pierre
What you have posted though doesn't appear to be following that?
It looks more like a V7 approach?
The key thing to getting API attribute routing to work is where you call
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
If you create exactly the example in the documentation with the 'ProductsController' and the Table, Chair etc
does that work for you?
regards
Marc
Hey Marc,
sometimes I realy ask myself what the heck I'm doing.
I followed your suggestion giving it another try now with a new controller and voila, it works like a charm :)
I'm now even finally able to have more than one additional url paramter if it's needed.
Thanks for your help and time.
I have one last question. I'm now calling
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
directly in my controller like the documentation did (Copy & Paste). The only thing I saw is, that this will affect every controller in this particular namespace. This isnt a big deal, since I wanted to remove the /umbraco/ in my urls.But do u have a cleaner sugestion how I can implement
Because right now it looks hmm idk what to call it, but it looks not pretty that one controller contains a part, other controllers arent containing. Is there a better way/solution u would suggest, or is it normal to create a "DefaultController" that then contains the "GlobalConf...".
Regards Pierre
Hi Pierre
I would have that call in its own 'component'
and I would insert that component to be the 'first' in the stack.
The example is sort of munged, I wouldn't have the 'ProductsController' in the same file as the AttributeRoutingComponent!
So normally I would have a folder called 'Composition' and within that a folder called 'Components'
I'd create a file called 'RegisterComponents.cs' and I'd use this to register any Components that I'm using to extend Umbraco eg:
then in the Components folder, I'd have the AttributeRoutingComponent:
And then all my API controllers I'd have 'elsewhere', usually inside a folder called Api, inside another folder called Controllers and I'd have one file for each controller...
Is that neater?
regards
marc
Hey Marc,
Hehe thanks, thats definitely neater & such a approach is what I had in mind.
My controllers are all in a folder called controllers. I was just curious if it would have been a normal approach to place it in the controller itself, or like u suggested in another separate folder. But yea, placing it separate makes most sence.
Thanks again for your help & time!
Regards Pierre
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.