Developer forum

Forum » Dynamicweb 10 » Api controllers

Api controllers

Karol Barkowski
Reply

Hi,

in DW9 it was possible to use this little piece of code that allowed to add custom api controllers to the exisdting DW project:

    [Subscribe(Standard.Application.AuthenticateRequest)]
    public class ApiEnabler : NotificationSubscriber
    {
        public const string RoutePrefix = "api/custom";
        public override void OnNotify(string notification, NotificationArgs args)
        {
            if (args is not Standard.Application.AuthenticateRequestArgs authenticateArgs) return;
            var requestPath = HttpContext.Current.Request.Path;
            var isApiRequest = requestPath.StartsWith($"/{RoutePrefix}");

            if (isApiRequest)
            {
                HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
                authenticateArgs.Handled = true;
                return;
            }
        }
    }

 

Apparently, that doesn't work anymore in DW10 and this notification subscriber is not even triggered anymore.

What is the approach to add an api controller to DW10 project now? 

regards

 

 


Replies

 
Karol Barkowski
Reply

Or maybe same question but asked in a different way - how to tell DW to not intercept a route to my controller and redirect to 404 page?

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Karol,

You can create a pipeline in which you can register controllers, middleware or services. All you need to do is create a class that implements the Dynamicweb.Host.Core.IPipeline interface. This gives you access to the service collection, the application builder and the mvc builder. There are two route prefixes reserved by DynamicWeb, /admin and /dwapi, all other routes can be mapped by you. The last pipeline to execute is the DynamicWeb Frontend, so it will only handle routes that are not explicitly mapped.

This GitHub project has an example where we register a GRPC service: https://github.com/dynamicweb/Summit2022_APILandscape

I hope this helps.

- Jeppe

 
Karol Barkowski
Reply

Hi,

that repo you linked not only doesn't show how to use that IPipeline interface but it literally has nothing to do with DynamicWeb itself.
I looked at the docs and there's also nothing about IPipeline interface and how it could be used.
Are there any live examples where it is actually shown how to use that interface in DW project?

 

   
Jonas Friedrich
Reply

Hi,

we've tried to follow this, and it works just as expected locally:
ConfigurePipieline.cs:

    public void RegisterApplicationComponents(IApplicationBuilder app)
    {
        var loggingService = app.ApplicationServices.GetRequiredService<GlobalLoggingLevelService>();
        loggingService.SetGlobalLoggingLevelFromSettings();
 
        app.MapWhen(
            context => context.Request.Path.StartsWithSegments("/hello-world"),
            appBranch =>
            {
                appBranch.UseRouting();
                appBranch.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            });
    }


HelloWorldController.cs:

[Route("/hello-world")]
[ApiController]
public class HelloWorldController : ControllerBase
{
    public HelloWorldController()
    {
    }
 
    [HttpGet("")]
    public IActionResult Get(string exampleParam)
    {
        return Content("<h1>Hello World</h1>", "text/html");
    }
}

 

However, on staging we get a 404 when we request /hello-world or /hello-world?exampleParam=test .What is interesting is that we get an "empty" 404 without the default 404 template.
I hope it's something obvious that we overlooked, would appreciate any clues :-)

edit: sorry for the formatting, it looks correct when editing so I can't fix it

 

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Hi

You might want to use a Dynamicweb iPipeline to register a custom controller:

https://doc.dynamicweb.dev/documentation/extending/middleware/index.html#implementation-example---custom-web-api

Why your implementation might not work:

Your local environment likely runs with UseRouting() and UseEndpoints() already defined in your startup pipeline before your MapWhen branch executes. When you call app.MapWhen(...), you create a new branch with its own middleware pipeline, but it doesn’t inherit all middleware from the main one — it starts fresh.
Inside the branch, you correctly call UseRouting() and UseEndpoints(), so the controller mapping works there. Locally, ASP.NET Core probably runs in a configuration where that’s fine — the order of execution or registration may differ slightly (e.g. app.UseDeveloperExceptionPage() being added).

Try adding a simple middleware at the start of your MapWhen block:

appBranch.Run(async context => { await context.Response.WriteAsync("Matched branch"); });

If you still get an empty 404, the branch isn’t matched. That confirms a path mismatch or proxy prefix issue.

If it does hit, then remove it and add this just before UseEndpoints():

appBranch.Use(async (ctx, next) => { Console.WriteLine("Inside /hello-world branch"); await next(); });

If this never logs, routing never triggers inside that branch.

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Jonas,

Just to confirm. Did you perform a recycle of the solution after you installed your addin? https://doc.dynamicweb.dev/documentation/fundamentals/setup/hosting/dynamicweb-cloud.html#how-to-recycle-the-application

Addins containing controllers and middleware require a restart to be enabled.

- Jeppe

 

You must be logged in to post in the forum