ASP.Net C# 路由; HttpHandler;并且 HttpModule 不工作
我在自定义扩展和拦截现有处理程序方面遇到了很多问题。
我想做什么
基于持久选项,我希望所有“虚拟”扩展都由设置处理程序处理。所有页面都是动态构建的,站点上不存在实际文件。该站点填充内容、形成 html 输出并将其作为 Web 结果返回。 这是必需的,因为我正在两台服务器之间建立胖/瘦关系。瘦服务器将简单地将请求传递给胖服务器,在胖服务器上处理请求并发出响应。 该项目是一个动态的多域内容管理系统。瘦服务器可能不兼容 .net(因此需要外部请求),但将针对 .net 进行优化(因此需要处理程序)。
问题
我想要的是重新路由现有的扩展 - aspx; php; html。 我已经在本地环境中使用自定义 HttpModule 实现了这一点,该模块设置了适当的处理程序。我已经探索过在配置中设置标签,但是扩展是使用持久的动态规则重新路由的。
如前所述,该解决方案适用于本地主机。 上传后,模块会正确处理 .Net 扩展,但任何自定义扩展或非 .net 扩展都会返回 404 错误。
为了寻求替代方案,我尝试了全局内的路由,但这也不起作用。
我还尝试使用注册自定义扩展...但每个扩展都遇到相同的结果 - 404 未找到。
全局路由尝试:
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route("{action}.sqs", new SqlRequestHandler()));
}
.Config(用于处理程序和模块尝试)
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime requestValidationMode="2.0" />
<customErrors mode="Off"/>
<httpHandlers>
<add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
<add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
</httpHandlers>
<httpModules>
<add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
</httpModules>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<modules>
<add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
</modules>
<handlers>
<add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqsHandler" />
<add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqlHandler" />
</handlers>
</system.webServer>
自定义模块(CmsMapper.VirtualModule)
if (extentionMap != null)
{
// note that extentionMap.ExtentionType is a predetermined enum
switch (extentionMap.ExtentionType)
{
// If the extention is banned then pass back a generic message
case ExtentionType.Banned:
this.WriteTextResponce("Invalid extention detected:" + extentionMap.Extention);
break;
// Remap .Ajax requests to the ajax handler
case ExtentionType.Ajax:
this._app.Context.RemapHandler(new AjaxHandler());
break;
// Remap session query or sql requests to the sql handler
case ExtentionType.SessionQuery:
this._app.Context.RemapHandler(new SqlRequestHandler());
break;
// if the extention is not ignored, re map to the virtual page handler
default:
bool isManagementServer = this._app.Context.Request.Url.Authority != VirtualModule.RESPONSE_SERVER;
bool isPostRequest = !String.IsNullOrEmpty(this._app.Context.Request.Form[HtmlRequest.RequestOrigin]);
bool isGetRequest = !String.IsNullOrEmpty(this._app.Context.Request.QueryString[HtmlRequest.RequestOrigin]);
bool isIgnored = extentionMap.ExtentionType == ExtentionType.Ignore;
if ((isPostRequest || isGetRequest) && !isIgnored)
{
this._app.Context.RemapHandler(new VirtualHandler());
}
else
{
this._app.Context.RemapHandler(new ExternalRequestHandler());
}
break;
}
}
所有处理程序都非常标准地实现以下功能:
public class SqlRequestHandler : IHttpHandler, IRequiresSessionState, IRouteHandler
同样,首选方法 - HttpModule - 在我的本地主机上工作。这可能是服务器配置问题(在这种情况下,我正在寻找解决方法),但处理 .net 扩展的事实很奇怪 - 因为这意味着中等信任的问题不应该适用,但是问题关于服务器上的扩展处理可能优先于 .net 应用程序。
服务器是共享托管(因此我无法更改 machine.config 文件),是使用 4.0 的 IIS6。
感谢您提供有关如何解决此问题的任何建议。 麦克风
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要在 IIS 6.0 中配置网站以路由所有扩展(包括称为 通配符扩展映射)到 ASP.NET ISAPI dll(并禁用文件存在检查)。
当然,您可以有选择地仅对那些想要通过 ASP.NET 代码路由的扩展进行此映射。但如果您没有预定义的扩展集,通配符映射会更有用。
如果没有这样的映射,IIS 不会将未知扩展名的请求转发到 ASP.NET(并且路由代码甚至不会出现) - 相反,IIS 会将扩展名传递给默认(静态文件)处理程序,该处理程序将发出 404 if file不存在。
请参阅描述这些步骤的这篇文章(适用于 ASP.NET MVC,但这同样适用于您的情况):http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
在文章接近尾声时,作者给出了如何添加通配符脚本映射
You need to configure web site in IIS 6.0 to route all extensions (including extensionless paths known as wildcard extension mapping) to ASP.NET ISAPI dll (and disable the check for file exists).
You can of course do this mapping selectively only for those extensions that you want to route via ASP.NET code. But wildcard mapping will be more useful in case you don't have predefined set of extensions.
In the absence of such mappings, IIS will not forward requests for unknown extensions to ASP.NET (and routing code will not even come into picture) - rather IIS will pass the extension to default (static file) handler that will issue 404 if file is not present.
See this article that describes these steps (for ASP.NET MVC but the same applies to your case): http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
Near the end of article, author has given how to add wildcard script map