我可以使用HttpHandler伪造aspx页面的存在吗?

时间:2009-03-23 15:04:15

标签: asp.net

我正在使用ASP.NET 3.5构建一个网站,并且大多数网站结构都是静态的,足以创建文件夹结构和aspx页面。但是,站点管理员希望能够通过Web界面和使用WYSIWYG编辑器将​​新页面添加到站点的不同部分。我正在使用嵌套的母版页为网站的不同部分提供自己的菜单。我想要做的是在网站的每个部分下都有一个通用页面,它使用适当的母版页,并有一个可以从数据库加载的内容的占位符。我也希望这些“假”页面像任何其他aspx页面一样有一个url,就好像它们在服务器上有相应的文件一样。所以不要让我的网址成为:

http://mysite.com/subsection/gerenicconent.aspx?contentid=1234

它会是这样的:

http://mysite.com/subsection/somethingmeaningful.aspx

问题在于somemeaningful.aspx不存在,因为管理员通过Web UI创建了它,并且内容存储在数据库中。我在想的是我将实现一个处理aspx文件请求的HTTP处理程序。在该处理程序中,我将检查所请求的URL是实际文件还是我的“虚假页面”之一。如果它是对虚假页面的请求,我会将请求重新路由到适当部分的通用内容页面,更改查询字符串以从数据库请求适当的数据,并重写URL以使其看起来如此用户好像假页面确实存在。我现在遇到的问题是我无法弄清楚如何将请求路由到aspx页面的默认处理程序。我试图实例化一个PageHandlerFactory,但是constuctor是内部保护的。有没有办法让我告诉我的HttpHandler调用正常用于处理请求的HttpHandler?我的处理程序代码目前如下所示:

using System.Web;
using System.Web.UI;

namespace HandlerTest
{
    public class FakePageHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if(RequestIsForFakedPage(context))
            {
                // reroute the request to the generic page and rewrite the URL
                PageHandlerFactory factory = new PageHandlerFactory(); // this won't compile because the constructor is protected internal
                factory.GetHandler(context, context.Request.RequestType, GetGenericContentPath(context), GetPhysicalApplicationPath(context)).ProcessRequest(context);
            }
            else
            {
                // route the request to the default handler for aspx pages
                PageHandlerFactory factory = new PageHandlerFactory();
                factory.GetHandler(context, context.Request.RequestType, context.Request.Path, context.Request.PhysicalPath).ProcessRequest(context);
            }
        }

        public string RequestForPageIsFaked(HttpContext context)
        {
            // TODO
        }

        public string GetGenericContentPath(HttpContext context)
        {
            // TODO
        }

        public string GetPhysicalApplicationPath(HttpContext context)
        {
            // TODO
        }
    }
}

我还有一些工作要做,以确定请求是否适用于真实页面,我还没有重写任何网址,但是这样的话可能吗?有没有其他方法来创建一个PageHandlerFactory而不是调用它的构造函数?有什么办法可以将请求路由到aspx页面的“普通”HttpHandler吗?我基本上会说“像往常那样处理这个ASPX请求。”

3 个答案:

答案 0 :(得分:3)

如果您使用的是3.5,请使用asp.net路由。

http://msdn.microsoft.com/en-us/library/cc668201.aspx

答案 1 :(得分:2)

最好使用http模块,因为在这种情况下,您可以使用RewritePath方法来路由虚假页面的请求,并且不对实际页面执行任何操作,这样可以正常处理它们。 / p>

这个here有一个很好的解释,它也涵盖了使用IIS 7.0的好处,如果这是你的选择。

答案 2 :(得分:1)

我刚刚从我们刚刚编写的类似系统中删除了它。

此方法负责物理页面和“假”页面。你能够确定这与你的假页面架构是如何相符的,我敢肯定。

public class AspxHttpHandler : IHttpHandlerFactory
{
        #region ~ from IHttpHandlerFactory ~

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {
                    string url=context.Request.Url.AbsolutePath;
            string[] portions = url.Split(new char[] { '/', '\\' });
                    // gives you the path, i presume this will help you identify the section and page
                    string serverSidePage=Path.Combine(context.Server.MapPath("~"),url);
                    if (File.Exists(serverSidePage))
                    {
                             // page is real
                            string virtualPath = context.Request.Url.AbsolutePath;
                string inputFile = context.Server.MapPath(virtualPath);

                try
                {
                                    // if it's real, send in the details to the ASPX compiler
                    return PageParser.GetCompiledPageInstance(virtualPath, inputFile, context);
                }
                catch (Exception ex)
                {
                        throw new ApplicationException("Failed to render physical page", ex);
                }
                      }
                      else
                      {
                            // page is fake
                            // need to identify a page that exists which you can use to compile against
                            // here, it is CMSTaregtPage - it can use a Master
                            string inputFile = context.Server.MapPath("~/CMSTargetPage.aspx");
                string virtualPath = "~/CMSTargetPage.aspx";
                            // you can also add things that the page can access vai the Context.Items collection
                            context.Items.Add("DataItem","123");
                            return PageParser.GetCompiledPageInstance(virtualPath, inputFile, context);
}

public void ReleaseHandler(IHttpHandler handler)
{

}