站点指南:一个. NET 实现cookie导航的实现

分享于 

20分钟阅读

Web开发

  繁體

Sample Image - sitecompass.gif

介绍

虽然Cookie的导航可以能不熟悉你,但是你几乎在互联网上看到的几乎所有的东西。 没有它,成千上万的用户会在成千上万的网站上迷失起来。 事实上,代码项目本身使用类似的。 查看任何文章的顶部,你将看到如下所示的内容:


All Topics, C#,. NET>> C# Control>> Beginners



基本概念非常简单: 当用户浏览站点时,会显示以前访问过的页的列表。 这允许用户轻松回到他们以前访问过的页面。

有许多实现这个想法的方法。 代码项目版本使用硬编码值,并假定用户遵循了项目的特定路径。 本文使用 ASP.NET 会话数据和一个Web自定义控件来跟踪用户到达页面的实际路径。

一切都开始了

这个项目最初开始作为一个下午,在这里创建一个 ASP.NET-based web自定义控件,以下的MSDN文章:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbwlkwalkthroughcreatingcustomwebcontrols.asp

几个下午,项目变成了可以在现实世界中使用的东西,所以我决定把它作为我的第一个代码项目项目发布。

演示项目

如果你想要快速起跑和跑步,并回到技术上的硬盘,这就是你需要做的事情:

  • 下载演示项目。
  • 将zip文件的内容解压缩到你的IIS web root。
  • 在IIS管理器中,将SiteCompassTest目录设置为具有应用程序名称。
  • 启动浏览器到 http://yourserver/SiteCompassTest/WebForm1.aspx.
  • 点击链接查看站点指南针完成它的事情。

使用站点指南进行开发

将控件添加到 Visual Studio

将控件添加到网页非常简单。 在 VS.NET, 中,你可以只使用添加/删除工具箱项,并选择控制文件的DLL。 控件将出现在工具箱中,你可以将它的添加到页中。

控件属性

用于控制站点指南针显示方式的AppearanceProperties。

CompassStyle
HorizonatalHTML - 生成传统的水平样式跟踪
VerticalHTML - 生成垂直列表跟踪
DHTMLMenu - 使用DHTML菜单。

如果选择DHTMLMenu选项,则必须手动在HEAD区域中添加对javascript的引用,如下所示:


<script src="siteCompassDHTML.js" type="text/javascript"></script>



CssClass
在呈现时,站点指南符包含在DIV标记中。 这里属性指示用于这里DIV的CSS类的NAME。 项目中有 5个示例CSS类。 这不适用于DHTML菜单指南针样式。

CssClassLink
这表示要用于站点指南的链接的CSS类的NAME。 这不适用于DHTML菜单指南针样式。

CurrentPageIndicator
这是针对当前页面显示的指示符。 在演示项目中我使用 *.

ItemSeperator
这是指南针项之间的分隔符。

PostFixCode
这是你想要在关闭DIV标记之前添加的任何html代码或者文本。 这是用锚标记括起来的。

PreFixCode
这是你想要在打开DIV标记之后立即添加的任何html代码或者文本。 这是用锚标记括起来的。

BehaviourGeneral行为属性

CaseSensitiveUrlComparison
当呈现站点指南针时,它会根据会话中已经存在的项目检查当前页面项值。 如果找到 MATCH,则移除该之后的所有项。 如果将控件设置为比较大小写,则 page1.htm 和 page1.htm 将被视为不同的页。

DivName
这是分配给包含站点指南的DIV的NAME 属性。 如果你想使用Javascript引用它,这可能很有用。

LinkLastItem
这表示指南针中最后一个条目是否为href链接。

MaxItems
这表示在站点指南中显示的最大项目数。 如果项的总数超过此值,则隐藏第一个项。 如果用户后退轨道,则旧项目将重新出现。

模式
正常- 渲染正常的站点指南针。
DisplayOnly - 不将当前页面添加到指南针,只是显示当前会话中的内容

OverrideTarget
这允许你用这个方法覆盖所有罗盘项目的目标属性。

SuppressIcons
允许你禁止显示任何指南针项图标。

Compass项PropertiesThis是存储在会话中的信息

DisplayTitle
要在 Site Compass中显示的文本,请参考这里网页。

IconAlt
指南针项 icon的替代文本属性。

IconPath
指南针项 icon 图像的根相对路径。

LinkTarget
指南针项链接的目标。

其他属性

SessionKey
这是识别驱动SiteCompass的会话数据的唯一键。 使用这个属性,可以在一个页面上有多个指南符,所有跟踪不同的things--as长度不同。

CSS

源文件和演示文件都带有一个CSS文件来驱动控件。 这里样式表有两个组件:

  • DIV和HREF链接样式
  • DHTML菜单样式

你可以使用这些风格对你的心心内容,但是当玩"有趣"菜单样式时要小心。 ( 请参阅文章底部的信用链接有关这里菜单的更多信息。) 如果选择不使用DHTML菜单。

