Copied to clipboard

Flag this post as spam?

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


  • Laura 4 posts 24 karma points
    Dec 22, 2023 @ 19:16
    Laura
    0

    Backoffice Routing

    I want to make a backoffice API (I am programming a plugin) but the url for my controller doesn't work. I have tried so many but it always said: "Request error: The URL returned a 404 (not found)"

    I am using the umbraco version 13.0.1

    namespace UmbracoProject.App_Plugins.MyPluginName.backoffice.Controllers
    {
    [Umbraco.Web.Mvc.PluginController("ContentApi")]
    public class ContentController : UmbracoAuthorizedJsonController
    {
        public IEnumerable<string> PageNames()
        {
            return new[] { "Table", "Chair", "Desk", "Computer" };
        }
    }
    

    in my controllerName.controller.js

    $http.get("/umbraco/backoffice/ContentApi/Content/PageNames").then(function (response) {
    $scope.content.pages = response.data;
    }
    

    It would be really great if someone knew what the problem is, thank you!

  • John Sharp 20 posts 110 karma points
    Jan 01, 2024 @ 19:13
    John Sharp
    0

    Hi Laura,

    I've been doing something similar today

    [PluginController("Spero")]
    //[Route("umbraco/backoffice/api/[controller]/[action]")]
    public class ProductDataController : UmbracoAuthorizedApiController
    {
        private readonly IProductService _productService;
    
        public ProductDataController(IProductService productService)
        {
            this._productService = productService;
        }
    
    ...etc
    

    Without any further modifications, this URL works: https://localhost/umbraco/backoffice/Spero/ProductData/get

    I've left a commented line in, [Route... - if you uncomment it then it overrides everything and uses that URL and you'd have the API accessible at umbraco/backoffice/api/ProductData/get

    To answer your actual question, given the configuration you've specified above then this should work umbraco/backoffice/ContentApi/Content/PageNames - as it's what you're trying already it doesn't work, I'd try the [Route] attribute option.

    Also, is the controller in the main web application or in a separate library?

  • Laura 4 posts 24 karma points
    Jan 01, 2024 @ 20:58
    Laura
    0

    Hi John,

    thanks for your answer. I really don't know what I am doing differently... My Controller is in here: "\App_Plugins\PluginName\backoffice". However, it can't find "umbraco/backoffice/api/Content/PageNames" when I use [Route("umbraco/backoffice/api/[controller]/[action]")].

    Is there something else that I should configure?

  • John Sharp 20 posts 110 karma points
    Jan 01, 2024 @ 21:25
    John Sharp
    0

    OK.... so, on your method that you're trying to call, put [Route("{id"})].

    It should mean that you can call https://localhost/1

    Does that work, if not then you may need to look at the way program.cs is registering Controllers.

    I assume all othe APIs work?

  • Laura 4 posts 24 karma points
    Jan 01, 2024 @ 21:39
    Laura
    0

    Okay, then I believe the issue lies in the program.cs file

    Actually thats my first API and I don't know Umbraco very well.

    What should I configure in the program.cs file that it works?

  • John Sharp 20 posts 110 karma points
    Jan 01, 2024 @ 21:51
    John Sharp
    0

    OK, what happens if you remove the attribute completely?

    Also, what does your program.slcs look like?

  • Laura 4 posts 24 karma points
    Jan 02, 2024 @ 14:46
    Laura
    0

    Program.cs:

    public class Program
    {
    public static void Main(string[] args)
        => CreateHostBuilder(args)
            .Build()
            .Run();
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureUmbracoDefaults()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStaticWebAssets();
                webBuilder.UseStartup<Startup>();
            });
    }
    

    Startup.cs:

    public class Startup
    {
        private readonly IWebHostEnvironment _env;
        private readonly IConfiguration _config;
    
        /// <summary>
        /// Initializes a new instance of the <see cref="Startup" /> class.
        /// </summary>
        /// <param name="webHostEnvironment">The web hosting environment.</param>
        /// <param name="config">The configuration.</param>
        /// <remarks>
        /// Only a few services are possible to be injected here https://github.com/dotnet/aspnetcore/issues/9337.
        /// </remarks>
        public Startup(IWebHostEnvironment webHostEnvironment, IConfiguration config)
        {
            _env = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
            _config = config ?? throw new ArgumentNullException(nameof(config));
        }
    
        /// <summary>
        /// Configures the services.
        /// </summary>
        /// <param name="services">The services.</param>
        /// <remarks>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940.
        /// </remarks>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddUmbraco(_env, _config)
                .AddBackOffice()
                .AddWebsite()
                .AddDeliveryApi()
                .AddComposers()
                .Build();
            services.AddControllers();
        }
    
        /// <summary>
        /// Configures the application.
        /// </summary>
        /// <param name="app">The application builder.</param>
        /// <param name="env">The web hosting environment.</param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
    
            app.UseUmbraco()
                .WithMiddleware(u =>
                {
                    u.UseBackOffice();
                    u.UseWebsite();
                })
                .WithEndpoints(u =>
                {
                    u.UseInstallerEndpoints();
                    u.UseBackOfficeEndpoints();
                    u.UseWebsiteEndpoints();
                });
        }
    }
    

    Thanks for your help!

  • John Sharp 20 posts 110 karma points
    Jan 02, 2024 @ 16:46
    John Sharp
    0

    That all looks sensible based what I understand. I've done some digging and found this bit of code that might help. Add it at the very end of the Configure method. It'll add a list of the defined endpoints into your Debug window.

    var sys = app.Services.GetRequiredService<IActionDescriptorCollectionProvider>();
    
    foreach (var item in sys.ActionDescriptors.Items)
    {
        if (item.AttributeRouteInfo is not null)
        {
            Debug.WriteLine($"{item.Id,38}. {item.DisplayName}");
            var ari = item.AttributeRouteInfo;
            Debug.WriteLine($"{ari.Template}");
        }
    }
    

    You'll get things like this from Umbraco itself, umbraco/delivery/api/v{version:apiVersion}/media/item/{path}*

    You should also see your stuff. For my project I got things like this umbraco/backoffice/api/Spero/Product/{id}

    If you don't see any of your APIs listed then you may need to investigate the MapRoute method https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/creating-custom-routes-cs

            routes.MapRoute(
                "Blog",                                           // Route name
                "Archive/{entryDate}",                            // URL with parameters
                new { controller = "Archive", action = "Entry" }  // Parameter defaults
            );
    
  • 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.

Please Sign in or register to post replies