【发布时间】:2011-12-15 08:53:15
【问题描述】:
背景:我必须附加查询字符串值,从对网站的初始调用(对于每个用户来说都是唯一的)到每个后续页面调用上的每个内部链接,以便在他们访问网站的其余时间保留跟踪信息分析。我在 Session_Start 期间将这些值存储在 Global.asax 中的 Session 对象中。我创建了一个自定义 Page 对象,它覆盖 CreateHtmlTextWriter 以提供一个自定义 HtmlTextWriter 对象,该对象覆盖了所有公共 AddAttribute 和 WriteAttribute 方法,这些方法检查名称/键是否为“href”,如果是,则附加附加查询字符串渲染过程中值对象的参数。这适用于通过 ASP.NET 控件生成的链接,即超链接,例如:
<asp:HyperLink BackColor="Red" ID="link" runat="server" NavigateUrl="http://www.google.com/" Text="Google" />
但如果只是写了就不起作用:
<a href="http://www.yahoo.com/">Yahoo</a>
直接在aspx页面中。来自 aspx 页面的 HTML 是通过 HtmlTextWriter 的哪一部分进行渲染的?
我正在包含我的代码文件,用于我正在尝试开始工作的概念证明(不会尝试识别链接是内部的还是外部的,这将在以后使用)[这是使用 Webforms 构建的, .NET Framework 3.5 和 C#]:
默认.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestRenderOverride._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:HyperLink BackColor="Red" ID="link" runat="server" NavigateUrl="http://www.google.com/" Text="Google" />
<br />
<a href="http://www.yahoo.com/">Yahoo</a>
</div>
</form>
</body>
</html>
Default.aspx.cs(包括自定义 Page 类和自定义 HtmlTextWriter 类):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
namespace TestRenderOverride
{
public partial class _Default : CustomPage
{
protected void Page_Load(object sender, EventArgs e)
{
HyperLink hl = new HyperLink();
}
}
public class CustomPage : System.Web.UI.Page
{
protected override HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
{
return new CustomHtmlTextWriter(HttpContext.Current, tw);
}
}
public class CustomHtmlTextWriter : HtmlTextWriter
{
private string UTM_A;
private string UTM_B;
public CustomHtmlTextWriter(HttpContext context, TextWriter writer) : base(writer)
{
if (context.Session["Protected_UTM-A"] != null)
{
UTM_A = context.Session["Protected_UTM-A"].ToString();
}
if (context.Session["Protected_UTM-B"] != null)
{
UTM_B = context.Session["Protected_UTM-B"].ToString();
}
}
public CustomHtmlTextWriter(HttpRequest request, TextWriter writer, string tabString)
: base(writer, tabString)
{
}
private string AppendCustomQueryString(string value)
{
if (HasQueryStringValues())
{
if (value.Contains('?'))
{
return value + "&" + BuildQueryStringAddition();
}
else
{
return value + "?" + BuildQueryStringAddition();
}
}
else
{
return value;
}
}
private string BuildQueryStringAddition()
{
string returnValue = String.Empty;
if (!String.IsNullOrEmpty(UTM_A))
{
returnValue = "UTM_A=" + UTM_A;
}
if (!String.IsNullOrEmpty(UTM_B))
{
if (!String.IsNullOrEmpty(returnValue))
{
returnValue += "&UTM_B=" + UTM_B;
}
else
{
returnValue = "UTM_B=" + UTM_B;
}
}
return returnValue;
}
private bool HasQueryStringValues()
{
if (!String.IsNullOrEmpty(UTM_A) || !String.IsNullOrEmpty(UTM_B))
{
return true;
}
return false;
}
public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
if (key == HtmlTextWriterAttribute.Href)
{
value = AppendCustomQueryString(value);
}
base.AddAttribute(key, value);
}
public override void AddAttribute(string name, string value)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.AddAttribute(name, value);
}
public override void AddAttribute(HtmlTextWriterAttribute key, string value, bool fEncode)
{
if (key == HtmlTextWriterAttribute.Href)
{
value = AppendCustomQueryString(value);
}
base.AddAttribute(key, value, fEncode);
}
public override void AddAttribute(string name, string value, bool fEndode)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.AddAttribute(name, value, fEndode);
}
protected override void AddAttribute(string name, string value, HtmlTextWriterAttribute key)
{
if ((name.ToLowerInvariant() == "href") || (key == HtmlTextWriterAttribute.Href))
{
value = AppendCustomQueryString(value);
}
base.AddAttribute(name, value, key);
}
public override void WriteAttribute(string name, string value)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.WriteAttribute(name, value);
}
public override void WriteAttribute(string name, string value, bool fEncode)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.WriteAttribute(name, value, fEncode);
}
public override void WriteStyleAttribute(string name, string value)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.WriteAttribute(name, value);
}
public override void WriteStyleAttribute(string name, string value, bool fEncode)
{
if (name.ToLowerInvariant() == "href")
{
value = AppendCustomQueryString(value);
}
base.WriteAttribute(name, value, fEncode);
}
}
}
全球.asax:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace TestRenderOverride
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
if (Request.QueryString["UTM_A"] != null)
{
Session["Protected_UTM-A"] = Request.QueryString["UTM_A"].ToString();
}
if (Request.QueryString["UTM_B"] != null)
{
Session["Protected_UTM-B"] = Request.QueryString["UTM_B"].ToString();
}
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
这是在您运行代码并将 Web 项目的起始页设置为“特定页面”时呈现的源代码,值为“Default.aspx?UTM_A=Georgia&UTM_B=Maryland”:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx?UTM_A=Georgia&UTM_B=Maryland" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzU0OTY1Mjk1ZGRbJc0Q8nWuQUZrihiKtbAzs/+VPA==" />
</div>
<div>
<a id="link" href="http://www.google.com/?UTM_A=Georgia&UTM_B=Maryland" style="background-color:Red;">Google</a>
<br />
<a href="http://www.yahoo.com/">Yahoo</a>
</div>
</form>
</body>
</html>
【问题讨论】: