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
我创建了一个自定义 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