Developer forum

Forum » Dynamicweb 9.0 Upgrade issues » Using webapi with attribute routing in DW 9

Using webapi with attribute routing in DW 9

Peter Leleulya
Reply

Hello,

 

We have started our first DW project in version 9.2.9, and are trying to use some webapi calls in our project to be able to do some ajax requests in our pages.

I know that DW registers the attribute routing in their own global asax calls from a previous project in DW 8.9, and from the error I get in this DW 9 project when I try to register the attributeroutes myself.

The problem is now that our webapi calls never reach our code, somehow even the most simple attribute route always results in a 404 error.

Has there been a change in DW9 making the use of webapi calls impossible?

 

Example of code that just doesn’t work in DW9 but would work in DW 8.9:

 

using System.Web.Http;

 

namespace Application.WebApi

{

    [RoutePrefix("testapi")]

    public class TestController : ApiController

    {

        [HttpGet]

        [Route("test")]

        public string Test()

        {

            return "Test OK";

        }

    }

}

 

Please let us know what we have to do to get this working again.


Replies

 
Nicolai Pedersen
Reply

Hi Peter

This was a tough nut to crack, hence the long waiting time.

In Dynamicweb 8, the entire frontend is runing in a webform called /Default.aspx using url rewriting to map /someurl/somepage to Default.aspx?ID=123. In Dynamicweb 9 the frontend is now a MVC controller with a default route that handles Default.aspx (that is why it still works with that in the URL) - but all /someurl/somepage urls are handled by this routehandler.

So when you register your own routehandlers they reside alongside our Dynamicweb.Frontend.DynamicwebRouteHandler, and we have some logic that determines if we should display a 404 if the route looks wrong. And Dynamicweb thinks that because it does not recognise your route.

So, working around this can be fixed - we will add a fix for Dynamicweb that will solve this issue for future installations. For now you can fix it by adding a notification subscriber to your solution.

In your solution add a reference to Dynamicweb.Extensibility.dll and create a notification subscriber that looks like this:

[Dynamicweb.Extensibility.Notifications.Subscribe(Dynamicweb.Notifications.Standard.Application.AuthenticateRequest)]
public class HandleRouteNotification : Dynamicweb.Extensibility.Notifications.NotificationSubscriber
{
    public override void OnNotify(string notification, Dynamicweb.Extensibility.Notifications.NotificationArgs args)
    {
        Dynamicweb.Notifications.Standard.Application.AuthenticateRequestArgs myargs = (Dynamicweb.Notifications.Standard.Application.AuthenticateRequestArgs)args;
        System.Web.Routing.RouteData routeData = System.Web.Routing.RouteTable.Routes.GetRouteData(new System.Web.HttpContextWrapper(myargs.Application.Context));
        if (routeData != null && routeData.RouteHandler.ToString() != "Dynamicweb.Frontend.DynamicwebRouteHandler")
        {
            //throw new System.Exception(routeData.RouteHandler.ToString());
            myargs.Handled = true;
        }
    }

    public override int Rank
    {
        get { return base.Rank - 70; }
    }
}

As you can tell, it simply asks Dynamicweb to fuck off if there is any other route handler that knows what to do.

Attached a sample solution with a MVC controller and WEB API controller using attributes and including the above notification subscriber. In IIS the solution is setup using virtual folders to /admin and /files, see dump.

BR Nicolai

Capture.PNG
 
Peter Leleulya
Reply

Thanks for your response Nicolai!

I'll dive into it first thing in the morning!

I don't mind to wait a bit if things are a challenge for you guys, but then please let me know that you are on top of it.

Then I know I can expect some answer in the near future and can communicatie to my team that it is being handled, in stead of telling them that I have no idea if or when I can expect an answer whatsoever.

Have a nice evening!

 
Peter Leleulya
Reply

It seems that routeData in your sample can be null when the url is called from javascript (no context).
I changed the if statement to the following and now I reach my code.

if ((bool)myargs?.Application?.Request?.RawUrl?.StartsWith("/my_webapi_name/")) {  myargs.Handled = true; }

 

You must be logged in to post in the forum