Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ivan 165 posts 543 karma points
    Jun 21, 2017 @ 15:44
    Ivan
    1

    Can I use Rout Attributes in Umbraco controllers?

    Hi guys!

    The controller is as follows:

    public class ProductsController : UmbracoApiController
    {
        public List<Product> GetAllProducts()
        {
            return null;
        }
    }
    

    I can easily access the method like this:

    /api/products/getAllProducts
    

    But can I do the same with:

    /api/products/
    

    I know it’s possible in ASP.NET Web API 2.0 using Rout Attributes. Not sure about Umbraco however.

  • Jonathan Richards 288 posts 1742 karma points MVP
    Jun 22, 2017 @ 09:20
    Jonathan Richards
    3

    Hi Ivan,

    You sure can, I do it myself all the time.

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

    [RoutePrefix("api/v1/products")]
    public class ProductsController : UmbracoApiController
    {
        [Route("")]
        public List<Product> GetAllProducts()
        {
            return null;
        }
    
        [Route("{productId}")]
        public Product GetProduct(int productId)
        {
            //   Throw a clean exception
            throw new HttpResponseException(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.BadRequest,
                Content = new StringContent("not written")
            });    
        }
    
        [Route("{productId}/sources")]
        public List<Source> ListProductSources(int productId)
        {
            return null;
        }
    
        [Route("{productId}/sources/{sourceId}")]
        public Source GetProductSource(int productId, int sourceId)
        {
            return null;
        }
    
    }
    

    Cheers

    Jonathan

  • Tom van Enckevort 107 posts 429 karma points
    Jun 22, 2017 @ 14:45
    Tom van Enckevort
    0

    I'm trying something similar, but with an UmbracoAuthorizedController:

    [RoutePrefix("umbraco/backoffice/MyDashboardSection")]
    public class MyDashboardSectionController : UmbracoAuthorizedController
    {
        [Route("")]
        public ActionResult Index()
        {
            return View("MyDashboard/Index.cshtml");
        }
    }
    

    But I get a 404 when I try to go to /umbraco/backoffice/MyDashboardSection

    Any reason on why that wouldn't work?

  • Tom van Enckevort 107 posts 429 karma points
    Jun 22, 2017 @ 15:43
    Tom van Enckevort
    2

    Turns out I needed to add /api/ in there. I guess it must be a route restriction within Umbraco.

    So my new controller now looks like:

    [RoutePrefix("umbraco/backoffice/api/MyDashboardSection")]
    public class MyDashboardSectionController : UmbracoAuthorizedController
    {
        [Route("")]
        public ActionResult Index()
        {
            return View("Index");
        }
    }
    
  • Ivan 165 posts 543 karma points
    Jun 22, 2017 @ 15:45
    Ivan
    0

    Hi Jonathan,

    Thanks for your effort. But I couldn't get this working.

    When I access the

    http://localhost:53724/umbraco/api/v1/products/
    

    Umbraco is not able to route this correctly and always returns 404.

    But this url is handler correctly:

    http://localhost:53724/umbraco/api/products/getallproducts
    

    event though I use routing attributes just as you showed in previous post.

    Which version of Umbraco are using? We use Umbraco 7.5.8 along with OWIN.

  • Jonathan Richards 288 posts 1742 karma points MVP
    Jun 22, 2017 @ 16:18
    Jonathan Richards
    1

    Hi Ivan,

    I don't have an answer to your issue, all I can say is that I'm using Umbraco 7.5.13. I haven't added/installed or changed any membership providers.

    I have installed Swagger (technically its Swashbuckle) into my Umbraco instance, so that I can test and document the End Points, which I show a screenshot here.

    enter image description here

    The code being used to generate those end points is in essence the code I posted in my previous post. And everything works as advertised.

    Cheers

    Jonathan

  • Tom van Enckevort 107 posts 429 karma points
    Jun 23, 2017 @ 07:45
    Tom van Enckevort
    1

    Hi Ivan,

    I think the RoutePrefix starts from the root, so you probably want to add umbraco in there as well to make it work on the URL you're trying:

    [RoutePrefix("umbraco/api/v1/products")]
    
  • Ivan 165 posts 543 karma points
    Jun 25, 2017 @ 11:30
    Ivan
    0

    Hi Tom,

    That did not help, unfortunately. I installed UmbracoCMS 7.5.13 on top of empty ASP.NET Web solution, and created simple controller:

    [RoutePrefix("umbraco/api/v1/products")]
    public class ProductsController : UmbracoApiController
    {
        [Route("")]
        public List<Product> GetAllProducts()
        {
            return null;
        }
    }
    

    But result remains same:

    • umbraco/api/v1/products - not working
    • umbraco/api/getallproducts - works fine
  • Tom van Enckevort 107 posts 429 karma points
    Jun 25, 2017 @ 17:11
    Tom van Enckevort
    3

    I assume you did remember to include a call to RouteTable.Routes.MapMvcAttributeRoutes() (link) somewhere in your application start events?

  • Ivan 165 posts 543 karma points
    Jul 10, 2017 @ 11:57
    Ivan
    105

    Thanks, Tom! Cannot believe I made this working.

    It turned out:

    • I didn't setup the config.MapHttpAttributeRoutes() for WebApi.
    • I used System.Web.Mvc.Route instead of System.Web.Http.Route.

    For those who faced similar problem, I'm posting final solution:

    UmbracoApplicationEventHandler.cs

    public class UmbracoApplicationEventHandler : IApplicationEventHandler
    {
        public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            WebApiConfig.Register(GlobalConfiguration.Configuration);
        }
    }
    

    WebApiConfig.cs

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();
        }
    }
    

    ProductsController.cs:

    using System.Web.Http;
    
    [RoutePrefix("api/products")]
    public class ProductsController : ApiController
    {
        [Route]
        public string GetAll(int id)
        {
            return "all";
        }
    
        [Route("{id}"]
        public string GetById(int id)
        {
            return "by id";
        }
    }
    
  • Tom van Enckevort 107 posts 429 karma points
    Jul 10, 2017 @ 12:03
    Tom van Enckevort
    0

    Yes, that has happened to me once as well. It's frustrating once you realise why it isn't working :-)

  • Kristian Ravnevand 94 posts 214 karma points
    Jan 22, 2019 @ 13:02
    Kristian Ravnevand
    0

    Thanks for this pointer. In case someone has the same problem as me. For me the issue was:

    using System.Web.Mvc;

    Instead of:

    using System.Web.Http;

    (the .Mvc namespace was referenced to my controller before I added custom routes, so the [RoutePrefix] didn't give any errors.

  • Nijaz Hameed 29 posts 163 karma points
    Nov 15, 2019 @ 04:15
    Nijaz Hameed
    0

    @Ivan Is it possible to do dependency injection for APIcontrollers, because i need to inject another service of umbraco during api call, for example IMemberService, i have tried with light inject and auto fac nut nothing worked, please check the error below, (Question related to umbraco 8)

    {
    "Message": "An error has occurred.",
    "ExceptionMessage": "An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.",
    "ExceptionType": "System.InvalidOperationException",
    "StackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
    "InnerException": {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Type 'Integration.Controllers.MyController' does not have a default constructor",
        "ExceptionType": "System.ArgumentException",
        "StackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
    }
    

    }

  • Nijaz Hameed 29 posts 163 karma points
    Nov 15, 2019 @ 10:09
    Nijaz Hameed
    0

    I have resolved the issue by using UmbracoApiController and i have registerd my services using IUserComposer so dependency injection works fine as expected. after all, UmbracoApiController is inheriting System.Web.Http.ApiController, so it is working fine as expected.

Please Sign in or register to post replies

Write your reply to:

Draft