生成样式时需要考虑的另一件事情是控件包含了用户访问过的一系列链接。 所以这部分是无用的:


A.YourLinkStyleName:link


{


 TEXT-DECORATION : none;


 COLOR : aqua;


}



如果需要,可以通过向ASPX页面中添加以下代码向页面添加样式表


<link title="errata" media="screen" href="StyleSheet1.css" type="text/css" rel="stylesheet">



public 函数

public void GenerateCompass_HTML(HtmlTextWriter output, bool designer )
public void GenerateCompass_DHTMLMenu(HtmlTextWriter output, bool designer )

这两个函数是 public的唯一原因是,控件的设计时间支持。 基本上这两个呈现函数为设计和运行时间生成HTML输出。

public void ResetCompass( )

这里函数将重置指南针并删除当前会话中的所有项。

public void ResetCompass(ArrayList compassData )

这里函数将重置指南针,并将指南针项的给定ArrayList作为数据驱动指南针。

public void ResetCompass(CompassItem item )

将指南针重置为只包含给定的指南针项。

public CompassItem GetCompassItemAt ( int索引)

检索数组中给定索引处的指南针项。

要注意的事项

控件呈现时,整个HTML代码被放在 <DIV> 标签中。 你可以看到 上面,有各种属性可以让你控制。

当页面被添加到控制会话数据时,它使用 Page.Request.RawUrl 要获取当前页面路径,relative 到服务器的root。 这也将检索分配给URL的任何 QueryString。 因此 page1.htm 和 page1.htm? id=2对于控件来说是不同的页面。

它是如何工作的还是 Gritty

当用户查看带有站点罗盘控件的页面时,会收集并存储在用户会话中的某些信息。 这里数据来自两个位置:

  • iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 页面 参数。
  • 指定给控件的属性。
  • 这里数据被放置到类的对象中( SiteCompassItem ),然后将它的放置到ArrayList中,以便可以维护它接收到的顺序。 当 ASP.NET 引擎请求控件生成它的HTML时,它将根据会话中已经保存的页检查当前页。 如果该页存在,则删除该页之后的所有项。 如果它不存在,则将它添加到当前项的末尾。 这里列表随后用于生成HTML代码,该代码在浏览器中呈现指南针。

代码

我没有在这里引入任何令人惊讶的新概念或者概念,因这里代码相对简单。 也就是说,这里有几个 兴趣点 值得提及。

比较对象

控件的核心是检查页面是否已经存在。 控件的第一个版本只是使用了几个连接字符串来存储数据,但是我看到了一个更好的解决方案。 最后,我创建了自己的定制类来保存compass项数据,但这导致了一个有趣的问题。

作为示例,请看下面的代码:


private bool TestMe()


{


 testClass tc1 = new testClass("abc", "def", "ghi");


 testClass tc2 = new testClass("123", "456", "789");


 testClass tc3 = new testClass("xxx", "yyy", "zzz");


 testClass tc4 = new testClass("abc", "def", "ghi"); //same values tc1



 ArrayList array1 = new ArrayList();


 array1.Add(tc1);


 array1.Add(tc2);


 array1.Add(tc3);


 return array1.Contains(tc4);


}



使用这里类

class testClass


{


 public string abc;


 public string def;


 public string ghi;



 public testClass(string abc, string def, string ghi)


 {


 this.abc = abc;


 this.def = def;


 this.ghi = ghi;


 }


}



iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 TestMe ( ) 函数将是 return false 要绕过这个问题,你需要重写这些类 Equals ( 对象对象) 函数为 ArrayList.Contains(.. ) 用于比较对象。

对于这里控件,我使用以下替代来执行对象比较:


public static bool _caseSensitiveUrlComparison = false;



...


...


...



public override bool Equals(object obj)


{


 CompassItem compareObject = obj as CompassItem;



 if (compareObject == null)


 {


 return false;


 }



 if (_caseSensitiveUrlComparison)


 {


 return this.ToString() == compareObject.ToString();


 }


 else


 {


 return this.ToString().ToLower() == compareObject.ToString().ToLower();


 }


}



public override int GetHashCode()


{


 return base.GetHashCode();


}



public override string ToString()


{


 return this.DisplayTitle + this.RawUrl + this.IconPath + this.IconAlt + this.Target;


}



iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 ToString ( ) 函数只接受所有类变量字符串并将它们连接成一个长字符串。 下一班车是什么时候? .Equals(.. ) 被调用 ArrayList.Contains(.. ) ,它使用这里字符串执行比较。

static 变量 _caseSensitiveUrlComparison 使我可以设置 ArrayList.Equals(.. ) 在我调用它之前。

例如这一部分代码处理不需要的指南针项。


//set the value of the static variable that


//indicates if object searches are case


//sensitive


CompassItem.CaseSensitiveUrlComparison = this.CaseSensitiveUrlComparison;



//check if the newItem exists in the current


//compass data this is possible as CompassItem


//has an overriden. equals()


if (compassData.Contains(newItem))


{


 int index = compassData.IndexOf(newItem) + 1;


 int count = compassData.Count - index;


 compassData.RemoveRange(index, count);


}



重写默认属性

当使用linked链接的上面 中的方法描述自定义控件时,将有各种默认属性。 对于这个项目,我不想显示不同的属性,因为它们不相关。使用或者重要。

隐藏这些属性仅仅是一个设置 可以浏览( false ) 属性。

例如:


[Browsable(false)]


public override FontInfo Font


{


 get { return base.Font; }


}



有关更多信息,请参见:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemComponentModelBrowsableAttributeClassTopic.asp

如果你查看代码,我隐藏的属性都与样式有关。 它们隐藏的原因是,我完全快乐地使用生成的HTML代码质量,当与 HtmlTextWriter 所以我决定让控件完全由样式表驱动。

Visual Studio 设计器支持

没有什么比用很少或者根本没有设计人员支持的控件来开发更烦人的了。 这里控件具有完整的设计器支持(。选择DHTMLMenu样式时除外),因为它生成虚拟条目,以便在查看页时显示控件。

这是如何在本页顶部的MSDN文章中描述的,但我认为应该在这里覆盖to控制器。

创建了与控件类位于同一命名空间中的以下类:


public class SiteCompassDesigner : System.Web.UI.Design.ControlDesigner 


{


 public override string GetDesignTimeHtml() 


 {


 //create the writers to handled the output


 StringWriter sw = new StringWriter();


 HtmlTextWriter tw = new HtmlTextWriter(sw);



 //get and instance of the object calling the class


 SiteCompass scc = (SiteCompass) Component;



 //switch on the users selected style to generate


 //the necessary designer code.


 switch (scc.CompassStyle)


 {


 case SiteCompass.CompassStyles.HorizonatalHTML:


 case SiteCompass.CompassStyles.VerticalHTML:


 scc.GenerateCompass_HTML(tw, true);


 break;


 case SiteCompass.CompassStyles.DHTMLMenu:


 scc.GenerateCompass_DHTMLMenu(tw, true);


 break;


 }



 //return the StringWriter string to VS


 return sw.ToString();


 }


}



重写 GetDesignTimeHtml ( ) 在设计视图中打开ASPX页时由 Visual Studio 调用函数。 返回的字符串将放置在页面上放置控件的位置。 你甚至可以做一些简单的事情,比如:


public class SiteCompassDesigner : System.Web.UI.Design.ControlDesigner 


{


 public override string GetDesignTimeHtml() 


 {


 return "<b>My Cool Control</b>"


 }


}



但那不是那么酷 !

在MSDN文章中,它生成一个标签,并将它的中的HTML全部返回到 GetDesignTimeHtml ( ) 函数我不想为运行时和设计时支持编码罗盘绘制器的两种变化

根据站点指南的风格选择 1个 2渲染器将被使用:

  • public void GenerateCompass_HTML(HtmlTextWriter output, bool designer )
  • public void GenerateCompass_DHTMLMenu(HtmlTextWriter output, bool designer )

就像你看到的,每一个都有同样的参数。 在运行时模式下,ASP.NET 引擎调用:

protected 替代 void Render(HtmlTextWriter output )

iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 输出 参数是当前页面 HtmlTextWriter 控件然后向编写器添加自己的html并将它的传递回引擎,以便进一步的代码添加和处理。 我 渲染( ) 函数调用描述的呈现器 上面 传递 设计器 作为 false 这意味着从会话中检索数据并用于生成指南针。 在设计时没有会话,因此 设计器true 代码生成一个虚拟列表,并生成HTML代码,该代码通过 GetDesignTimeHtml ( ) 前面提到的函数

可能存在的问题

  • Querystrings将始终用于比较,未来版本可能具有处理Querystrings的能力

可能的增强功能

  • 当控件简单地添加 <> 后,能够为垂直列表设置属性驱动列表标签。
  • 覆盖并公开更多 ArrayList 增强开发人员控制的功能。
  • 跟踪某项但不显示它的能力
  • 增强替代的比较选项 .Equals( )
  • 使用以下方法提高输出代码的可读性 缩进.WriteLine( )HtmlTextWriter

DHTML菜单信用

作为fancy的飞行,我构建了将控件呈现为DHTML菜单的能力。 这看起来好像是一个好主意,我的技术是弱的,因为我必须给教程的源代码。

http://www.brainjar.com/

让我在你的DHTML Fu之前鞠躬

历史记录

v 1.0.0.0 - 这里代码

所有的人,感谢你的调谐。

一件小事:我很遗憾没有任何地方来主持这个项目的工作示例。 如果有人可以占用一些带宽和服务器空间,请联系我。


COM  IMP  Implementation  asp  asp-net  cookie  
相关文章