DNN 模块使用的路由被忽略,因为请求 URL 被友好的 URL 提供商拦截

Route used by DNN module being ignored because request URL intercepted by friendly URL provider

我创建了一个自定义 DNN 模块,它使用路由来实现某些功能。

我用以下模式注册了一条路由:Data/{table}/{action}.aspx(我使用 class 实现 DNN 的 IServiceRouteMapper,它有一个名为 RegisterRoutes 的方法当 DNN 启动时)。

路由注册成功,可以在每次页面请求的RouteTable中看到。

但是,每个应与路由匹配的请求都会导致 DNN 显示其 404 错误页面。换句话说,DNN 似乎决定请求 URL 应该匹配 DNN 页面,但实际上没有。

如果我将友好的 URL 提供程序配置从 urlFormat="advanced" 更改为 urlFormat="searchfriendly",那么路由会成功。

我的结论是 DNN 友好 URL 提供程序(作为 HTTP 模块实现)首先拦截请求(即在路由匹配开始之前),并且在 "advanced" 模式下假定它是一个页面 URL,然后尝试在 CMS 中找到匹配的页面,但失败了。然而,在 "searchfriendly" 模式下,它会放任自流,因此路由匹配可以查看请求。

我想让友好的 URL 提供商保持 "advanced" 模式(因为 URL 更干净)。我还想找到一些不涉及的简单解决方案,例如编写我自己的友好 URL 提供商!

在 web.config 中,URL 路由似乎在友好的 URL 提供程序之前的管道中,所以我很困惑为什么会发生上述情况:

<modules runAllManagedModulesForAllRequests="true">
  <remove name="UrlRoutingModule-4.0" />
  <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler" />
  <add name="RequestFilter" type="DotNetNuke.HttpModules.RequestFilter.RequestFilterModule, DotNetNuke.HttpModules" preCondition="managedHandler" />
  <add name="UrlRewrite" type="DotNetNuke.HttpModules.UrlRewriteModule, DotNetNuke.HttpModules" preCondition="managedHandler" />

编辑:根据要求添加 IServiceRouteMapper 实现,即路由注册的位置。 Navigator.SiteRootFolder 是 returns "Data".

的常量
public void RegisterRoutes(IMapRoute mapRouteManager)
{
    // This method is called automatically by DNN on startup
    RegisterRoutes(RouteTable.Routes);
}

private static void RegisterRoutes(RouteCollection routes)
{
    if (Global.CanCreateDataContext())
    {
        Global.MetaModel.RegisterContext(
            new EFDataModelProvider(() => Global.CreateDataContext(Global.Context.DataContextAssemblyLocation)),
            new ContextConfiguration { ScaffoldAllTables = Global.Context.ScaffoldAllTables });

        Global.MetaModel.DynamicDataFolderVirtualPath = string.Format("~/{0}/DynamicData", Navigator.SiteRootFolder);

        routes.Add(
            new DynamicDataRoute(string.Format("{0}/{{table}}/{{action}}.aspx", Navigator.SiteRootFolder))
            {
                Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),
                Model = Global.MetaModel
            });
    }
}

这确实是一种在 DNN 中创建服务的非标准方式。通常你会使用一个简单的路由映射器来实现 DotNetNuke.Web.Api.IServiceRouteMapper 像这样:

public class ServiceRouteMapper : IServiceRouteMapper
{   public void RegisterRoutes(IMapRoute mapRouteManager)
    {
        mapRouteManager.MapHttpRoute(
            moduleFolderName: "MyModule",
            routeName: "default", 
            url: "{controller}/{action}",
            namespaces: new[] { "MyCompany.Dnn.MyModule.Controllers" });
    }
}

这将导致以下路线:

/DesktopModules/MyModule/Api/Data/List(假设您有一个名为 "DataController" 的控制器 class 和一个名为 "list".

的方法

这不会干扰 DNN 的友好 Url 提供程序的原因是因为“/DesktopModules”是被 Url 提供程序忽略的保留路径。

现在,如果您坚持拥有完全自定义的路由,您可以向 Url 提供程序添加一个路径忽略。为此,您需要在 HostSettings table 中添加(或更新,如果存在)一条记录,其中 SettingName = "AUM_DoNotRewriteRegEx"。下面是一个示例脚本,可以将路径“/Data”添加到忽略列表。

IF NOT EXISTS (SELECT * FROM HostSettings WHERE SettingName = 'AUM_DoNotRewriteRegEx' )
BEGIN
    INSERT INTO HostSettings (SettingName, SettingValue, SettingIsSecure, CreatedByUserId, CreatedOnDate, LastModifiedByUserId, LastModifiedOnDate)
    VALUES('AUM_DoNotRewriteRegEx','/DesktopModules/|/Providers|/LinkClick\.aspx|/Data', 0, -1, GETDATE(), -1, GETDATE())
END
ELSE
BEGIN
    UPDATE HostSettings SET SettingValue = (select SettingValue + '|/Data' from HostSettings where settingname = 'AUM_DoNotRewriteRegEx')
    where SettingName = 'AUM_DoNotRewriteRegEx'
END