Skip to content

[Bug]: Module content import subtle behavior change affecting portal template import during installation. #6798

@dimarobert

Description

@dimarobert

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

The changes made to support DI in IPortable introduced a subtle behavior change that no longer schedules the module content import to the next startup if there is an error with loading the type.

Steps to reproduce?

  1. Prepare a new website installation using DNN 10.x Install package.
  2. Add some additional 3rd party packages to /Install/Modules/ to be installed during the DNN Installation.
    2.1. The packages should correctly define its supportedFeatures in the desktopModule Module component (see below).
  3. Create a custom portal template that uses such packages and use it to create your first portal.
  4. Proceed with installation using the custom portal template.
  5. The installation will appear successful, and the site will load, but there will be empty (not configured / imported) modules on the pages due to the fact that those modules could not be imported during the same request (AppDomain) that made the installation due to type resolution errors.
<component type="Module">
  <desktopModule>
    <businessControllerClass>Namespace.MyBusinessControllerClass</businessControllerClass>
    <supportedFeatures>
      <supportedFeature type="Portable" />
    </supportedFeatures>
    ...
  </desktopModule>
</component>

Current Behavior

previous ModuleController.GetModuleContent() code:

try
{
    object businessController = Reflection.CreateObject(module.DesktopModule.BusinessControllerClass, module.DesktopModule.BusinessControllerClass);
    var controller = businessController as IPortable;
    if (controller != null)
    {
        var decodedContent = HttpContext.Current.Server.HtmlDecode(content);
        controller.ImportModule(module.ModuleID, decodedContent, version, portal.AdministratorId);
    }
}
catch
{
    // if there is an error then the type cannot be loaded at this time, so add to EventQueue
    EventMessageProcessor.CreateImportModuleMessage(module, content, version, portal.AdministratorId);
}

current code:

try
{
    var controller = businessControllerProvider.GetInstance<IPortable>(module);
    if (controller is not null)
    {
        var decodedContent = WebUtility.HtmlDecode(content);
        controller.ImportModule(module.ModuleID, decodedContent, version, portal.AdministratorId);
    }
}
catch
{
    // if there is an error then the type cannot be loaded at this time, so add to EventQueue
    EventMessageProcessor.CreateImportModuleMessage(module, content, version, portal.AdministratorId);
}

If you notice, in the previous code, the BusinessControllerClass was first created through reflection as object then cast to IPortable and the import skipped if null (e.g. not implementing IPortable), BUT if the creation through reflection failed (due to types not being available and a recycle being needed after installation), then the catch would schedule the import. (Reflection.CreateObject() does not swallow exceptions)

With the new code, the businessControllerProvider.GetInstance<IPortable>(module) will swallow any exceptions (deep in Reflection.CreateType(businessControllerTypeName)) and return null in both cases, type errors and cast to IPortable, which will lead to the module import being skipped altogether.

Expected Behavior

Module content should be correctly imported at the next startup and custom portal templates should be correctly deployed during initial portal creation during installation.

Relevant log output

Anything else?

No response

Affected Versions

10.1.2 (latest v10 release)

What browsers are you seeing the problem on?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions