使用 HttpHandlerFactory 渲染 CMS 和物理页面
我正在编写 CMS 系统,在阅读并完成了几个示例后,我决定使用 HttpHandlerFactory 来执行我需要的操作。
关键点是我们的网站通常混合了复制和注册流程。因此,我目前需要使用 aspx 的默认 HttpHandler 来呈现物理注册页面,直到我也能找到一种内容管理它们的方法。
创建处理程序类后,我将以下内容添加到网站的 Web 配置中
<add verb="*" path="*.aspx" type="Web.Helpers.HttpCMSHandlerFactory, Web.Helpers"/>
,由于上述路径处理物理和 cms 驱动的页面,通过对代码进行小检查,我可以查看该页面是否物理存在,然后可以呈现所需的页面。
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string pageName = Path.GetFileNameWithoutExtension(context.Request.PhysicalPath);
context.Items.Add("PageName", pageName);
//DirectoryInfo di = new DirectoryInfo(context.Request.MapPath(context.Request.ApplicationPath));
FileInfo fi = new FileInfo(context.Request.MapPath(context.Request.CurrentExecutionFilePath));
//var file = fi.Where(x => string.Equals(x.Name, string.Concat(pageName, ".aspx"), StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
if (fi.Exists == false)
{
// think I had this the wrong way around, the url should come first with the renderer page second
return PageParser.GetCompiledPageInstance(url, context.Server.MapPath("~/CMSPage.aspx"), context);
}
else
{
return PageParser.GetCompiledPageInstance(context.Request.CurrentExecutionFilePath, fi.FullName, context);
}
}
我的问题是,当存在物理页面时,我是否应该使用 PageParser.GetCompiledPageInstance
以外的其他内容?
更新:如上所述,我继续开发图像的 HttpHandler,它再次遵循相同的原理:如果图像存在,则使用它,否则从数据库提供服务。 png 文件存在一些问题,但以下过程适用于所示的文件格式。
byte[] image = null;
if (File.Exists(context.Request.PhysicalPath))
{
FileStream fs = new FileStream(context.Request.PhysicalPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
image = br.ReadBytes((int)fs.Length);
}
else
{
IKernel kernel = new StandardKernel(new ServiceModule());
var cmsImageService = kernel.Get<IContentManagementService>();
var framework = FrameworkSetup.GetSetFrameworkSettings();
image = cmsImageService.GetImage(Path.GetFileName(context.Request.PhysicalPath), framework.EventId);
}
var contextType = "image/jpg";
var format = ImageFormat.Jpeg;
switch (Path.GetExtension(context.Request.PhysicalPath).ToLower())
{
case ".gif":
contextType = "image/gif";
format = ImageFormat.Gif;
goto default;
case ".jpeg":
case ".jpg":
contextType = "image/jpeg";
format = ImageFormat.Jpeg;
goto default;
case ".png":
contextType = "image/png";
format = ImageFormat.Png;
goto default;
default:
context.Cache.Insert(context.Request.PhysicalPath, image);
context.Response.ContentType = contextType;
context.Response.BinaryWrite(image);
context.Response.Flush();
break;
}
I am in the middle of writing a CMS system and after reading and working through a few examples, I have settled on HttpHandlerFactory to perform what I need.
the key point is our sites are generally a mix of copy and registration processes. So I currently need to use the default HttpHandler for aspx to render the physical registration pages until I can work a way to content manage them too.
after creating the handler class I added the following to my website's web config
<add verb="*" path="*.aspx" type="Web.Helpers.HttpCMSHandlerFactory, Web.Helpers"/>
As the above path handles physical and cms driven pages, with a small check in the code I am able to see if the page physically exists and can then render the desired page.
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string pageName = Path.GetFileNameWithoutExtension(context.Request.PhysicalPath);
context.Items.Add("PageName", pageName);
//DirectoryInfo di = new DirectoryInfo(context.Request.MapPath(context.Request.ApplicationPath));
FileInfo fi = new FileInfo(context.Request.MapPath(context.Request.CurrentExecutionFilePath));
//var file = fi.Where(x => string.Equals(x.Name, string.Concat(pageName, ".aspx"), StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
if (fi.Exists == false)
{
// think I had this the wrong way around, the url should come first with the renderer page second
return PageParser.GetCompiledPageInstance(url, context.Server.MapPath("~/CMSPage.aspx"), context);
}
else
{
return PageParser.GetCompiledPageInstance(context.Request.CurrentExecutionFilePath, fi.FullName, context);
}
}
The question I have is should I be using something other than PageParser.GetCompiledPageInstance
when there is a physical page?
Update: since the above I have gone on to develop and HttpHandler for images, which again works on the same principle of if the image exists use it else serve from database. Had a bit of problem with png files but the below process works for the file formats shown.
byte[] image = null;
if (File.Exists(context.Request.PhysicalPath))
{
FileStream fs = new FileStream(context.Request.PhysicalPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
image = br.ReadBytes((int)fs.Length);
}
else
{
IKernel kernel = new StandardKernel(new ServiceModule());
var cmsImageService = kernel.Get<IContentManagementService>();
var framework = FrameworkSetup.GetSetFrameworkSettings();
image = cmsImageService.GetImage(Path.GetFileName(context.Request.PhysicalPath), framework.EventId);
}
var contextType = "image/jpg";
var format = ImageFormat.Jpeg;
switch (Path.GetExtension(context.Request.PhysicalPath).ToLower())
{
case ".gif":
contextType = "image/gif";
format = ImageFormat.Gif;
goto default;
case ".jpeg":
case ".jpg":
contextType = "image/jpeg";
format = ImageFormat.Jpeg;
goto default;
case ".png":
contextType = "image/png";
format = ImageFormat.Png;
goto default;
default:
context.Cache.Insert(context.Request.PhysicalPath, image);
context.Response.ContentType = contextType;
context.Response.BinaryWrite(image);
context.Response.Flush();
break;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定这是否完全回答了您的问题...我还构建了一个由 HttpHandler 驱动的 ASP.NET CMS,并且它还允许物理 .aspx 页面。由于我只有少量物理 .aspx 文件和位置,管理执行的最简单方法是通过 web.config。
首先,我将网站(一般而言)配置为使用我的处理程序 - 除了登录页面(作为示例):
您可以做的另一件事是通过
location
进行隔离,因此对于这一部分我选择使用开箱即用的 ASP.NET 处理程序,该处理程序通常处理“经典”ASP.NET 请求:I'm not sure if this completely answers your question... I've also built an ASP.NET CMS that was HttpHandler driven, and which also allows for physical .aspx pages. As I only had a small number of physical .aspx files and locations the easiest way to manage execution was via web.config.
Firstly, I configure the website (in general terms) to use my handler - except for the login page (as an example):
The other thing you can do is isolate by
location
, so for this part of the site I'm opting to use the out-of-the-box ASP.NET handler which normally processes "classic" ASP.NET requests: