Copied to clipboard

Flag this post as spam?

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


  • Debabrata 6 posts 107 karma points
    Apr 04, 2019 @ 02:03
    Debabrata
    0

    Umbraco 8 - ApiController attribute routing

    I am trying to develop an web api using umbraco api controller which works fine if I provide the controller and action name in the url but if I am trying to to use attribute routing as like Asp.Net Web Api it's returning 404.

    working url : umbraco/api/MembershipApi/GetAllMembers

    404 url : umbraco/api/members

    public class MembershipApiController : UmbracoApiController {
            [HttpGet]
            [Route("umbraco/api/members")]
            public IEnumerable<string> GetAllMembers()
            {
                return new[] { "Table", "Chair", "Desk", "Computer", "Beer fridge"};
            } }
    
  • Marc Goodson 2112 posts 14120 karma points MVP 8x c-trib
    Apr 04, 2019 @ 19:51
    Marc Goodson
    100

    Hi Debabrata

    I wonder if you have called MapHttpAttributeRoutes() at startup ?

    If you have your Api controller defined like so: (make sure you are using System.Web.Http namespace and not System.Web.Mvc:

    using System.Collections.Generic;
    using System.Web.Http;
    using Umbraco.Web.WebApi;
    
    namespace Umbraco8.Controllers
    {
        public class MembershipApiController : UmbracoApiController
        {
            [HttpGet]
            [Route("umbraco/api/members")]
            public IEnumerable<string> GetAllMembers()
            {
                return new[] { "Table", "Chair", "Desk", "Computer", "Beer fridge" };
            }     
        }
    }
    

    Then in order to have the request respond on a request to /umbraco/api/members

    then you'll need to tell Umbraco to MapHttpAttributeRoutes at startup, you can do this in V8 by creating a 'Component' (https://our.umbraco.com/documentation/Implementation/Composing/)

    So add a c# class something like this:

    using System;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Umbraco.Core.Composing;
    using Umbraco.Web;
    using Umbraco.Web.Mvc;
    
    namespace Umbraco8.Components
    {
    
        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
            public class MapHttpRoutesComposer : ComponentComposer<MapHttpRoutesComponent>
            {
                // nothing needed to be done here!
            }
            public class MapHttpRoutesComponent : IComponent
            {
                // initialize: runs once when Umbraco starts
                public void Initialize()
                {
                   GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
                }    
    
                public void Terminate()
                {
    
                }
            }
        }
    }
    

    Should do the trick!

    regards

    Marc

  • Debabrata 6 posts 107 karma points
    Apr 05, 2019 @ 03:10
    Debabrata
    1

    Hi Mark, Thanks for your help. I implemented the same with a little bit change, I moved the MapHttpAttributeRoutes method inside the constructor of MapHttpRoutesComponent class. After this change, it's started working.

    public class MapHttpRoutesComponent : IComponent
    {
        public MapHttpRoutesComponent()
        {
            GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
        }
        public void Initialize()
        {
    
        }
    
        public void Terminate()
        {
    
        }
    }
    
  • Thomas 315 posts 602 karma points c-trib
    Oct 17, 2019 @ 13:48
    Thomas
    0

    Hey

    I'm trying to do what has been described here.. But can't get it to work..

    When I call this from postman

    (/umbraco/api/v1/SubscribeToPage?pageId=1283&[email protected]), i'm just getting a 404. Anyone that can see what i'm doing wrong??

    My controller looks like this

    public class SubscribeController : UmbracoApiController
    {
        protected new ServiceContext Services { get; }
        public SubscribeController(ServiceContext services)
        {
            Services = services;
        }
        [HttpGet]
        [Route("umbraco/api/v1/SubscribeToPage")]
        public Status SubscribeToPage(int pageId, string email)
        {
            Status status = new Status();
            var node = Services.ContentService.GetById(pageId);
            if (node != null)
            {
                var member = Services.MemberService.GetByUsername(email);
                // Check if the member exists in the system
                if(member == null)
                {
                    // else create a member
                    member = Services.MemberService.CreateMember(email, email, email, "pageSubscribes");
                }
                // Get The udi from pageId - uses to add page to the multinode picker on member
                var pageUdi = Udi.Create(Constants.UdiEntityType.Document, node.Key).ToString();
                var currentList = member.GetValue("pages");
                if (currentList != null)
                {
                    List<string> pageList = currentList.ToString().Split(',').ToList();
                    pageList.Contains(pageUdi);
                    // check of the user already subscribe to given page
                    if (!pageList.Contains(pageUdi))
                    {
                        pageList.Add(pageUdi);
    
                        member.SetValue("pages", string.Join(",", pageList.ToArray()));
                        Services.MemberService.Save(member);
                        status.Success = true;
                        status.Message = node.Name;
                    } else
                    {
                        status.Success = false;
                        status.Message = "user already subscribing to " + node.Name;
                    }
                }
                else
                {
                    // if the list are empty
                    member.SetValue("pages", pageUdi);
                    Services.MemberService.Save(member);
                    status.Success = true;
                    status.Message = node.Name;
                }
            } else
            {
                status.Success = true;
                status.Message = "Page not existing";
            }
    
            return status;
        }
    
    
    
    
    }
    

    And my composer:

    public class MapHttpRoutesComponent : IComponent
    {
        public MapHttpRoutesComponent()
        {
            GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
        }
        public void Initialize()
        {
    
        }
    
        public void Terminate()
        {
    
        }
    }
    
  • David Armitage 503 posts 2071 karma points
    Jan 09, 2020 @ 15:07
    David Armitage
    0

    Hi,

    I tried both solutions and still got a 404. Any ideas?

    Here is my code.

    The Component - This fires as expect without error.

    using System.Web.Http;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    
    namespace CMS.Controllers.Api
    {
        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
        public class MapHttpRoutesComposer : ComponentComposer<MapHttpRoutesComponent>
        {
            // nothing needed to be done here!
        }
        public class MapHttpRoutesComponent : IComponent
        {
            public void Initialize()
            {
                GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
            }
    
            public void Terminate()
            {
    
            }
        }
    }
    

    The Api Controller.

    using System.Collections.Generic;
    using System.Web.Http;
    using Umbraco.Web.WebApi;
    
    namespace CMS.Controllers.Api
    {
        public class MembershipApiController : UmbracoApiController
        {
            [HttpGet]
            [Route("umbraco/api/members")]
            public IEnumerable<string> GetAllMembers()
            {
                return new[] { "Table", "Chair", "Desk", "Computer", "Beer fridge" };
            }
        }
    }
    
  • David Armitage 503 posts 2071 karma points
    Jan 09, 2020 @ 15:14
    David Armitage
    0

    Hi,

    I actually found the correct url by an extension method I found.

     @{
            var apiUrl = Url.GetUmbracoApiService<CMS.Controllers.Api.MembershipApiController>("GetAllMembers");
            <h1>@apiUrl</h1>
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft