精华内容
下载资源
问答
  • walther
    2011-01-24 10:57:21

    为了适应自动化测试的需要,单元测试框架需要满足两个重要的指标。首先当然是程序库的质量了,因为你需要使用它来构建测试。其次是测试框架能够集成到你所使用的工具链当中。对于.NET开发者来说,这意味着可以通过构建脚本在IDE中运行JavaScript测试。虽说如此,但大多数框架只关注于前者,Stephen Walther则对后者展开了研究。

    \u0026#xD;\n

    感兴趣的读者可以在Stephen Walther所发表的名为Integrating JavaScript Unit Tests with Visual Studio的文章中了解完整的设计,我们这里只是介绍一下其中的关键点。

    \u0026#xD;\n

    最重要的事情就是他的设计中并没有浏览器组件,这很有意思。

    \u0026#xD;\n
    • 由于没有使用浏览器,因此测试的运行速度会非常快。\u0026#xD;\n
    • 环境非常纯粹。只有显式导入到测试引擎中的代码会执行,不会掺杂任何浏览器的东西。\u0026#xD;\n
    • 由于是个整洁、无浏览器的环境,因此你没法访问到DOM或是其他特定于Web的对象。\u0026#xD;\n
    • 虽然对于纯JavaScript库来说非常完美,但对于UI测试却完全不适合(这可以通过模拟特定于Web的对象来解决)。\u0026#xD;\n

    虽然任何独立的JavaScript引擎都可以实现这个目标,但Stephen最终选择了IE下的JScript引擎、Windows Script Host以及传统的ASP。这样就可以通过Windows Script Interfaces与Microsoft Script Control公开给.NET了。

    \u0026#xD;\n

    他构建了一个非常原始的JavaScript测试库,用于填平JScript引擎与MSTest框架之间的沟壑。考虑到设计的简洁性,这项技术实际上可以将任意的JavaScript测试库、JavaScript引擎和自动化测试框架组合起来。

    \u0026#xD;\n

    查看英文原文:Stephen Walther on Integrating JavaScript Unit Tests

    更多相关内容
  • 这是 Walther 方程的简单实现,用于在给定两个温度/粘度点(在许多数据表上通常为 40C 和 100C)的温度范围(或单个点)内估算油的粘度(动态和运动)
  • 由于[Walther-WA2000 如果你想自我主持 将此仓库克隆到您选择的工作目录中。 填写config_templates然后将它们拖到工作目录中的index.js旁边 在您的工作目录中执行npm i 做npm start启动机器人 如果您想贡献,只需...
  • 基于 Stefan Walther 创建的“AutoRefresh”扩展的 QlikView 文档扩展,增加了每隔 X 秒自动在文档变量中定义的工作表序列之间跳转的功能。 扩展的目标是允许使用 QlikView Server 保持会话处于活动状态,并在无需...
  • 一套在BeOS下可以在FidoNet中工作的程序。
  • nutipraktikum:沃尔特·克拉姆(Walther Kraam)nutipraktikum 2021
  • walther换枪盘

    2019-01-11 13:10:21
    工业机器人换枪盘walther硬件介绍,端口介绍,电气原理图,机械结构图
  • In this book, world-renowned ASP.NET expert and member of the Microsoft ASP.NET team Stephen Walther shows experienced developers how to use Microsoft's new ASP.NET MVC Framework to build web ...
  • (stephen walther, kavin hoffman,nate dudek)所著作:《asp揭秘 .net4 》源代码
  • NET_ASP.NET合作专区_微软技术图书_微软程序设计_微软.NET 作者:(美)Stephen Walther 本书是美国亚马逊网站同类书... www.china-pub.com/19111 40K 2009-7-19 - 百度快照
  • ☆特别推崇Stephen Walther大师简单实用、清晰明了的编程风格~关于作者Stephen Walther 撰写了有关 ASP.NET 的最畅销著作 — ASP.NET Unleashed他还曾是 ASP.NET Community Starter Kit(一个由 Microsoft 生产的 ...

     ☆特别推崇Stephen Walther大师简单实用、清晰明了的编程风格~

    关于作者

    Stephen Walther 撰写了有关 ASP.NET 的最畅销著作 — ASP.NET Unleashed他还曾是 ASP.NET Community Starter Kit(一个由 Microsoft 生产的 ASP.NET 示例应用程序)的架构师和首席开发人员。他已经通过他的公司 Superexpert (http://www.superexpert.com) 为美国各地的公司(包括 NASA 和 Microsoft)提供了 ASP.NET 培训。

    作者本身毕业于加州大学伯克利分校的艺术专业,并曾在MIT攻读过语言和哲学专业的博士,

    blog地址:http://www.superexpert.com/Default.aspx

    展开全文
  • 20世纪90年代以来,以计算机为中介的传播(Computer-Mediated Communication,CMC)成为人类越来越普遍的经验。新技术深刻而全面地影响着人际传播的模式,并成为人际关系建立、发展和维系过程中不可或缺的因素。...

    20世纪90年代以来,以计算机为中介的传播(Computer-Mediated Communication,CMC)成为人类越来越普遍的经验。新技术深刻而全面地影响着人际传播的模式,并成为人际关系建立、发展和维系过程中不可或缺的因素。对实践过程的观察和研究形成了人际传播的新知识、新议题、新问题和新方法。尤其是,人们迅速而又广泛地对社交网络化技术的采纳,正扩大着、积累着甚至修正着我们对这些新知识的理解。了解这些新知识、新议题无疑将为我们对中国人际传播经验展开本土化研究提供典范。

    线索过滤理论

    库尔兰和马尔库斯首创了“线索过滤”这一名词来指称CMC与面对面传播的根本性差异。

    社会在场理论强调,在提供更多的温暖感和参与感等方面,CMC天生就不如面对面传播。但大多数研究者认为,只有把在场概念分为远程在场、共在和社会在场,才可以更好地揭示人们在不同的人际关系活动中为何使用不同的新媒介以及媒介使用的顺序差异。而且,以照片、虚拟化身和视频为特征的第二代CMC比第一代提供的在场感更强。其实,正是并只有传播技术才为我们提供了在场与不在场之间做灵活选择的可能性。

    社会语境线索缺失理论认为,CMC阻碍了面对面互动中通过非语言行为所能传达出的个性和规范行为等线索的传递,导致了传播使用者变得去个体化、以自我为中心、抵制影响、难以劝服、不受约束、好战、情绪消极。但反对者却认为,CMC使用者会根据使用的媒介来调整自己的语言,以弥补非语言线索的缺失,从而产生不同的社会和人际效果——除了非人的、人际的,还有超人际效果。

    媒介丰富度理论指出,“富媒介”经常被用于表示多模式或带宽更高的媒介,也就是能支持多种语言线索和非语言线索系统的媒介(比如,面对面传播最丰富);在信息情境的多义性与发送该信息的媒介的丰富度之间存在匹配关系:信息多义性越高,越要使用丰富度高的媒介,信息多义性低则只需要使用简单的媒介,这样的传播最有效。有研究考察了个体在欺骗他人(谎言可被视作多义信息)时的媒介选择倾向,发现面对新媒介的可记录性等特征时,媒介丰富度理论解释乏力。

    信号理论解释了社交网站在帮助观察者评价他人在线表述的真实性方面的益处和潜能。即,如果你能够接触到互动对象社交网络中的其他人,那么互动对象欺骗你的可能性就会降低;如果观察者戳穿了互动对象的骗局,那么这一互动对象将受到社会制裁或惩罚。社交网站使用者对这些成本心知肚明,也就不会在简介中做假了。

    展开全文
  • ASP.NET 3.5 Unleashed.pdf

    2011-10-30 15:09:05
    本书作者Stephen Walther是ASP界的名人,是微软公司的ASP.NET MVP,荣获微软“软件传奇人物”称号(微软技术社区的最高荣誉),曾经开发了许多示范性应用程序。 本书适合所有ASP.NET开发人员阅读
  • Rivera,S.,Best,C.,Yim,H.,Martinez,A.,Sloutsky,V.,&Walther,D.(2012年)。 成人和婴儿的视觉分类中自动选择眼睛跟踪变量。 在N. Miyake,D。Peebles和RP Cooper(编),《认知科学学会第34届年会论文...
  • T.Walther2 1NorwegianRadiation ProtectionAuthority, ÒsterÔs, Norway 2Department of Molecular Biology, University of Bergen, Bergen, 挪威 斑马鱼胚胎在卵内暴露于 1000 mT rms 的 50 Hz AC 磁场,以及监测...
  • [a]格赖夫斯瓦尔德大学,数学与计算机科学研究所,Walther-Rathenau-Str。 47, 17489 德国格赖夫斯瓦尔德 [b]格赖夫斯瓦尔德大学,微生物功能基因组学中心,Felix-Hausdorff-Str。 8, 17489 德国格赖夫斯瓦尔德 [c]...
  • rsa matlab代码音乐核磁共振 进行中 该存储库包含Music-fMRI项目中使用的代码(引用此内容)。 可以找到原始数据(链接在这里) 我尝试包括matlab依赖项,但是此版本...C,Walther A,Su L,Marslen-Wilson W,Krieges
  • Walther Kossel 25-30 可持续发展 - 化学的概念和实施 66-76 潜热储存的高效能源利用 77-85 德尔福课程学习化学:通识教育和化学课程 86-90 优化化学课程的图像122-129 胶体系统在二级 I 中的整合 130-135 在科学...
  • 癌症基因治疗方案说明书 癌症基因治疗方案说明书 Wolfgang Walter 和 Ulrike Stein(编辑):癌症基因治疗:方法和方案。 Humana ...Walther 和 Ulrike Stein 在召集各自领域的许多专家贡献章节方面
  • matlab求导代码 ...和Walther,A.(2008)。 评估导数:算法差异的原理和技术。 工业和应用数学协会。 目录 特征 mado editor当前提供以下核心功能。 前向活动分析 逆向活动分析 代码线性化 一阶转发模式
  • Walther *, a, Rainer Kilian、Heike Schreer 和 Helmar Görls Jena,弗里德里希席勒大学无机和分析化学研究所 2001 年 11 月 22 日编辑部收到。献给 Walter Siebert 教授 65 岁生日之际内容。 苯甲醛-N-糠基亚胺、...
  • Walther和Christof Koch(2006),建模对显着原型对象的关注。 神经网络19,1395-1407。 要求 为了读取图像,需要使用带有libz libjpeg和libpng ,并且使用X11进行测试。 为了提高速度,需要具有CUDA支持的Nvidia ...
  • Walther *, Frank Schramm, Nils Thatssen, R. Beckert 和 Helmar Görls耶拿大学无机和分析化学研究所。2002 年 7 月 3 日收到。四聚三(N,N-二甲氨基)甲硅烷基酰胺锂:合成、结构和React性摘要。 [(Me2N) 3...
  • 估计簇数的方法:Calinski-Harabasz,Tibshirani和Walther的预测强度,Fang和Wang的自举稳定性。 高斯/多项式混合拟合,用于混合的连续/类别变量。 聚类解释的可变智商统计。 DBSCAN集群。 R中实现的许多聚类方法的...
  • (1977年)以及Walther,Slovacek和Tidwell,2001年),我们假设,在互联网约会网站上伴随女性的个人广告拍摄的精美照片会引起男性受访者的更多参与,并增加她们的交流会引起受访者的回覆的可能性。女士。
  • D Walther,生化科学趋势22(7),274-275 可根据要求提供源代码。 WebMol是在1996年至1999年由EMBL(德国海德堡)和UCSF(美国San Francisoco)开发的作者:Dirk Walther 独特功能,亮点分析次级结构元素的填充...
  • 我们与所有者Jessica Walther一起确定了Woodland Consulting的需求和品牌,同时研究了她的竞争对手以了解照明领域以及我们可以添加哪些功能来使她的业务与众不同。 最终的网站具有直观,简单的管理仪表板,用于检索...
  • 作者: Stephen Walther 原文地址:http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnvs05/html/UserProfiles.asp 译者:Tony Qu 概要:许多ASP.NET应用程序需要跨访问的用户属性跟踪功能,...

    作者: Stephen Walther
    原文地址:http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnvs05/html/UserProfiles.asp
    译者:Tony Qu

    概要:许多ASP.NET应用程序需要跨访问的用户属性跟踪功能,在ASP.NET1.1中,我们只能人工实现这一功能。但如今,使用 ASP.NET 2.0的Profile对象,这个过程变得异常简单。Stephen Walther将验证该对象,并向你展示如何使用Profile来跟踪用户属性、创建一个购物篮,及其他一些例子。

    总目录
    介绍
    User Profile总揽
    定义User Profile
    使用Profile组
    使用复杂的Profile属性
    继承一个Profile
    迁移匿名Profile设置
    配置Profile Provider
    管理Profiles并生成Profile报告
    总结
    相关书籍

    Microsoft ASP.NET 2.0支持被称为Profile的新对象,它可以自动在多个Web应用程序的访问之间存储用户信息。一个User Profile中可以存储各种类型的信息,这些信息既可以是简单的string和integer类型,也可以是复杂的自定义类型。例如,你可以存储用户的姓、购物篮、用户属性或网站使用情况统计。
    本文中,你将学习如何在一个应用中定义user profile。我们也会向你演示如何配置使用不同provider的profile。最后,你将学习如何管理和生成user profile的报告。

    User Profiles总揽
    Profile 对象与Session对象十分相似,但是更好用一些。与Session相似的地方在于,Profile是相对于一个特定的用户的,也就是说,每个Web应用程序的用户都有他们自己的profile对象。与Session不同的是,Profile对象是持久对象。如果你向Session中添加一个项,在你离开网站时,该项就会消失。而Profile则完全不同,当你修改Profile的状态时,修改在多个访问之间均有效。

    profile使用provider模式来存储信息,默认情况下,user profile的内容会保存在SQL Server Express数据库中,该数据库位于网站的App_Data目录。然而,在本文的后半部分,你将了解如何使用其他数据提供者(data provider)来存储信息,如完整版的SQL Server中的一个数据库或者一个Oracle数据库。

    与Session不同,Profile是强类型的,Session对象仅仅是一个项集合而已,而profile对象则有强类型属性。
    使用强类型是有它的道理的。例如,使用强类型,你就可以在Microsoft Visual Web Developer中使用智能感知技术,当你键入Profile和一个点的时候,智能感知会弹出你已经定义过的profile属性列表。

    定义user profile
    你既可以在machine.config中,也可以在web.config中定义一个user profile,由于你不能在应用程序的二级目录中创建一个包含文件profile节的web.config文件,这意味着你将无法在一个应用程序中定义两个以上的profile。
    在列表1的web.config中,列举了一个简单的profile定义的实例,该profile有三个属性,FirstName, LastName和PageVisits。

    列表1
    < configuration >
    < system .web >
    < authentication mode ="Forms" />

    < anonymousIdentification enabled ="true" />

    < profile >
    < properties >
    < add
    name ="FirstName"
    defaultValue
    ="??"
    allowAnonymous
    ="true" />
    < add
    name ="LastName"
    defaultValue
    ="??"
    allowAnonymous
    ="true" />
    < add
    name ="PageVisits"
    type
    ="Int32"
    allowAnonymous
    ="true" />
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    由于该profile需要同时被匿名用户和已认证用户使用,因此我们在web.config文件中增加包含一个 < anonymousIdentification>元素,有了这个元素,系统就会自动为匿名用户生成唯一的ID。仔细看的话我们会发现,每一个 profile属性都有一个allowAnonymous特性,该特性表明这个profile属性是否允许被匿名用户使用。

    默认的profile属性类型是System.String类型。列表1中,由于没有为FirstName和LastName这两个profile属性增加type特性,那么系统默认它们是string类型,而PageVisits属性则指定了type特性为Int32,因此该profile属性可用于表示一个整型值。

    最后,注意FirstName和LastName属性都有defaultValue特性。你可以为简单的数据类型设置defaultValue特性,但你不能为复杂类型设置defaultValue特性。

    当你定义好一个profile之后,系统会自动在下一次页面被调用时,生成一个与该profile相对应的类。这个类会被保存在"Temporary ASP.NET Files Directory"目录(该目录也用于存放用于动态生成页面的类)。你可以使用HttpContext的Profile属性(Property)调用该类。
    当你定义好一个profile后,你可以使用如下方法为profile属性赋值。

    [VisualBasic.NET]
    Profile.FirstName
    = " Bill "

    [C#]
    Profile.FirstName
    = " Bill " ;

    任何在web.config中定义的profile属性都会在Profile对象中呈现。
    列表2演示了你该如何使用profile来持久化保存用户信息。这个页显示了FirstName,LastName, PageVisits三个属性的值,同时它包含了一个能够用于修改这三个属性的表单(form)。在Page_Load中更新PageVisits的值,这意味着每一次刷新页面,PageVisits的值都会改变。

    图1 使用简单的profile

    列表 2. Simple.aspx (Visual Basic .NET)
    < %@PageLanguage = " VB " % >
    < scriptrunat = " server " >

    Sub Page_Load()
    Profile.PageVisits
    += 1
    EndSub

    Sub UpdateProfile( ByVal s As Object , ByVal e As EventArgs)
    Profile.FirstName
    = txtFirstName.Text
    Profile.LastName
    = txtLastName.Text
    EndSub

    </ script >

    < html >
    < head >
    < title > Simple </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >
    < b > Name: </ b > < % = Profile.FirstName% > < % = Profile.LastName% >
    < br />
    < b > PageVisits: </ b > < % = Profile.PageVisits% >

    < hr />

    < b > FirstName: </ b >
    < asp:TextBoxID = " txtFirstName " Runat = " Server " />
    < br />
    < b > LastName: </ b >
    < asp:TextBoxID = " txtLastName " Runat = " Server " />
    < br />
    < asp:Button
    Text
    = " UpdateProfile "
    OnClick
    = " UpdateProfile "
    Runat
    = " server " />

    </ form >
    </ body >
    </ html >

    列表 2. Simple.aspx (C#)
    <% @PageLanguage = " C# " %>
    < scriptrunat = " server " >

    void Page_Load(){
    Profile.PageVisits
    ++ ;
    }

    void UpdateProfile(Objects,EventArgse){
    Profile.FirstName
    = txtFirstName.Text;
    Profile.LastName
    = txtLastName.Text;
    }

    </ script >

    < html >
    < head >
    < title > Simple </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >
    < b > Name: </ b > <%= Profile.FirstName %> <%= Profile.LastName %>
    < br />
    < b > PageVisits: </ b > <%= Profile.PageVisits %>

    < hr />

    < b > FirstName: </ b >
    < asp:TextBoxID = " txtFirstName " Runat = " Server " />
    < br />
    < b > LastName: </ b >
    < asp:TextBoxID = " txtLastName " Runat = " Server " />
    < br />
    < asp:ButtonID = " Button1 "
    Text
    = " UpdateProfile "
    OnClick
    = " UpdateProfile "
    Runat
    = " server " />

    </ form >
    </ body >
    </ html >

    如果你多次访问列表2中的页面,你会注意到PageVisits在不断增大。如果你关闭的浏览器,并在一周之后调用该页面,PageVisits属性仍然会保留原值。从这一点可以看出Profile为每个用户自动保存一个副本。

    使用Profile组

    尽管你仅可以为一个应用程序定义一个profile,但如果你需要让几个profile属性一起工作,把它们放在组中,会让你觉得它们更易管理。

    例如,在列表3中,有一个带有两个组的profile,这两个组分别是Address和Preferences

    列表3. Web.Config
    < configuration >
    < system .web >

    < anonymousIdentification enabled ="true" />

    < profile >
    < properties >
    < group name ="Address" >
    < add
    name ="Street"
    allowAnonymous
    ="true" />
    < add
    name ="City"
    allowAnonymous
    ="true" />
    </ group >
    < group name ="Preferences" >
    < add
    name ="ReceiveNewsletter"
    type
    ="Boolean"
    defaultValue
    ="false"
    allowAnonymous
    ="true" />
    </ group >
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    当你用组来定义 profile 时,你应该使用组名来设置或读取 profile 属性。例如,在列表 3 中,你可以使用以下一些句子来完成三个 profile 属性的赋值。

    [VisualBasic.NET]

    Profile.Address.City
    = " Modesto "
    Profile.Address.Street
    = " 111KingArthurLn "
    Profile.Preferences.ReceiveNewsletter
    = False

    [C#]

    Profile.Address.City
    = " Modesto " ;
    Profile.Address.Street
    = " 111KingArthurLn " ;
    Profile.Preferences.ReceiveNewsletter
    = false ;

    一个profile的定义只能包含一层组,换句话说,你不能把其他的组放在一个profile组的下面一层。

    使用复杂的profile属性

    到目前为止,我们已经介绍了声明包含简单类型(如string或整型)属性的profile,其实你也可以在profile中声明复杂属性。
    举个例子,假设你现在需要在profile中存储一个购物篮,如果这样做的话,你就可以在每次访问网站时获得自己的购物篮。
    列表4 声明了一个包含profile,这个profile包含一个名为ShoppingCart的属性,而该属性的type特性是一个叫ShoppingCart的类(我们接下来会创建该类),该类名是有效的。
    我们还会注意到,该声明中包含一个serializeAs特性,该特性可以帮助ShoppingCart使用二进制序列化器(binary serializer)进行持久化,而不是使用xml序列化器。

    列表4 Web.config

    <
    configuration >
    < system .web >

    < anonymousIdentification enabled ="true" />

    < profile >
    < properties >
    < add
    name ="ShoppingCart"
    type
    ="ShoppingCart"
    serializeAs
    ="Binary"
    allowAnonymous
    ="true" />
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    列表5 中有一个简单购物篮的实现代码,该购物篮拥有添加和删除项(item)的方法(method),同时它还拥有两个属性(property),一个是用于获得该购物篮中的所有项的,一个是用于表示所有商品的总价的。

    列表5 ShoppingCart (Visual Basic.NET)

    Imports
    Microsoft.VisualBasic

    < Serializable() > _
    Public Class ShoppingCart
    Public _CartItems As New Hashtable()

    ' ReturnalltheitemsfromtheShoppingCart
    Public ReadOnly Property CartItems() As ICollection
    Get
    Return _CartItems.Values
    End Get
    EndProperty

    ' Thesumtotaloftheprices
    Public ReadOnly Property Total() As Decimal
    Get
    Dim sum As Decimal
    For Each item As CartItem In _CartItems.Values
    sum
    += item.Price * item.Quantity
    Next
    Return sum
    End Get
    EndProperty

    ' Addanewitemtotheshoppingcart
    Public Sub AddItem( ByVal ID As Integer ,_
    ByVal Name As String , ByVal Price As Decimal )
    Dim item As CartItem = CType (_CartItems(ID),CartItem)
    If item Is Nothing Then
    _CartItems.Add(ID,
    New CartItem(ID,Name,Price))
    Else
    item.Quantity
    += 1
    _CartItems(ID)
    = item
    End If
    EndSub

    ' Removeanitemfromtheshoppingcart
    Public Sub RemoveItem( ByVal ID As Integer )
    Dim item As CartItem = CType (_CartItems(ID),CartItem)
    If item Is Nothing Then
    Return
    End If
    item.Quantity
    -= 1
    If item.Quantity = 0 Then
    _CartItems.Remove(ID)
    Else
    _CartItems(ID)
    = item
    End If
    EndSub

    EndClass

    < Serializable() > _
    Public Class CartItem

    Private _ID As Integer
    Private _Name As String
    Private _Price As Decimal
    Private _Quantity As Integer = 1

    Public ReadOnly Property ID() As Integer
    Get
    Return _ID
    End Get
    EndProperty

    Public ReadOnly Property Name() As String
    Get
    Return _Name
    End Get
    EndProperty

    Public ReadOnly Property Price() As Decimal
    Get
    Return _Price
    End Get
    EndProperty

    Public Property Quantity() As Integer
    Get
    Return _Quantity
    End Get
    Set ( ByVal value As Integer )
    _Quantity
    = value
    End Set
    EndProperty

    Public Sub New ( ByVal ID As Integer ,_
    ByVal Name As String , ByVal Price As Decimal )
    _ID
    = ID
    _Name
    = Name
    _Price
    = Price
    EndSub
    EndClass

    列表5 ShoppingCart (c#)

    using
    System;
    using System.Collections;

    [Serializable]
    public class ShoppingCart
    {
    public Hashtable_CartItems = new Hashtable();

    // ReturnalltheitemsfromtheShoppingCart
    public ICollectionCartItems
    {
    get { return _CartItems.Values;}
    }

    // Thesumtotaloftheprices
    public decimal Total
    {
    get
    {
    decimal sum = 0 ;
    foreach (CartItemitem in _CartItems.Values)
    sum
    += item.Price * item.Quantity;
    return sum;
    }
    }

    // Addanewitemtotheshoppingcart
    public void AddItem( int ID, string Name, decimal Price)
    {
    CartItemitem
    = (CartItem)_CartItems[ID];
    if (item == null )
    _CartItems.Add(ID,
    new CartItem(ID,Name,Price));
    else
    {
    item.Quantity
    ++ ;
    _CartItems[ID]
    = item;
    }
    }

    // Removeanitemfromtheshoppingcart
    public void RemoveItem( int ID)
    {
    CartItemitem
    = (CartItem)_CartItems[ID];
    if (item == null )
    return ;
    item.Quantity
    -- ;
    if (item.Quantity == 0 )
    _CartItems.Remove(ID);
    else
    _CartItems[ID]
    = item;
    }

    }

    [Serializable]
    public class CartItem
    {
    private int _ID;
    private string _Name;
    private decimal _Price;
    private int _Quantity = 1 ;

    public int ID
    {
    get { return _ID;}
    }

    public string Name
    {
    get { return _Name;}
    }

    public decimal Price
    {
    get { return _Price;}
    }

    public int Quantity
    {
    get { return _Quantity;}
    set {_Quantity = value;}
    }

    public CartItem( int ID, string Name, decimal Price)
    {
    _ID
    = ID;
    _Name
    = Name;
    _Price
    = Price;
    }
    }

    如果你把列表5中的代码添加到应用程序的App_Code目录中,购物篮会自动被编译。

    在列表5中有一点值得注意,那就是ShoppingCart和CartItem类都加上了可序列化的特性,这一点对于他们能否被序列化十分重要,只有这样才能保存在Profile对象中。

    最后,列表6的页面显示了可以被添加到购物篮中的产品。购物篮是通过BindShoppingCart方法从Profile对象中载入,该方法把购物篮中的对象绑定到一个GridView对象上,这些对象可以通过ShoppingCart类的CartItems属性获得。


    图2 在profile中存储购物篮

    AddCartItem方法用于在购物篮中添加一个产品,该方法中包含了检测Profile是否存在ShoppingCart的代码。对于Profile中存储的对象,你必须自己实例化这些对象,他们不会自动实例化。

    RemoveCartItem方法用于从购物篮中移除一个产品,该方法只是简单地通过调用Profile中的ShoppingCart对象的RemoveItem方法。

    列表 6 - Products.aspx (Visual Basic .NET)

    <
    %@PageLanguage = " VB " % >

    < scriptrunat = " server " >

    Sub Page_Load()
    If Not IsPostBack Then
    BindShoppingCart()
    End If
    EndSub

    Sub BindShoppingCart()
    If Not Profile.ShoppingCart Is Nothing Then
    CartGrid.DataSource
    = Profile.ShoppingCart.CartItems
    CartGrid.DataBind()
    lblTotal.Text
    = Profile.ShoppingCart.Total.ToString( " c " )
    End If
    EndSub

    Sub AddCartItem( ByVal s As Object , ByVal e As EventArgs)
    Dim row As GridViewRow = ProductGrid.SelectedRow

    Dim ID As Integer = CInt (ProductGrid.SelectedDataKey.Value)
    Dim Name As String = row.Cells( 1 ).Text
    Dim Price As Decimal = CDec (row.Cells( 2 ).Text)

    If Profile.ShoppingCart Is Nothing Then
    Profile.ShoppingCart
    = New ShoppingCart
    End If
    Profile.ShoppingCart.AddItem(ID,Name,Price)
    BindShoppingCart()
    EndSub

    Sub RemoveCartItem( ByVal s As Object , ByVal e As EventArgs)
    Dim ID As Integer = CInt (CartGrid.SelectedDataKey.Value)
    Profile.ShoppingCart.RemoveItem(ID)
    BindShoppingCart()
    EndSub
    </ script >

    < html >
    < head >
    < title > Products </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >

    < tablewidth = " 100% " >
    < tr >
    < tdvalign = " top " >
    < h2 > Products </ h2 >
    < asp:GridView
    ID
    = " ProductGrid "
    DataSourceID
    = " ProductSource "
    DataKeyNames
    = " ProductID "
    AutoGenerateColumns
    = " false "
    OnSelectedIndexChanged
    = " AddCartItem "
    ShowHeader
    = " false "
    CellPadding
    = " 5 "
    Runat
    = " Server " >
    < Columns >
    < asp:ButtonField
    CommandName
    = " select "
    Text
    = " Buy " />
    < asp:BoundField
    DataField
    = " ProductName " />
    < asp:BoundField
    DataField
    = " UnitPrice "
    DataFormatString
    = " {0:c} " />
    </ Columns >
    </ asp:GridView >




    < asp:SqlDataSource
    ID
    = " ProductSource "
    ConnectionString
    =
    " Server=localhost;Database=Northwind;Trusted_Connection=true; "
    SelectCommand
    =
    " SELECTProductID,ProductName,UnitPriceFROMProducts "
    Runat
    = " Server " />
    </ td >
    < tdvalign = " top " >
    < h2 > ShoppingCart </ h2 >
    < asp:GridView
    ID
    = " CartGrid "
    AutoGenerateColumns
    = " false "
    DataKeyNames
    = " ID "
    OnSelectedIndexChanged
    = " RemoveCartItem "
    CellPadding
    = " 5 "
    Width
    = " 300 "
    Runat
    = " Server " >
    < Columns >
    < asp:ButtonField
    CommandName
    = " select "
    Text
    = " Remove " />
    < asp:BoundField
    DataField
    = " Name "
    HeaderText
    = " Name " />
    < asp:BoundField
    DataField
    = " Price "
    HeaderText
    = " Price "
    DataFormatString
    = " {0:c} " />
    < asp:BoundField
    DataField
    = " Quantity "
    HeaderText
    = " Quantity " />
    </ Columns >
    </ asp:GridView >
    < b > Total: </ b >
    < asp:LabelID = " lblTotal " Runat = " Server " />
    </ td >
    </ tr >
    </ table >
    </ form >
    </ body >
    </ html >

    列表 6. Products.aspx (C#)

    <%
    @PageLanguage = " C# " %>
    <% @ImportNamespace = " System.Globalization " %>
    < scriptrunat = " server " >

    void Page_Load(){
    if ( ! IsPostBack)
    BindShoppingCart();
    }

    void BindShoppingCart()
    {
    if (Profile.ShoppingCart != null )
    {
    CartGrid.DataSource
    = Profile.ShoppingCart.CartItems;
    CartGrid.DataBind();
    lblTotal.Text
    = Profile.ShoppingCart.Total.ToString( " c " );
    }
    }

    void AddCartItem(Objects,EventArgse)
    {
    GridViewRowrow
    = ProductGrid.SelectedRow;

    int ID = ( int )ProductGrid.SelectedDataKey.Value;
    StringName
    = row.Cells[ 1 ].Text;
    decimal Price = Decimal.Parse(row.Cells[ 2 ].Text,
    NumberStyles.Currency);

    if (Profile.ShoppingCart == null )
    Profile.ShoppingCart
    = new ShoppingCart();

    Profile.ShoppingCart.AddItem(ID,Name,Price);
    BindShoppingCart();
    }

    void RemoveCartItem(Objects,EventArgse)
    {
    int ID = ( int )CartGrid.SelectedDataKey.Value;
    Profile.ShoppingCart.RemoveItem(ID);
    BindShoppingCart();
    }
    </ script >

    < html >
    < head >
    < title > Products </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >

    < tablewidth = " 100% " >
    < tr >
    < tdvalign = " top " >
    < h2 > Products </ h2 >
    < asp:GridView
    ID
    = " ProductGrid "
    DataSourceID
    = " ProductSource "
    DataKeyNames
    = " ProductID "
    AutoGenerateColumns
    = " false "
    OnSelectedIndexChanged
    = " AddCartItem "
    ShowHeader
    = " false "
    CellPadding
    = " 5 "
    Runat
    = " Server " >
    < Columns >
    < asp:ButtonField
    CommandName
    = " select "
    Text
    = " Buy " />
    < asp:BoundField
    DataField
    = " ProductName " />
    < asp:BoundField
    DataField
    = " UnitPrice "
    DataFormatString
    = " {0:c} " />
    </ Columns >
    </ asp:GridView >




    < asp:SqlDataSource
    ID
    = " ProductSource "
    ConnectionString
    =
    " Server=localhost;Database=Northwind;Trusted_Connection=true; "
    SelectCommand
    =
    " SELECTProductID,ProductName,UnitPriceFROMProducts "
    Runat
    = " Server " />
    </ td >
    < tdvalign = " top " >
    < h2 > ShoppingCart </ h2 >
    < asp:GridView
    ID
    = " CartGrid "
    AutoGenerateColumns
    = " false "
    DataKeyNames
    = " ID "
    OnSelectedIndexChanged
    = " RemoveCartItem "
    CellPadding
    = " 5 "
    Width
    = " 300 "
    Runat
    = " Server " >
    < Columns >
    < asp:ButtonField
    CommandName
    = " select "
    Text
    = " Remove " />
    < asp:BoundField
    DataField
    = " Name "
    HeaderText
    = " Name " />
    < asp:BoundField
    DataField
    = " Price "
    HeaderText
    = " Price "
    DataFormatString
    = " {0:c} " />
    < asp:BoundField
    DataField
    = " Quantity "
    HeaderText
    = " Quantity " />
    </ Columns >
    </ asp:GridView >
    < b > Total: </ b >
    < asp:LabelID = " lblTotal " Runat = " Server " />
    </ td >
    </ tr >
    </ table >
    </ form >
    </ body >
    </ html >

    继承一个profile
    你也可以通过从一个已经存在的profile类中继承一个profile来完成对profile的定义,这种特性能够帮助你在多个应用程序中使用相同的profile。
    例如,列表7中列出了一个拥有多个用户属性的类,该类是从ProfileBase类继承而来的(你可以在System.Web.Profile中找到)

    在列表8中的Web.config包含一个从UserInfo类继承而来的profile,通过该声明,新的profile可以获得UserInfo类的所有属性。

    列表 7. UserInfo (Visual Basic .NET)

    Imports
    Microsoft.VisualBasic
    Imports System.Web.Profile

    Public Class UserInfo
    Inherits ProfileBase

    Private _FirstName As String
    Private _LastName As String

    Public Property FirstName() As String
    Get
    Return _FirstName
    End Get
    Set ( ByVal value As String )
    _FirstName
    = value
    End Set
    EndProperty

    Public Property LastName() As String
    Get
    Return _LastName
    End Get
    Set ( ByVal value As String )
    _LastName
    = value
    End Set
    EndProperty

    EndClass

    列表 7. UserInfo (C#)
    using System;
    using System.Web.Profile;
    
    public class UserInfo : ProfileBase
    {
        private string _FirstName;
        private string _LastName;
    
        public string FirstName 
        {
            get { return _FirstName; }
            set { _FirstName = value; }
        }
        public string LastName
        {
            get { return _LastName; }
            set { _LastName = value; }
        }
    }

    using
    System;
    using System.Web.Profile;

    public class UserInfo:ProfileBase
    {
    private string _FirstName;
    private string _LastName;

    public string FirstName
    {
    get { return _FirstName;}
    set {_FirstName = value;}
    }
    public string LastName
    {
    get { return _LastName;}
    set {_LastName = value;}
    }
    }

    列表 8. Web.Config

    <
    configuration >
    < system .web >
    < anonymousIdentification enabled ="true" />
    < profile inherits ="UserInfo" />
    </ system.web >
    </ configuration >


    迁移匿名Profile设置
    Profile对象既可用于匿名用户也可以用于已认证用户。然而,当用户从匿名用户状态转换为已认证用户状态时,Profile对象能够以一种令人难以理解的方式完成任务。
    当匿名用户使用Profile对象时,用户profile是与一个随机生成的号码相关联的,该号码是根据每个用户唯一生成的,它保存在浏览器的cookie中,无论何时该用户返回应用程序,该用户的Profile设置会被自动加载。
    如果匿名用户通过认证的话,所有与该用户相关的profile就会丢失,同时系统会生成一个新的profile。这时该Profile信息将与用户名相关联,而非唯一识别号。
    要想理解所有这些工作,最好的方法就是看看下面的例子。列表9中的web.config定义了一个profile,该profile只有一个FavoriteColor属性。

    列表 9 Web.config

    <
    configuration >
    < system .web >

    < authentication mode ="Forms" />

    < anonymousIdentification enabled ="true" />

    < profile >
    < properties >
    < add
    name ="FavoriteColor"
    allowAnonymous
    ="true"
    defaultValue
    ="Red" />
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    列表10中有一个包含两个按钮的页面,分别是login和logout按钮,其中还有一个用于更新FavoriteColor属性的表单。
    列表10. Anonymous.aspx (Visual Basic .NET)

    <
    %@PageLanguage = " VB " % >

    < scriptrunat = " server " >

    Sub Login( ByVal s As Object , ByVal e As EventArgs)
    FormsAuthentication.SetAuthCookie(
    " Bill " , False )
    Response.Redirect(Request.Path)
    EndSub

    Sub Logout( ByVal s As Object , ByVal e As EventArgs)
    FormsAuthentication.SignOut()
    Response.Redirect(Request.Path)
    EndSub

    Sub UpdateProfile( ByVal s As Object , ByVal e As EventArgs)
    Profile.FavoriteColor
    = txtFavoriteColor.Text
    EndSub

    Sub Page_PreRender()
    lblUsername.Text
    = Profile.UserName
    lblFavoriteColor.Text
    = Profile.FavoriteColor
    EndSub

    </ script >

    < html >
    < head >
    < title > Anonymous </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >

    < asp:ButtonID = " Button1 "
    Text
    = " Login "
    OnClick
    = " Login "
    Runat
    = " Server " />
    < asp:ButtonID = " Button2 "
    Text
    = " Logout "
    OnClick
    = " Logout "
    Runat
    = " Server " />
    < hr />
    < asp:TextBox
    id
    = " txtFavoriteColor "
    Runat
    = " Server " />
    < asp:ButtonID = " Button3 "
    Text
    = " UpdateProfile "
    OnClick
    = " UpdateProfile "
    Runat
    = " Server " />
    < hr />
    < b > Username: </ b >
    < asp:Label
    id
    = " lblUsername "
    Runat
    = " Server " />
    < br />
    < b > FavoriteColor: </ b >
    < asp:Label
    id
    = " lblFavoriteColor "
    Runat
    = " Server " />

    </ form >
    </ body >
    </ html >

    列表10. Anonymous.aspx (C#)

    <%
    @PageLanguage = " C# " %>

    < scriptrunat = " server " >

    void Login(Objects,EventArgse)
    {
    FormsAuthentication.SetAuthCookie(
    " Bill " , false );
    Response.Redirect(Request.Path);
    }

    void Logout(Objects,EventArgse)
    {
    FormsAuthentication.SignOut();
    Response.Redirect(Request.Path);
    }

    void UpdateProfile(Objects,EventArgse)
    {
    Profile.FavoriteColor
    = txtFavoriteColor.Text;
    }

    void Page_PreRender()
    {
    lblUsername.Text
    = Profile.UserName;
    lblFavoriteColor.Text
    = Profile.FavoriteColor;
    }

    </ script >

    < html >
    < head >
    < title > Anonymous </ title >
    </ head >
    < body >
    < formid = " form1 " runat = " server " >

    < asp:Button
    Text
    = " Login "
    OnClick
    = " Login "
    Runat
    = " Server " />
    < asp:ButtonID = " Button1 "
    Text
    = " Logout "
    OnClick
    = " Logout "
    Runat
    = " Server " />
    < hr />
    < asp:TextBox
    id
    = " txtFavoriteColor "
    Runat
    = " Server " />
    < asp:Button
    Text
    = " UpdateProfile "
    OnClick
    = " UpdateProfile "
    Runat
    = " Server " />
    < hr />
    < b > Username: </ b >
    < asp:Label
    id
    = " lblUsername "
    Runat
    = " Server " />
    < br />
    < b > FavoriteColor: </ b >
    < asp:Label
    id
    = " lblFavoriteColor "
    Runat
    = " Server " />

    </ form >
    </ body >
    </ html >

    当你打开第一个页面时,UserName的值是一个随机生成的唯一识别号(见图3)。当你按下Login按钮后,你就完成了身份认证,它是通过用户票据(User Bill)完成的。


    图3 使用匿名和认证profile

    列表10的页面中包含一个用于更新FavoriteColor的表单,要注意的是,在你登录登出的时候,会分别生成两个不同的profile。例如当你先登录,后登出的话,那么系统会生成一个随机的唯一识别号。

    在很多情况下,你需要把匿名profile迁移到认证profile状态,如果你需要迁移profile属性值的话,你可以利用 ProfileModule类的MigrateAnonymous事件完成该任务,该事件只能在Global.asax文件中进行处理。列表11中的 Global.asax演示了你如何才能实现FavoriteColor属性的迁移。

    列表 11 .Global.asax(VisualBasic.NET)

    < %@ApplicationLanguage = " VB " % >
    < scriptrunat = " server " >

    Sub Profile_MigrateAnonymous( ByVal s As Object ,_
    ByVal e As ProfileMigrateEventArgs)
    Dim anonProfile As ProfileCommon = _
    Profile.GetProfile(e.AnonymousId)
    Profile.FavoriteColor
    = anonProfile.FavoriteColor
    EndSub
    </ script >

    列表 11 .Global.asax(C#)

    <% @ApplicationLanguage = " C# " %>
    < scriptrunat = " server " >

    void Profile_MigrateAnonymous(Objects,
    ProfileMigrateEventArgse)
    {
    ProfileCommonanonProfile
    =
    Profile.GetProfile(e.AnonymousId);
    Profile.FavoriteColor
    = anonProfile.FavoriteColor;
    }
    </ script >

    通过Profile类的GetProfile()方法你可以获得匿名profile,该方法接收一个唯一识别号,并且返回与唯一识别号对应的profile。ProfileMigrateEventArgs对象包含一个匿名识别号。

    配置Profile Provider
    默认情况下,profile被保存在sqlserver 2005 express数据库,它位于App_Data目录中,这或许在你开发一些普通的asp.net应用程序时是没有问题的,但很有可能,你需要把你的应用程序的profile保存在另一个数据库中,比如一个完整版的SqlServer 2005的实例中,而该数据库又位于你局域网的某个位置。

    Profile使用Provider模式,通过修改web.config或machine.config的设置来告诉系统把信息存储在哪里。
    ASP.NET本身配了一个profile provider,叫SqlProfileProvider。如果你感到困惑,你可以通过继承ProfileProvider基类来创建一个自己的 provider。例如,你可以创建一个基于Oracle数据库或MySql数据库的Provider。在这里,我们将只讨论最简单的方法,即通过SqlServer数据库来保存profile信息。

    要使用Microsoft SQL Server存储profile信息,必须完成两个步骤。首先,你必须安装SQL Server数据库,然后你必须重新设置配置文件。

    ASP.NET 2.0框架提供了一个用于配置SQL Server来存储Profile信息的工具,该工具叫做aspnet_regsql,它位于Windows\Microsoft.NET\ Framework\[.NET版本号]。执行该工具后,你会看到图4中的ASP.NET SQL Server安装向导。

    图4 使用ASP.NET SQL Server安装程序

    SQL Server安装向导会指导你完成必要的步骤,完成这些步骤后,向导会自动创建用于存储profile信息的存储过程和表结构。

    在你完成SQL Server数据库的配置后,你需要修改web.config或machine.config中的数据库连接设置来指向服务器上的SQL Server数据库,本例中该数据库的实例名为MyServer,列表12列出了该配置文件。

    列表 12.Web.Config

    < configuration >
    < connectionStrings >
    < add
    name ="myConnectionString"
    connectionString
    =
    "Server=MyServer;Trusted_Connection=true;database=MyDatabase"
    />
    </ connectionStrings >
    < system .web >
    < anonymousIdentification enabled ="true" />
    < profile defaultProvider ="MyProfileProvider" >
    < providers >
    < add
    name ="MyProfileProvider"
    type
    ="System.Web.Profile.SqlProfileProvider"
    connectionStringName
    ="myConnectionString" />
    </ providers >
    < properties >
    < add
    name ="FirstName"
    allowAnonymous
    ="true" />
    < add
    name ="LastName"
    allowAnonymous
    ="true" />
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    在列表12中的profile配置中,包含了一个defaultProvider特性,这个特性指向一个叫MyProfileProvider的 profile provider,而这个provider定义是在profile标记的<providers>节中完成的。 MyProfileProvider则使用一个叫MyConnectionString的连接字符串完成数据库连接,并保存profile信息到数据库中。MyConnectionString可以在位于web.config开头的<connectionStrings>节中找到。

    管理profile并生成profile报告
    Profile会对象自动保存用户profile信息,这既是好事业是坏事。说它是好事,是因为你不需要写存储信息的所有逻辑代码,说它是坏事,是因为这样可能造成一大堆无用的信息被保存在数据库中。

    幸运的是,ASP.NET 2.0框架包含一个叫做ProfileManager的类,你可以使用它来管理profile信息。它包含了相当多的方法使你能够有效地管理profile并且生成profile报表,下面列出了一些该类的重要方法:
    • DeleteInactiveProfiles. 删除一个特定日期之前的所有profile
    • DeleteProfile. 删除特定用户的profile
    • DeleteProfiles. 删除一个profile集合
    • FindInactiveProfilesByUserName. 返回一个ProfileInfo对象的集合,该集合表示的profile是匹配一个某个名字,并且是从某个特定日期开始一直未被使用
    • FindProfilesByUserName. 返回一个ProfileInfo对象集合,该集合与某个用户名相关联
    • GetAllInactiveProfiles. 返回一个ProfileInfo对象集合,该集合表示的profile是从某个特定日期开始一直未被使用的profile
    • GetAllProfiles. 返回一个ProfileInfo对象集合,该集合表示所有的profile
    • GetNumberOfInactiveProfiles. 返回从某个特定日期开始一直未被使用的profile的数量
    • GetNumberOfProfiles. 返回profile总数
    这些方法中,虽然所有的方法都返回一个ProfileInfo对象集合,但没有一个返回一个真正的profile。ProfileInfo对象包含以下profile属性
    • IsAnonymous. 表示该profile是否为匿名profile
    • LastActivityDate. 最后一次profile被访问的时间和日期
    • LastUpdatedDate. 最后一次profile被升级的时间和日期
    • Size. 表示profile的大小,这是在profile provider存储profile信息时记录的
    • UserName. 与profile关联的用户名
    ProfileManager有几个方法提供了额外的参数用于支持分页。例如,GetAllProfiles方法的一个重载版本就提供了专门用于设置页面索引、页面大小、总共的记录数的参数,这些参数在需要分页的页面中十分有用。

    ProfileManager既可以在asp.net页面下使用,也可以在其它程序中使用。例如,你可能需要做一个控制台程序用于每天清除长时间未使用的 profile。列表14的控制台程序会删除七天未使用的profile,你可以使用Windows计划任务(Windows Scheduled Tasks)来安排该程序的执行时间。

    列表 14 .DeleteInactiveProfiles(VisualBasic.NET)

    Imports System.Web.Profile

    Public Class DeleteInactiveProfiles

    Public Shared Sub Main()
    Dim deleted As Integer
    deleted
    =
    ProfileManager.DeleteInactiveProfiles(
    ProfileAuthenticationOption.All,
    DateTime.Now.AddDays(
    - 7 ))
    Console.WriteLine(
    " Deleted " & deleted & " profiles " )
    EndSub

    EndClass

    列表 14 .DeleteInactiveProfiles(C#)

    using System;
    using System.Web.Profile;

    public class DeleteInactiveProfiles
    {
    public static void Main()
    {
    int deleted = 0 ;
    deleted
    =
    ProfileManager.DeleteInactiveProfiles(
    ProfileAuthenticationOption.All,
    DateTime.Now.AddDays(
    - 7 ));
    Console.WriteLine(
    " Deleted " +
    deleted.ToString()
    + " profiles " );
    }
    }

    你可以通过一下的命令行指令对列表14进行编译

    [VisualBasic.NET]
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\vbc
    /r:System.Web.dllDeleteInactiveProfiles.vb

    [C#]
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\csc
    DeleteInactiveProfiles.cs

    你还可以使用ProfileManager类生成profile信息报表。例如,如果你打算生成一个用户调查的报表,你可以把用户调查保存在profile中,这样就可以轻易的使用ProfileManager生成你需要的报表。

    列表15中的web.config中有三个属性: SurveyCompleted、FavoriteLanguage FavoriteEnvironment

    Listing15.Web.Config

    < configuration xmlns ="http://schemas.microsoft.com/.NetConfiguration/v2.0" >

    < system .web >


    < anonymousIdentification enabled ="true" />

    < profile >
    < properties >
    < add
    name ="SurveyCompleted"
    type
    ="Boolean"
    allowAnonymous
    ="true" />
    < add
    name ="FavoriteLanguage"
    allowAnonymous
    ="true" />
    < add
    name ="FavoriteEnvironment"
    allowAnonymous
    ="true" />
    </ properties >
    </ profile >
    </ system.web >
    </ configuration >

    列表16中的页面演示了一个简单的用户调查。该页面包含两个Panel控件,第一个控件中有两个调查问题,当用户完成调查后,第一个控件会自动隐藏,而第二个会显示出来,第二个Panel有一段表示感谢的文字。

    列表16.Survey.aspx(VisualBasic.NET)

    <% @PageLanguage = " VB " %>
    < script runat ="server" >

    SubSaveSurvey(ByValsAsObject,ByValeAsEventArgs)
    Profile.FavoriteLanguage
    = rdlLanguage.SelectedItem.Text
    Profile.FavoriteEnvironment
    = rdlEnvironment.SelectedItem.Text
    Profile.SurveyCompleted
    = True
    EndSub

    SubPage_PreRender()
    IfProfile.SurveyCompletedThen
    pnlSurvey.Visible
    = False
    pnlSurveyCompleted.Visible
    = True
    Else
    pnlSurvey.Visible
    = True
    pnlSurveyCompleted.Visible
    = False
    EndIf
    EndSub

    </ script >

    < html >
    < head >
    < title > Survey </ title >
    </ head >
    < body >
    < form id ="form1" runat ="server" >

    < asp:Panel ID ="pnlSurvey" Runat ="Server" >
    Whatisyourfavoriteprogramminglanguage?
    < br />
    < asp:RadioButtonList
    id ="rdlLanguage"
    runat
    ="Server" >
    < asp:ListItem Text ="VB.NET" Selected ="True" />
    < asp:ListItem Text ="C#" />
    < asp:ListItem Text ="J#" />
    </ asp:RadioButtonList >
    < p > &nbsp; </ p >
    Whatisyourfavoritedevelopmentenvironment?
    < br />
    < asp:RadioButtonList
    id ="rdlEnvironment"
    runat
    ="Server" >
    < asp:ListItem Text ="VS.NET" Selected ="True" />
    < asp:ListItem Text ="WebMatrix" />
    < asp:ListItem Text ="Notepad" />
    </ asp:RadioButtonList >
    < p > &nbsp; </ p >
    < asp:Button
    Text ="SubmitSurvey"
    Onclick
    ="SaveSurvey"
    Runat
    ="Server" />
    </ asp:Panel >
    < asp:Panel ID ="pnlSurveyCompleted" Runat ="Server" >
    Thankyouforcompletingthesurvey!
    </ asp:Panel >
    </ form >
    </ body >
    </ html >

    列表 16. Survey.aspx(C#)

    <% @PageLanguage = " C# " %>
    < script runat ="server" >

    void SaveSurvey(Objects,EventArgse)
    {
    Profile.FavoriteLanguage
    = rdlLanguage.SelectedItem.Text;
    Profile.FavoriteEnvironment
    = rdlEnvironment.SelectedItem.Text;
    Profile.SurveyCompleted
    = true ;
    }

    void Page_PreRender()
    {
    if (Profile.SurveyCompleted)
    {
    pnlSurvey.Visible
    = false ;
    pnlSurveyCompleted.Visible
    = true ;
    }
    else
    {
    pnlSurvey.Visible
    = true ;
    pnlSurveyCompleted.Visible
    = false ;
    }
    }

    </ script >

    < html >
    < head >
    < title > Survey </ title >
    </ head >
    < body >
    < form id ="form1" runat ="server" >

    < asp:Panel ID ="pnlSurvey" Runat ="Server" >
    Whatisyourfavoriteprogramminglanguage?
    < br />
    < asp:RadioButtonList
    id ="rdlLanguage"
    runat
    ="Server" >
    < asp:ListItem Text ="VB.NET" Selected ="True" />
    < asp:ListItem Text ="C#" />
    < asp:ListItem Text ="J#" />
    </ asp:RadioButtonList >
    < p > &nbsp; </ p >
    Whatisyourfavoritedevelopmentenvironment?
    < br />
    < asp:RadioButtonList
    id ="rdlEnvironment"
    runat
    ="Server" >
    < asp:ListItem Text ="VS.NET" Selected ="True" />
    < asp:ListItem Text ="WebMatrix" />
    < asp:ListItem Text ="Notepad" />
    </ asp:RadioButtonList >
    < p > &nbsp; </ p >
    < asp:Button ID ="Button1"
    Text
    ="SubmitSurvey"
    Onclick
    ="SaveSurvey"
    Runat
    ="Server" />
    </ asp:Panel >
    < asp:Panel ID ="pnlSurveyCompleted" Runat ="Server" >
    Thankyouforcompletingthesurvey!
    </ asp:Panel >
    </ form >
    </ body >
    </ html >

    列表17中显示调查的结果,该页面中有一个显示ProfileInfo对象集合的GridView控件,该ProfileInfo对象集合是由 ProfileManager的GetAllProfiles方法获得的。当你点击GridView中的任意一行的Select链接时,你将会看到对这个问题的调查结果,该调查结果是由Profile类的GetProfile方法获得的。


    图5 显示调查结果

    列表 17. SurveyResults.aspx(VisualBasic.NET)

    <% @PageLanguage = " VB " %>
    < script runat ="server" >

    SubPage_Load()
    ResultsGrid.DataSource
    = _
    ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All)
    ResultsGrid.DataBind()
    EndSub

    SubDisplayProfileDetails(ByValsAsObject,ByValeAsEventArgs)
    DimSelectedProfileAsProfileCommon
    SelectedProfile
    = Profile.GetProfile(ResultsGrid.SelectedValue)
    lblLanguage.Text
    = SelectedProfile.FavoriteLanguage
    lblEnvironment.Text
    = SelectedProfile.FavoriteEnvironment
    EndSub

    </ script >

    < html >
    < head >
    < title > SurveyResults </ title >
    </ head >
    < body >
    < form id ="form1" runat ="server" >
    < h2 > SurveyResults </ h2 >
    < asp:GridView
    id ="ResultsGrid"
    DataKeyNames
    ="UserName"
    AutoGenerateSelectButton
    ="true"
    OnSelectedIndexChanged
    ="DisplayProfileDetails"
    SelectedRowStyle-BackColor
    ="LightYellow"
    Runat
    ="Server" />
    < p > &nbsp; </ p >
    < h2 > SurveyDetails </ h2 >
    < b > FavoriteLanguage: </ b >
    < asp:Label
    id ="lblLanguage"
    Runat
    ="Server" />
    < br />
    < b > FavoriteEnvironment: </ b >
    < asp:Label
    id ="lblEnvironment"
    Runat
    ="Server" />

    </ form >
    </ body >
    </ html >

    列表 17.SurveyResults.aspx(C#)

    <% @PageLanguage = " C# " %>
    < script runat ="server" >

    void Page_Load()
    {
    ResultsGrid.DataSource
    =
    ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);
    ResultsGrid.DataBind();
    }

    void DisplayProfileDetails(Objects,EventArgse)
    {
    ProfileCommonSelectedProfile
    =
    Profile.GetProfile(ResultsGrid.SelectedValue.ToString());
    lblLanguage.Text
    = SelectedProfile.FavoriteLanguage;
    lblEnvironment.Text
    = SelectedProfile.FavoriteEnvironment;
    }

    </ script >

    < html >
    < head >
    < title > SurveyResults </ title >
    </ head >
    < body >
    < form id ="form1" runat ="server" >
    < h2 > SurveyResults </ h2 >
    < asp:GridView
    id ="ResultsGrid"
    DataKeyNames
    ="UserName"
    AutoGenerateSelectButton
    ="true"
    OnSelectedIndexChanged
    ="DisplayProfileDetails"
    SelectedRowStyle-BackColor
    ="LightYellow"
    Runat
    ="Server" />
    < p > &nbsp; </ p >
    < h2 > SurveyDetails </ h2 >
    < b > FavoriteLanguage: </ b >
    < asp:Label
    id ="lblLanguage"
    Runat
    ="Server" />
    < br />
    < b > FavoriteEnvironment: </ b >
    < asp:Label
    id ="lblEnvironment"
    Runat
    ="Server" />
    </ form >
    </ body >
    </ html >


    总结
    当建立Web应用程序时,我依旧花费了大量的时间和精力用于做一些大伤脑筋的事情。其中的一个任务就是写一些用于从数据库存储和获得用户信息的代码。虽然 Profile对象引入的都是asp.net 1.0中可以实现的功能,但是这个新特性帮助我们从乏味的编码工作中解脱出来,这样也能让我们在写Web应用程序的过程中,把更多的精力放在我们更感兴趣的事情上。
    展开全文
  • ASP.NET揭秘(第二版) ASP.NET UNLEASHED Second Edition 作者:[美]Stephen Walther 译者:汤涛 出版社:中国电力出版社 内容简介: 本书是美国亚马逊网站同类书长期销售冠军,并受到微软ASP.NET小组项目经理Rob...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,067
精华内容 426
关键字:

walther