Dnn.Platform: Dynamically compiled Web APIs don't resolve since DNN 9.4
Description of bug
When a system has WebApi controllers which are compiled dynamically - in our case 2sxc Apps can include .cs files which are compiled on the fly - they must be given to the .net framework for activation. This worked well till DNN 9.4, which accidentally broke this functionality because DNN 9.4 replaced the IHttpControllerActivator.
I already found out how to fix this.
Steps to reproduce
List the steps to reproduce the behavior:
- Create a DNN 9.2 and a 9.4.x and install 2sxc on both
- Add an app-module (2sxc) to a page and install the angular demo app from https://2sxc.org/en/apps/app/tutorial-angular-8
- In the UI, click on the WebAPI demo
- As you can see, it works in <9.4 and fails in 9.4.x
Result in Pre 9.4

Result in 9.4

Result in 9.4 with fix applied

Current result
In 9.4 the WebApi calls fail with this message:
{"Message":"No HTTP resource was found that matches the request URI 'http://dnn940rc1raw2.dnndev.me/API/2sxc/app/auto/live/api/simple/hello'.","MessageDetail":"No controller was created to handle this request."}
Expected result
This should work
Additional context
The solution is fairly simple, I believe @ahoefling should be able to confirm this.
Affected version
- 9.4.1 nightly build
- 9.4.0 latest supported release
- 9.2 (not affected)
Affected browser
- all
Solution
The solution is to correct the code in the DnnHttpControllerActivator in DotNetNuke.Web. Here’s the fix:
using DotNetNuke.Common;
using System;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using Microsoft.Extensions.DependencyInjection;
namespace DotNetNuke.Web.Api
{
public class DnnHttpControllerActivator : IHttpControllerActivator
{
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
// first try to just get it from the DI - if it's there
return (IHttpController) Globals.DependencyProvider.GetService(controllerType) ??
// If it's not found (null), then it's probably a dynamically compiled type from a .cs file or similar
// Such types are never registered in the DI catalog, as they may change on-the-fly.
// In this case we must use ActivatorUtilities, which will create the object and if it expects
// any DI parameters, they will come from the DependencyInjection as should be best practice
(IHttpController) ActivatorUtilities.CreateInstance(Globals.DependencyProvider, controllerType);
}
}
}
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 11
- Comments: 19 (14 by maintainers)
Commits related to this issue
- Fix issue with dynamic web api controllers https://github.com/dnnsoftware/Dnn.Platform/issues/3045 — committed to 2sic/Dnn.Platform by iJungleboy 5 years ago
@eXistenZe This was in a RC for more than 3 months, and others are already using it, we cannot reverse it at this time
@mitchelsellers & @valadas could you point me in the direction how dynamically compiled webapis would be done according to the mentioned best practices? The solution we had was IMHO best practice and I simply don’t know a better way. Many thanks!
I agree with this decision, 9.4.0 is a feature release and this is a feature that was added with extensive documentation, examples, blog posts, etc. There was a good effort done to verify this was not a breaking change for all the module pipelines and good overall awareness for anyone to point out issue with this before it has been released for 3 months. So at this point in time and because any developer could already be using it, we cannot revert this now.
We are meeting on this later this week, there is a lot more to this than appears.
Also, this was not mentioned at all during the almost 3 months of Release Candidates. But regardless we will address this, in some manner, ASAP.
A short video explaining it more https://www.screencast.com/t/WQibFL6yx4on