CSS 变量
使用 HTTPHandlers 支持动态 CSS。
引言
用户希望访问的网站具有灵活性;他们希望定义他们看到的内容以及内容的显示方式。网站开发者希望赋予他们这种能力,但需要将其与可维护性相平衡。使用层叠样式表 (CSS),开发者可以指定某些基本布局或主题,并允许用户在运行时更改这些布局或主题。但是,为所有可能性创建单独的文件是不合理的。更好的方法是在运行时根据用户指定的设置更改某些 CSS 值,但 CSS 并没有可以在运行时评估的变量。
解决方案
为了解决 CSS 中没有变量的问题,必须在运行时读取 CSS 文件并替换给定的值。好消息是,在 ASP.NET 中,这是一项相对简单的任务。
body
{
background-color:#BG_COLOR#
}
通用 HTTPHandler
使用 Visual Studio 2005,您可以轻松添加一个通用 HTTPHandler。
这将创建一个 ashx 文件并将其添加到您的项目中。该文件实现了 IHTTPHandler
接口,只有一个方法 ProcessRequest
,并包含 WebHandler
页面指令。
<%@ WebHandler Language="C#" Class="Handler" %>
.NET Framework 将这些文件视为 HTTPHandlers,无需在 web.config 文件的 <httpHandlers>
部分中注册它们。
<%@ WebHandler Language="C#" Class="CSSHandler" %>
代码隐藏部分
using System;
using System.Web;
using System.Configuration;
public class CSSHandler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/css";
// Get the file from the query stirng
string File = context.Request.QueryString["file"];
// Find the actual path
string Path = context.Server.MapPath(File);
//Limit to only css files
if(System.IO.Path.GetExtension(Path) != ".css")
context.Response.End();
//Make sure file exists
if(!System.IO.File.Exists(Path))
context.Response.End();
// Open the file, read the contents and replace the variables
using( System.IO.StreamReader css = new System.IO.StreamReader(Path) )
{
string CSS = css.ReadToEnd();
CSS = CSS.Replace("#BG_COLOR#",
ConfigurationManager.AppSettings["BGColor"]);
context.Response.Write(CSS);
}
}
public bool IsReusable
{
get { return false; }
}
}
正如我们所见,ProcessRequest
方法只是打开查询字符串中指定的文件,读取它,并使用字符串替换来添加在 web.config 文件中指定的变量的值。这很简单。
<link rel="Stylesheet" href="CSSHandler.ashx?file=default.css" />
<appSettings>
<add key="BGColor" value="Red"/>
</appSettings>
限制
使用通用 webhandler 的缺点是必须指定要解析的样式表。但是,当使用 ASP.NET 2.0 主题时,这会破坏,因为放置在主题文件夹中的任何样式表都会自动链接,无需手动将其添加到您的网页中。虽然您可以手动添加每个样式表,但这并不是一个非常可维护的模型。
更好的解决方案
更好的解决方案是创建一个自定义 HTTPHandler 并将其添加到 web.config 文件的 httpHandlers
部分。
<httpHandlers>
<add verb="*" path="*.css"
type="CustomHandler.CSSHandler, CustomHandler"/>
</httpHandlers>
代码
public class CSSHandler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(System.Web.HttpContext context)
{
// Get the physical path of the file being processed
string File = context.Request.PhysicalPath;
// Open the file, read the contents and replace the variables
using(System.IO.StreamReader reader = new System.IO.StreamReader(File))
{
string CSS = reader.ReadToEnd();
CSS = CSS.Replace("#BG_COLOR#",
ConfigurationManager.AppSettings["BGColor"]);
context.Response.Write(CSS);
}
}
#endregion
}
与前面的示例唯一的区别是,要解析的 CSS 文件是从 context.Request.PhysicalPath
属性获取的。由于该处理程序已注册用于 CSS 文件,因此它将处理 Web 项目中任何位置的任何样式表文件。
结论
希望本文已经展示了一种可以用于为静态文件提供动态设置的方法,并为网站用户提供更积极的体验。