Developer forum

Forum » Development » Making a custom Web API with Dynamicweb

Making a custom Web API with Dynamicweb

Thomas Berthelsen
Reply

Hello!

I read that it is possible to further develope an API supporting the dynamic web platform. Any further information regarding this, meaning do you have any examples where's you've implemented one or two routes / controllers that will work with a dynamicweb website already? We're primaly interested in getting data from the database, however mapping them to custom returns. What i've found so far get several exception in the Application_Start function in the Global Class. Any help?


Replies

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Thomas,

If you only need to fetch data from the database and don't need any context information, then it's fairly straight forward to implement a WebAPI. All you need a notification subscriber that tells Dynamicweb that you'll handle the specific request and the API controller itself.

The notification subscriber could look something like this. Note that there's a local switch for enabling session state or not. If you need to access information from the Dynamicweb context then you need to enable session state, otherwise you can leave that to false and same a few milliseconds per request.

using Dynamicweb.Extensibility.Notifications;

namespace MyArea.WebApi
{
    [Subscribe(Dynamicweb.Notifications.Standard.Application.AuthenticateRequest)]
    public class WebApiEnabler : NotificationSubscriber
    {
        internal const string RoutePrefix = "api/myarea";
        private const bool EnableSessionState = true;

        public override void OnNotify(string notification, NotificationArgs args)
        {
            var authenticateArgs = args as Dynamicweb.Notifications.Standard.Application.AuthenticateRequestArgs;
            var request = authenticateArgs.Application.Context.Request;
            var isHandled = request.Path.StartsWith($"/{RoutePrefix}");
            if (EnableSessionState && isHandled)
            {
                // Enable session
                System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
            }

            // When this is set to true then Dynamicweb will skip the default handling of the current request
            authenticateArgs.Handled = isHandled;
        }
    }
}

 

For the controller, the only thing you need to be aware of is that you need to use Attribute Routing. Note that the route prefix comes from the WebApiEnabler notification subscriber class.

using System;
using System.Web.Http;

namespace MyArea.WebApi
{
    [RoutePrefix(WebApiEnabler.RoutePrefix + "/data")]
    public class MyAreaDataApiController : ApiController
    {
        [Route("list")]
        public IHttpActionResult GetList()
        {
            // TODO: Add custom logic
            var list = new string[] { };
            return Json(list);
        }
    }
}

 

I hope this helps you to implement your own WebAPI.

- Jeppe

Votes for this answer: 1
 
Thomas Berthelsen
Reply

Hi!

Thanks for help, it really helped a lot.

However i wonder why this solution would not work:

I based it on your implementation of the Dynamicweb.Ecommerce.WebAPI.dll implementation.  

PagesAPIRegistration Class:

 

public class PagesAPIRegistration : APIRegistrationBase
    {
        protected override string ControllerName
        {
            get
            {
                return "Pages";
            }
        }

        protected override List ControllerVersions
        {
            get
            {
                return new List()
                {
                    "PageController"
                };
            }
        }

        protected override string CurrentControllerVersion
        {
            get
            {
                return "PageController";
            }
        }

        public PagesAPIRegistration()
        {

        }
    }

PageController

public class PageController : ApiController
    {

        public PageController()
        {
        }

        [HttpGet]
        public int Get()
        {
            int test = 5;
            return test;
        }


    }
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Thomas,

The APIRegistrationBase class is not actually meant for public consumption. It's present to handle some internal legacy things and unfortunately it has to be public because of the way these types are resolved.

The approach I gave in my initial post is the recommended way of adding WebAPIs to a Dynamicweb solution.

- Jeppe

 
Martin Moen
Reply

Sorry for opening this thread again, but are there any updated code for DW 9.13?
I'm struggling with making this work on new versions.

Anyone got a example project for VS I could have a look at?

 
Mario Santos Dynamicweb Employee
Mario Santos
Reply

Hi Jeppe,

I'm trying to create a custom API for a project. We already have the a .cs file that is working:

namespace Dna.SwiftRizzo.MyLogin.Controllers
{
    [RoutePrefix("dna-api/password")]
    public class PasswordController : ApiController
    {
	[HttpPost]
        [Route("update")]
        public List UpdateRealUserPassword()
        {
            var loginResult = new List();
            // logic
            return loginResult;
        }
    }
}

When I create a new .cs file under the same project with a different route it is not working for me:

namespace Dna.SwiftRizzo.MyLogin.Controllers
{
    [RoutePrefix("dna-api/password2")]
    public class Password2 : ApiController
    {
	[HttpPost]
        [Route("update2")]
        public List UpdateRealUserPassword()
        {
            var loginResult = new List();
            // logic
            return loginResult;
        }
    }
}

These are just samples, but the point is I can access the dna-api/password/update and also create other endpoints there like dna-api/password/xyz but I cannot access the dna-api/password2/update2. Not sure what I am missing, any thoughts?

DW version is 9.12.10.

Thanks,
BR Mario

 
 
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Hi Mario,

You're missing the word Controller on Password2 which prevents it from being a controller:

public class Password2Controller : ApiController

Cheers,

Imar

 
Mario Santos Dynamicweb Employee
Mario Santos
Reply

Wow... I would never guess that! Thanks Imar.

BR Mario

 

You must be logged in to post in the forum