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.
List the steps to reproduce the behavior:



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."}
This should work
The solution is fairly simple, I believe @ahoefling should be able to confirm this.
The solution is to correct the code in the DnnHttpControllerActivator in DotNetNuke.Web. Here's the fix:
```c#
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);
}
}
}
```
I reviewed the problem and the submitted Pull Request and left notes on the Pull Request. I politely disagree with the change and do not think that DNN should be responsible for managed generated code in this fashion. It will also prevent generated code from leveraging Dependency Injection which defeats the point of the original change.
Take a look at my review
https://github.com/dnnsoftware/Dnn.Platform/pull/3046#pullrequestreview-295980423
@iJungleboy Can you provide us a snippet/example of how you are using this in code? Just trying to get an understanding of the downstream implications, as the use-case isn't exactly clear.
@ahoefling I addressed your concerns in the pull request. I really believe this is extremely important, as it's just like aspx or theme pages - you also don't need to compile those before running DNN. This is the same just for WebApis
@mitchelsellers sure.
2sxc allows users to easily create schema/data/template/code packages to basically build anything.
In the trivial case - which many people are familiar with - people create schemas and some template pages to show that data. This is not what we're addressing here.
When people use 2sxc to create a SPA, they often need more capabilities than provided by the simple REST. For example, they may want to have custom code running on certain calls etc. This kind of API is created using source files (.cs) in the /api folder in 2sxc. This is the use case we're talking about. And it's also the case mentioned above with the angular 8 template application which only breaks on DNN 9.4.
2sxc is also often used for custom forms, like https://github.com/2sic/app-mobius-forms. Such forms can be customized indefinitely, incl. what happens on saving. But this is only possible because the save-code is freely editable in the background.
Basically many advanced 2sxc apps use WebApi. Maybe to get some statistics, to make some changes, custom save-routines, or just for some special AJAX.
All this much more flexible and faster than with building DLLs, since the server never restarts and the distribution of the App is also much simpler, as 2sxc apps can easily be exported/imported without any problems. So this functionality is absolutely essential. Breaking it would severely limit 2sxc.
A short video explaining it more https://www.screencast.com/t/WQibFL6yx4on
First things first:
I'm sure there's a good reason for this update and this specific change (I honestly don't understand a single thing you discuss in the pull request), but I do know that perhaps this change needs to be more reflected on the consequences we now know.
I suggest 9.4.2 (or a quick 9.4.1.1) to revert the change or temporarily accept the suggested fix until this issue can be properly accessed.
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.
@mitchelsellers thanks for prioritizing this and reviewing it with the releasers :). I'll be on vacation starting in a few hours, so I will be offline for a week - sorry about that.
Closing this request, as the change does not align with the patterns & practices recommendations for the long-term planning and growth of the DNN Platform. All standard development practices are possible with the existing implementation. For the specific impact to 2sxc, the vendor will need to work around this limitation that is in place for standards and security, a possible solution for this has been included earlier in the communication chain on this pull request.
@iJungleboy I'm emailing you directly on this as well.
Is it out of question to postpone this change (or reverse it temporarily) further into DNN later developments, so that extention developers have time to adapt?
@eXistenZe This was in a RC for more than 3 months, and others are already using it, we cannot reverse it at this time
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.
Ok. I have a working server on my home pc. Guess I can start testing beta versions.
Is it a paid job (beta testing)? :)
@eXistenZe I know it is a bit tongue in cheek with your comment, but NONE of us are paid for the work that is done for DNN Platform. It鈥檚 all volunteer
Don't know what that means, but I was kidding. Both DNN and 2sxc are free, so it's only fair to contribute.
@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!
@valadas BTW I don't really agree - my fix doesn't break anything, because it's only applied when the DNN 9.4 mechanism fails (returns null). Otherwise my fix doesn't do anything. So I can't see it breaking anything in production, as it only changes the behavior if something is broken.
@ijungleboy. We emailed you directly about why no
can we also be updated if a solution to this problem has been found?
@Scippy there was a new release of 2sxc that addressed this issue.
Most helpful comment
@eXistenZe This was in a RC for more than 3 months, and others are already using it, we cannot reverse it at this time