人生是一场不能存盘的RPG,我只能尽量多搞几个Screenshot

July 25, 2007

IE Language Preference and Culture in Page Directive

Filed under: ASP.NET

Create a web application with chinese and english resource strings.resx and strings.zh-CN.resx.
Read resource with following code:

ResourceManager L10N = new ResourceManager(”WebAppCulture.strings”, typeof(_Default).Assembly);
this.Label1.Text = L10N.GetString(”Name”);

this.Label2.Text = “Culture: “+Thread.CurrentThread.CurrentCulture.Name;
this.Label3.Text = “UICulture: ” + Thread.CurrentThread.CurrentUICulture.Name;

相关设定有:
OS
IE
Page:Culture
Page:UICulture
结果有:
CurrentThread.CurrentCulture
CurrentThread.CurrentUICulture

结论,IE Language Preference 和Page:Culture相互作用,影响当前线程的Culture.对UICulture无影响
如果不指定Page:Culture, CurrentThread.CurrentCulture为OS的culture
如果指定了Page:Culture, CurrentThread.CurrentCulture为IE指定的culture
如果不支持IE指定的culture, CurrentThread.CurrentCulture为Page:Culture指定的culture

如果不指定Page:UICulture, CurrentThread.CurrentUICulture为OS指定的culture
如果指定了Page:UICulture, CurrentThread.CurrentUICulture为Page:UICulture指定的culture

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/localization/culture.aspx#autoculture
If the first language in the list matches the name of a neutral culture supported by the .NET Framework, ASP.NET will try to use the function CultureInfo.CreateSpecificCulture() to create a specific culture for the purpose of formatting.
If the first language in the list isn’t a culture supported by the .NET Framework, ASP.NET will fall back to the culture specified after the colon in the Culture declaration.

June 18, 2007

window.onload and body onload =

Filed under: ASP.NET

本文测试环境为IE7,vs2005
<html>
<head>
<title>Untitled Page</title>
<script type=”text/javascript”>
function pageLoaded()
{
window.status=”Page loaded”;
}

</script>
</head>
<body onload=”pageLoaded();”>
<script type=”text/javascript”>
window.onload=windowLoad;

function windowLoad()
{
window.status=”Window loaded”;
}
</script>
</body>
</html>
当这个html页面被加载时,windowLoad()会被执行,而pageLoaded()不会被执行.
如果把JavaScript代码全部放在<Head>中
<html>
<head>
<title>Untitled Page</title>
<script type=”text/javascript”>
function pageLoaded()
{
window.status=”Page loaded”;
}
window.onload=windowLoad;

function windowLoad()
{
window.status=”Window loaded”;
}
</script>
</head>
<body onload=”pageLoaded();”>
</body>
</html>
则pageLoaded()执行而windowLoad()不执行.

MSDN对onload有如下描述
The onload attribute of the body object sets an onload event handler for the window.

可见,在IE解析html文件时,后出现的设定会覆盖前边的设定.即window.onload
和onload=” “,后出现者起作用.

如果要两者都执行,则要使用attachEvent来指定window load时要运行的函数:
if (document.all){
window.attachEvent(’onload’,FuncName)
}
else{
window.addEventListener(’load’,FuncName,false);
}

June 5, 2007

AJAX Components

Filed under: ASP.NET

http://ajax.asp.net/about/default.aspx?tabid=47

1.ASP.NET 2.0 AJAX Extensions and Document, Source Code
扩展ASP.NET 2.0 server-side从而提供了和ASP.NET兼容的AJAX编程模型

2.Microsoft AJAX Library
JaveScript library

3.ASP.NET AJAX Control Toolkit
ASP.NET AJAX control SDK以及sample
在线演示http://ajax.asp.net/ajaxtoolkit/

4.ASP.NET Futures

5.Sample Applications

June 4, 2007

How to get IIS version

Filed under: ASP.NET

I found this registry in a web applcation setup project.

registry path:
HKLM\SYSTEM\CurrentControlSet\Services\W3SVC\Prarameters
value: MajorVersion

May 29, 2007

禁止IE Cache页面

Filed under: ASP.NET

在页面中使用HTML标记:
<HEAD>
<META http-equiv=Pragma content=no-cache>
<META http-equiv=Cache-Control content=no-cache>
<META HTTP-EQUIV=”Expires” CONTENT=”-1″>

CACHE-CONTROL (49) Cache control directives.
PRAGMA (17) Implementation-specific directives that might apply to any recipient along the request/response chain.
EXPIRES (10) Date and time after which the resource should be considered outdated.

HOWTO:防止在 Internet Explorer 中进行缓存
http://support.microsoft.com/kb/234067/zh-cn

May 28, 2007

ASP.NET 中的各种Control

Filed under: ASP.NET

ASP.NET Web Server Controls Overview
http://msdn2.microsoft.com/en-us/library/zsyt68f1.aspx

Overview of user controls vs. custom controls
http://support.microsoft.com/kb/893667/en-us

UserControl和WebControl 的比较
UserControl用于单个程序,WebControl用于多个程序,易于发布
WebControl缺乏对Design Time的支持
UserControl适用于固定布局,WebControl适用于动态布局

May 11, 2007

XSS的资料收集

Filed under: ASP.NET

常见的手法:
在页面或地址栏中写入javascript代码,经过HEX编码编码後会更隐蔽.
javaScript的用途:
盗取当前用户的cookie信息
通过XMLHttpRequest() 整蛊web server.

如何检查XSS
在各种输入接口输入或者在GET的URL参数中加入: “><img src=1 onerror=javascript:alert(document.cookie)><” 如果有js alert执行,说明可能有潜在漏洞。

防御
过滤非法的输入
把user提交的某些可以在浏览器中执行的代码encode後再发送给请求者

The Cross Site Scripting (XSS) FAQ
http://www.cgisecurity.com/articles/xss-faq.shtml

How To: Prevent Cross-Site Scripting in ASP.NET
http://msdn2.microsoft.com/en-us/library/ms998274.aspx

MS Anti-Cross Site Scripting Library V1.5
http://blog.joycode.com/saucer/archive/2006/11/21/87365.aspx
http://msdn2.microsoft.com/en-us/security/aa973814.aspx

March 6, 2007

IIS 7

Filed under: ASP.NET

出自:IIS 7.0 探索用于 Windows Vista 的 Web 服务器和更多内容

1> IIS 7.0 的核心完全模块化,由 40 多项功能组成,这些功能基于一个新的可扩展层,这个层
允许.NET Framework 来扩展或替换。

2> IIS元数据被基于分布式 XML 配置文件applicationHost.config 文件替换.该文件包含服务器级
别的配置默认设置.在 IIS 7.0 中,配置系统是完全可扩展的。新模块可以添加它们自己的配置
架构,从而使应用程序能够与 IIS 和 ASP.NET一起配置其功能

3>新的图形化 IIS 管理器管理工具取代了InetMgr.exe MMC 管理单元.可将自定义管理 UI 添加到工具中
http://iis.net/default.aspx?tabid=7&subtabid=73
IIS 7.0 提供了 appcmd.exe 命令行工具
http://iis.net/default.aspx?tabid=2&subtabid=25&i=954&p=1

4>可以利用 Microsoft.Web.Administration API 通过 .NET 应用程序管理IIS
iis.net/default.aspx?tabid=2&subtabid=25&i=1076。

5>在 IIS 7.0 中,ASP.NET 有两个版本:经典模式和集成模式。
经典模式的工作方式与它在以前版本的 IIS 中完全相同。
集成模式是新的平台默认设置,它使用全新的引擎来提供与 IIS Web 服务器前所未有的集成。
在集成模式下,可以用 ASP.NET API 开发 IIS 7.0 模块,这样的模块可以直接与 Web 服务
器集成,并且能够提供用基本 C++ API 即可实现的几乎所有服务。
http://mvolo.com/2006/11/10/stopping-hotlinking-with-iis-and-aspnet.aspx

6>URL 授权与 ASP.NET 2.0 成员身份和角色管理功能无缝集成在一起

7>新的XML日志文件

8>通过 appcmd.exe 命令行工具或使用 Microsoft.Web.Administration API 以编程方式访问
服务器的实时状态

9>Windows Vista 上的 IIS 受限于每次 10 个并发请求

February 13, 2007

模拟一个文件被cut后Icon的半透明效果

Filed under: ASP.NET

在一个tree 空间中进行的实验:
function AfterNodeSelChange(treeId, nodeId)
{
var selectNode = document.getElementById(nodeId);
var subElements = selectNode.children;
for(x=0; x<subElements.length; x++)
{
var subElement = subElements.item(x);
if(subElement.tagName == ‘IMG’)
{
if(subElement.src != ‘’)
{
subElement.style.cssText = “filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50);”;
}
}
}

//selectNode.filters.item(”DXImageTransform.Microsoft.Alpha”).opacity=50;
}

February 8, 2007

About Infargistics UltraWebTree NodeChanged Event

Filed under: ASP.NET

UltraWebTree在缺省情况下,
<AutoPostBackFlags NodeChanged=”false” /> 就是在client edit一个node,并不会引发
server 端的NodeChanged event,但奇怪的是如果给NodeClicked event 指定了一个
event handler, NodeChanged event就会被触发,神奇.

February 5, 2007

在Client JavaScript中支持多语言

Filed under: ASP.NET

一个小小的Trick:
在server端读出语言相关的字符串资源并注入到client端:
System.Text.StringBuilder sb = new System.Text.StringBuilder();

sb.Append(”<script type=’text/javascript’>”);
sb.Append(”var I18N = new Array();\n”);
sb.AppendFormat(”I18N[’{0}’] = ‘{1}’;\n”, “my_String_1″, GetResourceString(”my_String_1″));
sb.AppendFormat(”I18N[’{0}’] = ‘{1}’;\n”, “my_String_2″, GetResourceString(”my_String_2″));
sb.Append(”</script>”);

ClientScript.RegisterClientScriptBlock(GetType(), “I18N”, sb.ToString());

在客户端进行读取:
function getI18N(resourceId)
{

return I18N[resourceId];

}

var myString1 = getI18N(”myString_1″))

February 3, 2007

如何在关闭ModalDialog时避免打开新的IE窗口

Filed under: ASP.NET

很多时候,asp.net程序需要弹出一个Modal Dialg来收集用户的输入,这个Modal Dialg会有”OK”,”Cancel”两个button,使用javascript关闭dialog,但是有一些猫腻会导致在Modal Dialg中点击了”OK”或”Cancel”后,不但dialog不关闭反而打开一个新的IE.

原因就在于如果点击button导致了页面的提交,就会出现上述情况,如果这个Modal Dialg所对应的aspx页面是用vs自动生成,asp:button缺省就会提交页面,
此时如果在页面的<head></head>中添加<base target=_self></base>,就可以防止打开新的IE,但故事并没有结束,如果不幸在页面的form中,指定了
<form id=”form1″ runat=”server” target=”_self”>
用上述方法也阻止不了新的IE弹出.此时,需要使用更强大的手段:及在page load时指定form1的target:
javaScript:
function handleOnLoad()
{
window.name = ‘dialognew’ + Number(new Date()).toString();
document.dialognew.target = window.name;
}
form:
<form id=”dialognew” method=”post” target=”_self” runat=”server”>

January 9, 2007

vs2005 sp1 之后的 Server Application Unavailable

Filed under: ASP.NET

在装了 vs2005 sp1 之后,遭遇错误
Server Application Unavailable

The web application you are attempting to access on this web server is currently unavailable.
Please hit the “Refresh” button in your web browser to retry your request.
在产看了Eventlog(Application)之后,看到:

aspnet_wp.exe could not be launched because the username and/or password supplied in the
processModel section of the config file are invalid.

aspnet_wp.exe could not be started. The error code for the failure is 80004005.

这两个错误成对出现,由此怀疑 ASPNET 这个帐号的设置有问题.
经过一番折腾,得出解决方案:
1. 删除ASPNET帐号,
2. 为了保险,运行 aspnet_regiis -u, 此过程并不能删除ASPNET帐号,实在有些令人不解
3. 运行 aspnet_regiis -i, 重新安装ASP.net, 此过程会生成ASPNET帐号.
4. 运行 iisreset

December 5, 2006

[HTML] Disabled control can’t be submited!

Filed under: ASP.NET

Forms in HTML documents.
http://www.w3.org/TR/html4/interact/forms.html#adef-readonly
17.12 Disabled and read-only controls
17.13.2 Successful controls

TextBox can be used with readonly attribute.
Checkbox will be used with javeScript “return false;” to simulate the readonly state.

December 4, 2006

Application_Start 中的断点

Filed under: ASP.NET

我在Application_Start中加了一个断点,第一次使用f5运行程序,断点可以工作,
然后终止程序,再运行,断点就不工作了,重起IIS,断点又可以工作,
原因不明.

November 23, 2006

Create the group label in the dropdown list.

Filed under: ASP.NET

http://www.w3schools.com/tags/tag_optgroup.asp
<select>
<optgroup label=”Swedish Cars”>
<option value =”volvo”>Volvo</option>
<option value =”saab”>Saab</option>
</optgroup>
<optgroup label=”German Cars”>
<option value =”mercedes”>Mercedes</option>
<option value =”audi”>Audi</option>
</optgroup>
</select>

November 11, 2006

RegisterClientScriptBlock and RegisterStartupScript

Filed under: ASP.NET

这两个函数在asp.net1.1中是Page class上的方法.
在asp.net2.0中,变成了ClientScriptManager class上的方法,一般用法是在Page Load事件中调用:
this.ClientScript.RegisterClientScriptBlock
this.ClientScript.RegisterStartupScript

与此配套的函数还有
IsClientScriptBlockRegistered
IsStartupScriptRegistered
设想你写了一个web control, 需要一段client javaScript,如果user 在一个form上创建了这个control
多次,如果没有这个判断,就会生成多份代码.但在page上只注册一段代码可以不调用这个方法,
使用相同的type和key注册代码会被忽略.

这两个方法唯一的不同在于
RegisterClientScriptBlock()在Web 窗体的开始处,<form runat=”server”>之后生成代码,
而RegisterStartupScript()在 Web 窗体的结尾处,</form>标识之前生成代码。
从名称上看,asp.net 希望RegisterStartupScript生成的代码用于在page刚刚完成加载,OnLoad 事件
尚未触发前执行.

–参考
从 ASP.NET 服务器控件插入客户端脚本
http://www.microsoft.com/china/MSDN/library/archives/library/DNAspp/html/aspnet-injectclientsidesc.asp#aspnet-injectclientsidesc_topic3

Adding Client-Side Message Boxes in your ASP.NET Web
http://aspnet.4guysfromrolla.com/articles/021104-1.2.aspx

November 10, 2006

RegisterClientScriptBlock vs RegisterStartupScript

Filed under: ASP.NET

RegisterClientScriptBlock一般返回的是客户端函数的包装,而RegisterStartupScript返回得函数在document装载完成后会执行,类似于body onload=”f()”里面的函数;

这两个方法在客户端呈现的代码位置不同,RegisterClientScriptBlock在<form runat=server>之后,而RegisterStartupScript在</form>之前。

October 13, 2006

收集Scott Mitchell的文章

Filed under: ASP.NET

Online Articles
http://www.4guysfromrolla.com/ScottMitchell.shtml

Working with data in asp.net 2.0
http://www.asp.net/learn/dataaccess/default.aspx?tabid=63
中文版:http://www.cnblogs.com/lovecherry/archive/2006/07/02/440840.html

Blog : {Scott on Writing}
http://www.scottonwriting.net/sowBlog/

Scott’s Code Project
http://www.scottonwriting.net/sowBlog/CodeProjects.htm

September 12, 2006

IIS 7.0 RC1的新feature

Filed under: ASP.NET

原文见.
http://weblogs.asp.net/scottgu/archive/2006/09/07/IIS-7.0-RC1.aspx

1.可以create多个web site(IIS6也可以啊?)
2.IIS 管理和 asp.net管理被放在一起
3.IIS 使用和asp.net类似的web.conifg,发布时不再需要使用admin script去设置IIS
4.IIS 管理工具提供了”delegated administration”,可用于远程管理.
5.IIS 管理工具的UI可扩展,从而可以管理自己写的HTTP runtime modules.
6.IIS 管理工具集成了ASP.NET 2.0 Membership 管理
7.IIS 5 中在一个web site下只能create Virtual Directory,
IIS 6 中在一个web site下可以create website 或 Virtual Directory,
可设置一个VD的Application Setting,如果设置了Application Setting,VD的图标会变化.
在IIS 7 中,明确区分了Application和VD,在web site的context menu 上有两个选项:
create vd 和 create application.

September 8, 2006

防止IIS out of memory

Filed under: ASP.NET

有关System.OutOfMemoryException,google一下,会找到很多究其本质,System.OutOfMemoryException出现有两种可能:
1.在我们试图新建一个对象时,而CLR又找不到任何可用内存,GC也找不到可释放的对象时被抛出,应用程序此时可捕获该异常.
2.CLR需要内存时,而却系统却不能提供,也会抛出该异常,此时,应用程序不能捕获该异常.

思路:给CLR更多的内存.减少应用程序所占的内存,及时释放无用的对象.对于ASP.NET程序,
CLR host在 asp.net的工作进程中,问题就转化为如何让asp.net的工作进程有更多的用户
地址空间.同时要设法利用IIS的一些功能来回收工作进程占用的内存.

————————————————————————————–
1. Enabling 4GT RAM Tuning
————————————————————————————–
此配置只在Windows 2000 Advanced Server,Data Center及Windows Server 2003以上才支持.
该模型可提供 3GB 的用户地址空间,另 1GB 保留给内核,通过在 boot.ini 中添加 /3GB 选项来启用该模型。

注意:Windows Server 2003 上支持的最大内存为 4 GB。但是,Windows Server 2003 Enterprise Edition
支持 32 GB 的物理 RAM。使用物理地址扩展 (PAE) 功能,Windows Server 2003 Datacenter Edition 可支持
64 GB 的物理内存。
对于下列系统,可以在 Boot.ini 文件中使用 3 GB 开关:
Microsoft Windows Server 2003 Standard Edition, but only in non-production environments.
Microsoft Windows Server 2003 Enterprise Edition 或
Microsoft Windows Server 2003 Datacenter Edition。

在WindowsXP和Windows Server 2003中提供一个新的启动参数/USERVA,必须和/3GB参数联合使用,
比如: 3GB /USERVA=2500 的意思就是配置2.5G的内存地址空间预留给用户内存空间,1.5G的留给核心
内存空间.


What Is 4GT?
http://technet2.microsoft.com/WindowsServer/en/library/cab49770-0239-4a8b-90c1-612e70b729c81033.mspx

How 4GT Works
http://technet2.microsoft.com/WindowsServer/en/library/edc9f27d-76fb-4139-9555-20acc684c3af1033.mspx

You may receive the “System.OutOfMemoryException” error message when you view ASP.NET pages on a server that has 3 gigabytes of RAM
http://support.microsoft.com/default.aspx?scid=kb;en-us;820108

如何配置 SQL Server 以便使用 2 GB 以上的物理内存
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;274750

结论: 此选项可以使CLR有更多的可分配内存,我们使用的是windows 2003标准版,不推荐用这个参数.

————————————————————————————–
2. 设置.NET machine.config file的<processModel>或配置IIS,及时释放工作进程.
————————————————————————————–
<processModel>中有的一些配置:

memoryLimit(default=60),指定了ASP.NET进程(IIS5中为aspnet_wp,IIS6中为w3wp)
能够使用所有物理内存的百分比。当超过这个限额时,IIS回收工作进程,并创建一个新
的进程去负责应付Http请求。
*注意,如果将session存放在进程中,session会丢失.

当我们有很大内存时,memoryLimit这个值是需要进行适当的调整的。比如一台4G内存的服务器,
那么4G*60%=2.4G。但是,对于Win32操作系统,一个进程所能占用的所有内存空间只有2G。
当ASP.NET进程占用的内存开始达到2G时,由于它并没有达到2.4G的”回收阈值”,所以IIS不会
启动recycle进程操作,但是由于Win32的限制,实际上已经不能给这个进程分配更多的内存了,
于是,OutOfMemoryException就很可能会被抛出了。为了避免这样的情况,我们就必须将”memoryLimit”
适当调小,以让IIS更早的进行进程回收。

微软推荐的ASP.NET进程占用内存是不超过60%物理内存,当使用2GB地址空间时最好使计算出的实
际值不超过800M。

!注意缺省情况下IIS6并不设置内存的使用限制.


Running ASP.NET 1.1 with IIS 6.0
http://www.asp.net/faq/AspNetAndIIS6.aspx#2(非常重要!!)

ASP.NET Performance Monitoring, and When to Alert Administrators
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/monitor_perf.asp

Timeout(default=Infinite),持续运行了timeout指定的时间后,重启 ASP.NET服务

IdleTimeout(default=Infinite),在 idleTimeout 指定的时间内没人的访问,重启 ASP.NET服务

PingTimeout(default =5s),ISAPI extension 会每隔一段时间(PingFrequency, default=30)ping一次
工作进程,如果5秒内无相应,则重启工作进程.

PingFrequency(default =30s)

RequestLimit(default=Infinite),在处理了n个请求后重启工作进程.

这些配置在IIS6中不再由machine.config控制,而是由IIS控制.

如果使用iis5及以下版本需要安装MS提供的IIS5Recycle service
安装说明见http://support.microsoft.com/?id=322350

3. 编程
System.Drawing注意调用dispose
慎用new byte[],最好定义一个比较小的byte数组做为缓存,然后循环使用。

参照
OutOfMemoryException问题的处理
http://www.cnblogs.com/chainet/archive/2005/01/25/97000.html

ASP.NET中的OutOfMemoryException
http://blog.joycode.com/kaneboy/archive/2005/05/07/50409.aspx

Tuning .NET Application Performance
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt17.asp

IIS 6.0 Tuning for Performance
http://www.eggheadcafe.com/articles/20050613.asp

FIX: SetMinThreads and GetMinThreads API Added to Common Language Runtime ThreadPool Class
http://support.microsoft.com/default.aspx?scid=kb;en-us;810259

September 4, 2006

IIS

Filed under: ASP.NET

跟我一起学Visual Studio 2005(12):IIS 5.1_6.0 内幕

UNIX CGI使用一种进程外(out-of-process)执行模型.每次请求都要打开一个进程,
故MS的ISAPI选择了进程内模型(IIS4之前),
所有的操作都基于进程(inetinfo.exe)内执行,缺点在于:
更新程序必须重启IIS
一个程序出错,IIS崩溃
*asp出现于IIS3,asp.dll是ISAPI的扩展实现.

——–IIS4
增加了进程隔离(process isolation),注意这里的隔离以应用程序为单位,和UNIX CGI不同.

进程隔离的缺点
- 进程外应用程序的运行速度可能比进程内应用程序慢很多
- 所有的配置被加载到inteinfo.exe进程空间中.进程外应用程序不能
使用内置的IIS管理对象来访问IIS配置数据库属性.
- 进程外应用程序占用比进程内应用程序更多的内存资源

实现:通过MTS(跨进程处理)和(Web Application Manager,WAM)实现
inteinfo.exe外的新城已WAN_计算机名帐号执行

——-IIS5
提供了三个不同级别的应用程序保护
>低(IIS进程)与IIS的版本1~3最初的单一结构一样,作为WEB服务器进程(inetinfor.exe)的一部分在进程内运行
>中(共用的)作为一个单独的缓冲池进程在inetinfo.exe进程外运行,也就是说,它作为名为dllhost.exe的新
COM+宿主进程内部运行的几个应用程序之一
>高(独立的)在自己的隔离dllhost.exe进程中运行

——-IIS6
IIS 6与IIS 5之间的区别
1. HTTP请求由内核驱动程序HTTP.SYS处理,而不再是inetinfo.exe.
2. 支持两种新的应用程序隔离模型:
>工作进程隔离模型:全新的模型,它将用户开发的所有应用
程序代码与核心IIS服务完全隔离
>IIS 5隔离模型:为IIS 5设计的早期应用程序向后兼容
3.多个应用程序池的支持,可以单独配置每一个池
4.重新改造了WWW服务(W3SVC),包括了一个新的配置和进程管理部分,名为Web管理服务(WAS)
5.其他增强的特性:处理器相似性,运行状况监视,Web园,请求式启动,空闲超时,快速故障保护,工作进程回收,XML配置数据库等

——-IIS6观察:
在ComputerManagement的Services中查看
IIS Admin Service,对应程序为C:\WINDOWS\System32\inetsrv\inetinfo.exe

Web管理服务(W3SVC):World Wide Web Publishing Service,
对应程序为C:\WINDOWS\System32\svchost.exe -k iissvcs

HKLM\System\CurrentControlSet\Services\W3SVC
下的Parameters,有一个名为ServiceDll的value,其值为%systemroot%\System32\inetsrv\iisw3adm.dll
svchost.exe会根据这个记录来加载iisw3adm.dll

使用
netstat -a -b -n 来查看每个端口的侦听程序.
对于80端口,IIS5和IIS6有所不同.
IIS5 为inetinfo.exe
IIS6 为svchost.exe

August 31, 2006

把页面内容作为Email发出

Filed under: ASP.NET

思路:在button的client click中把页面的内容存到一个hidden filed中,在server端的click中读取并发送
asp:Button ID=”Button_SendMail” runat=”server” Text=”SendEmail” OnClientClick=”CellPostBack();” OnClick=”Button_SendMail_Click”

function CellPostBack()
{
var result = document.getElementById(”result”);
var hiddenInfo = document.getElementById(”hiddenInfo”);
//alert(result.innerText);
//hiddenInfo.value = result.innerHTML;
}
protected void Button_SendMail_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(this.hiddenInfo.Value))
this.SendMail(this.hiddenInfo.Value);
}
private void SendMail( string body)
{
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress(”aloneplayer@gmail.com“, “aLONEPLayer”);

smtpClient.Host = “XXXXX”;
//smtpClient.Port = 25;
message.From = fromAddress;
message.To.Add(”aloneplayer@gmail.com“);
message.Subject = “Hi, I’am Riven”;
message.IsBodyHtml = true;
message.Body = body;
smtpClient.Send(message);
}
还需要关闭Asp.net对页面内容的校验
<pages validateRequest=”false”/>

ASP.NET Design Templates

Filed under: ASP.NET

http://msdn.microsoft.com/asp.net/reference/design/templates/default.aspx

August 30, 2006

ASP.NET Themes and Skins

Filed under: ASP.NET

ASP.NET Themes and Skins Overview(MSDN)

Theme and StyleSheetTheme
http://blogs.effectivexaml.net/DaveWheeler/2005/10/theme-and-stylesheettheme.html

What is a StyleSheetTheme?
http://weblogs.asp.net/vimodi/articles/WhatIs_StyleSheetTheme.aspx

A Look at Themes
http://www.gridviewguy.com/ArticleDetails.aspx?articleID=151

1.Theme
Theme由位于一个特殊的路径下的skin,css,image等资源构成,App_Themes下的每一个
foleder包含一个Theme.

2.Theme的作用域:
page theme
Create a new folder named App_Themes in your Web site.
global theme
iisdefaultroot\aspnet_client\system_web\version\Themes

If an application theme has the same name as a global application theme, the page theme takes precedence.

3.Theme的使用:
通过web.config使用
<system.web>
<pages theme=”<ThemeName>”/>
<system.web>

<system.web>
<pages StyleSheetTheme=”Themename” />
</system.web>
或通过代码实现:
void Page_PreInit()
{
Page.Theme = profile.XXX;
Page.Theme = “Green”;
}

4. Theme and StyleSheetTheme的区别:
Simply put, the Theme is applied AFTER the properties are applied to the server-side control,
which means that the settings in the Theme override those of the control. A StyleSheetTheme
is applied BEFORE the properties from the server-side control, and are therefore overridden
by the properties on the control.

For example if StyleSheetTheme contain following default Label skin.
<asp:Label runat=”server” Text=”StyleSheetLabel” Font-Size=”Small” BackColor=”Red” ></asp:Label>

and Page Which has StyleSheetTheme and Theme defiened contain a Label contol as
<asp:Label runat=”server” Text=”PageLabel” Font-Size=”X-Large” ></asp:Label>

and Theme contain following default label skin.
<asp:Label runat=”server” Text=”ThemedLabel” ></asp:Label>

Then the resultant Label shown will look like.
<asp:Label runat=”server” Text=”ThemedLabel” Font-Size=”X-Large” BackColor=”Red” ></asp:Label>

2.Skin
.skin文件包含了一些control属性的定义,如:
skin分为default skin和named skin
default skin被用于每一类control,
<asp:button runat=”server” BackColor=”lightblue” ForeColor=”black” />

control通过SkinId属性来使用named skin,同类control的不同实例可以使用不同的named skin
<asp:imagebutton runat=”server” Imageurl=”Images/button-login.gif” skinid=”login” />
<asp:imagebutton runat=”server” id=”LoginButton” CommandName=”Login” AlternateText=”login” skinid=”login” CssClass=”button”/>
Skin和CSS的比较:
Skin可以用来设置Control的属性,如Style,CSS无此功能.
二者可以协同工作,如,设置Textbox的外观有两种等效的做法:
1.使用Skin来设置control property
In Default.skin:
<asp:TextBox runat=”server” BackColor=”#F7DE8A” BorderColor=”#933126″ BorderStyle=”Solid” BorderWidth=”1px” />

2.使用Skin + CSS
In Styles.css: .textBox {border:1px solid #933126; background-color:#F7DE8A;}
In Default.skin: <asp:TextBox runat=”server” CssClass=”textBox” />

August 24, 2006

Using SQL server to store asp.net session

Filed under: ASP.NET

1.运行%windir%\Microsoft.NET\Framework\version\InstallPersistSqlState.sql
It will create a database named “ASPState”

We should config the permission for asp.net process in this database.

2. Modify the web.config
<system.web>
<sessionState mode=”SQLServer” sqlConnectionString=”data source=servername;user id=uid;password=pwd” cookieless=”false”
timeout=”30″ stateNetworkTimeout=”20″/>
</system.web>

stateNetworkTimeout configuration setting is used to define the time, in seconds, that the ASP.NET Web
application will wait for the state server to respond to network requests.
By default, this time is 10 seconds.

3. If we using two IIS server or more, we need setup the same machine key in the web.config on those IIS
Sample:
<system.web>
<machineKey validation=”SHA1″ validationKey=”
F3690E7A3143C185AB1089616A8B4D81FD55DD7A69EEAA3B32A6AE813ECEECD28DEA66A
23BEE42193729BD48595EBAFE2C2E765BE77E006330BC3B1392D7C73F” />
</system.web>

! How to create a machine key
http://support.microsoft.com/?id=312906

4.所有要放入session的class必须Serializable,且尽量小.

开发asp.net应用的两条经验

Filed under: ASP.NET

1.不要把session保存在进程的内存中.
有n种可能会导致进程中的session丢失:对web.config和global.asx进行病毒扫描,修改bin目录的内容,
asp.net的预编译.
更重要的是如果想使用多台web server,就决不能把session放到进程中

因此,所有要放入session的class必须可serialize,且尽量小.

2.一开始就使用https,以免后来才发现程序因为安全因素不能执行.

August 16, 2006

在web.config中限制对文件类型的访问

Filed under: ASP.NET

<system.web>
<httpHandlers>
<add path=”*.xml” verb=”*” type=”System.Web.HttpForbiddenHandler”>
</httpHandlers>
</system.web>

August 14, 2006

ASP.net trace and debug

Filed under: ASP.NET

这两个功能的开关都有两个级别: Application级(在web.config中设置),页面级(在<@Page>中设置)
以Page中的设定为准.

此外.net 2.0 的machine.cofig中还有一个机器级的设定:
<system.web>
<deployment retail=”false” />
</system.web>
一旦retail=”true”所有的Trace, debug设定统统无效.
参考MSDN How to: Precompile ASP.NET Web Sites for Deployment

正式服务器一定不要用debug, trace
http://blogs.msdn.com/tess/archive/2006/04/13/575364.aspx
http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx

>>有关 Trace:
1. 如果web.config中的Trace设定为false,就不能使用Trace.axd来
查看Trace信息.

2. TarceMode=”SortByCategory”设置Trace信息的显示顺序.

3. 条件输出
if(Trace.IsEnabled)
Trace.Write

4. 完全用代码控制:
void Page_Load (object sender, EventArgs e)
{
Trace.TraceFinished +=new TraceContextEventHandler (OnTraceFinished);
}

void OnTraceFinished (object sender, TraceContextEventArgs e)
{
foreach (TraceContextRecord record in e.TraceRecords)
{
Response.Write (String.Format (”{0}: {1}<br>”,record.Category, record.Message));
}
}
在vs2005中,可以使用下边的配置在output window中显示trace信息.
<configuration>
<system.web>
<trace enabled=”true” writeToDiagnosticsTrace=”true” />
</system.web>
</configuration>

参考 Power Programming Tips for ASP.NET 2.0 一文

>>有关Debug
1. 和<customError mode=”">联合使用,根据error code跳转到不同页
2. 在Page.Error中进行错误处理
Page_Error
{
Server.GetLastError().ToString(); //显示call stack
}

3. 常见错误
IIS 状态代码(http://support.microsoft.com/?id=318380)

500 内部服务器错误
403 No access
404 Not found

参考
ASP.NET 2.0 监视你的应用
http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/episode.aspx?newsID=1242387

August 12, 2006

HttpModule应用Trap browser refresh

Filed under: ASP.NET

参考
MSDN HttpApplication class, AcquireRequestState Event 的时机

Interface IHttpModule
{
void Init( HttpApplication context );
void Dispose();
}

使用
<system.web>

<httpModules>
<add name=”RefreshModule” type=”RivenWeb.RefreshModule” />
</httpModules>
</system.web>

要解决的问题:
当你refresh一个页面时,browser会将上次的提交再重复一遍,如果上次的操作是删除一条
记录,refresh会导致再删除一次,如果上次的操作是添加一条记录,则refresh会插入冗余
的记录.

写一个自己的HttpModule,在Init中注册HttpApplication的AcquireRequestState,
在时间处理函数中根据HttpApplication.Context拿到HttpContext并处理之.
public class RefreshModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);
}
public void Dispose()
{

}
private void OnAcquireRequestState(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context;

RefreshAction.Check(ctx);
}
}

RefreshAction是一个工具类,用与Check HttpContext中的refresh信息,判断本次页面请求
的性质,并记录.
public static void Check(HttpContext ctx)

查看ctx.Session[”__LASTREFRESHTICKET”]是否为null,如果为null,
ctx.Session[”__LASTREFRESHTICKET”] = 0;

从Session读取Last refresh ticket
ctx.Session[”__LASTREFRESHTICKET”]
从hidden field读取Current refresh ticket
ctx.Request[”__CURRENTREFRESHTICKET”]
注意Last refresh ticket 位于Session中,而 Current refresh ticket位于Resuest中.
整个程序的关键就在于ctx.Request[”__CURRENTREFRESHTICKET”],如果是F5, ctx.Request[”__CURRENTREFRESHTICKET”]
和上一次请求一样,如果是正常的request,ctx.Request[”__CURRENTREFRESHTICKET”]为Page的隐藏字段”__CURRENTREFRESHTICKET”的值
而Page的隐藏字段”__CURRENTREFRESHTICKET”的值会在每次request中被TrackRefreshState()函数加1.
并在Pag_PreRender中被记录到hidden field中.

“When the user submits a new request (causes the displayed page to post back), the
hidden field (if any) is automatically attached to the request for the server. “

比较Last refresh ticket和Current refresh ticket,
如果current > last ()或
current = last 并且 current = last = 0(说明是第一次请求)
说明是正常的请求,set ctx.Items[PageRefreshEntry] = false;
并同步Last refresh ticket和Current refresh ticket,
ctx.Session[”__LASTREFRESHTICKET”] = current ticket;
否则在context的itemt记录此次refresh的类型
set ctx.Items[PageRefreshEntry] = true;

写一个Page类,为所有的request生成一个递增的ticket号,
1.提供Propery:IsPageRefresh,读取HttpContext.Current.Items[PageRefreshEntry],
从而得知但前page是refresh还是正常的请求.在进行正常的处理前,判断是否需要进行
数据操作.
protected void Button_Add_Click(object sender, EventArgs e)
{
if (!IsPageRefresh)
AddRecord(this.TextBox_FirstName.Text, this.TextBox_LastName.Text);
else
this.Message.InnerText = “Page refreshed”;
TrackRefreshState();
}
2.提供一个方法TrackRefreshState来修改Page.Session[RefreshTicketCounter],
如果是通过button click等错作引起的refresh, 就调用这个函数,使Page.Session[RefreshTicketCounter]+1
,以便新的页面请求中可以包含RefreshTicketCounter信息.

3.在Page.PreRender事件中将Page.Session[RefreshTicketCounter]记录到Page的隐藏字段中.
注意,这个隐藏字段中字段的名字为”__CURRENTREFRESHTICKET”,从而HttpModule可以从
ctx.Request[CurrentRefreshTicketEntry]读到这个值.

问题:
HttpContext.Session与Page.Session的辨析
隐藏字段和HttpContext.Request的关系.

August 9, 2006

E都市API

Filed under: ASP.NET

一、在文字后提供链接,指向地图上所在的位置
如:
钟楼<span classid=”edushianchor” city=”西安” sitename=”钟楼” address=”" style=”display:none”></span>
西工大<span classid=”edushianchor” city=”西安” sitename=”西工大” address=”" style=”display:none”></span>
杭州阿拉丁信息科技有限公司<span classid=”edushianchor” city=”杭州” sitename=”杭州阿拉丁信息科技有限公司” address=”杭州市庆春路228号6层(延安路口)” style=”display:none”></span>

[city] 城市参数,可以是城市的名称、城市的全拼、城市的区号
[sitename] 地点名称
[address] 具体地址

二、URL地址引用
<a href= http://www.edushi.com/api/url.asp?isMark=1&z=1&v=7&x=0&y=0&w=500&h=400&city=xian&sitename”>我的位置</a>
我的位置

z: 离地面的高度

三、嵌入地图
<script language=”javascript” src= ” http://www.edushi.com/api/api.js?isMark=1&z=2&v=3&x=0&y=0&w=500&h=400&city=xian&sitename=我的位置” type=”text/javascript”> </script>
直接用IE打开html文件不能显示地图,把html文件放在vd下才能显示

四、嵌入图片
<img src=http://www.edushi.com/api/getmap?city=xian&w=200&h=200&v=3&z=1&x=0&y=0 width=500 height=400 border=0>
目前似乎不能用.

五、高级扩展

还不会…

ThreadAbortException in asp.net applcation calling web method.

Filed under: ASP.NET

Improving .NET Application Performance and Scalability Chapter 10
Improving Web Services Performance, Timeout 一节
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt10.asp)
中提到asp.net application调用web service是个很常见的case, 如果web page先于对web service的调用超
时,会导致resource leak和ThreadAbortException.因为asp.net application的I/O线程和sockets被用于调用
service,一旦出现ThreadAbortException,会导致socket无法关闭,并无法重用.

目前我们的程序的机制是在一个web page中反复调用一个web method,把多条记录逐一由web method写入另一个数据库.(很显然web page的执行时间大于web method的执行时间)

影响这个过程的timeout有:
web application 所在机器上的web proxy timeout,执行timeout, 死连接timeout
Web service 所在机器的执行timeout.

1. web proxy timeout对应proxy的Timeout属性,default 为100s

2. 执行timeout 对应web.config中的

<system.web>
<httpRuntime executionTimeout=”90″ />
</system.web >
指示在请求被ASP.NET 自动关闭前允许执行的最大秒数。Default为90s

3. 死连接timeout对应web.config中的

<system.web>
<processModel responseDeadlockInterval=”00:03:00″ />
</system.web>
Default为3m, 180s
有关各个timeout的设定,见Improving .NET Application Performance and Scalability Ch17:
Configure Timeouts Aggressively一节.

简言之:
Web service proxy timeout< executionTimeout < responseDeadlockInterval

August 7, 2006

Web Application Debug Mode

Filed under: ASP.NET

ScottGu’s Blog(MS ASP.NET PM),
http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx
Doing so causes a number of non-optimal things to happen including:
1) The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)
2) Code can execute slower (since some additional debug paths are enabled)
3) Much more memory is used within the application at runtime
4) Scripts and images downloaded from the WebResources.axd handler are not cached

http://blogs.msdn.com/tess/archive/2006/04/13/575364.aspx
There are three main differences between debug=true and debug=false:

ASP.NET Timeouts
Batch compilation
Code optimization

Note: Timeout values are specified in milliseconds. If you have debug=”true”
in the Web.config file, the executionTimeout value will be ignored.

Question:

>>How about using Debug=true in the web.config and using release version dll?

Upload File in ASP.NET

Filed under: ASP.NET

http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppUploadASP2.mspx?mfr=true(CH)
http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/UploadASP2.asp(En)

http://www.codeproject.com/aspnet/fileupload.asp

http://windowssdk.msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.aspx

When using the File Field control in ASP.NET 1.x you had to take a few extra steps to get
everything in line and working. For example, you were required to add
enctype=”multipart/form-data” to the page’s <form> element on your own.

The new FileUpload server control provided in ASP.NET 2.0 makes the process of uploading
files to the hosting server as simple as possible.

//–Web Config
默认情况下,使用 FileUpload 控件上载到服务器的文件最大为 4MB 左右.

<system.web>
<httpRuntime maxRequestLength=”SIZE IN BYTES” executionTimeout=”????” />
</system.web>

负责上载文件大小的设置是 maxRequestLength 属性
executionTimeout 是 ASP.NET 关闭前允许发生的上载秒数

可参考web.config.comments (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG)中的defalut value
参考What’s New in ASP.NET Configuration

//–相关错误:
When uploading large files, a user might also receive the following error message:

aspnet_wp.exe (PID: 1520) was recycled because memory consumption exceeded 460 MB (60 percent of available RAM).

If your users encounter this error message, increase the value of the “memoryLimit” attribute in the “processModel”
element of the Web.config file for the application.
The memoryLimit attribute specifies the maximum amount of memory that a worker process can use.
If the worker process exceeds the memoryLimit amount, a new process is created to replace it, and all current
requests are reassigned to the new process.

To control whether the file to upload is temporarily stored in memory or on the server while the request is being
processed, set the requestLengthDiskThreshold attribute of the httpRuntime element. This attribute allows you
to manage the size of the input stream buffer. The default is 256 bytes. The value that you specify should not
exceed the value that you specify for the maxRequestLength attribute.

//–Client
FileUpload 控件被转换为一个 HTML <input type=”file”>

//–Server
if (FileUpload1.HasFile)
{
try
{
FileUpload1.SaveAs(”C:\\Uploads\\” + FileUpload1.FileName);
}
}

//–Folder permission
在folder上为asp.net的执行帐号:ASPNET 或 WebService赋写权限

//–Check File Type
Client : Validator
Server:
string fileExt = System.IO.Path.GetExtension(FileUpload1.FileName);
if (fileExt == “.mp3″)
{
}

//–Check File size
Client (just image):
Assign a image to a image’s src. get size by Image.FileSize.
If assign a image to a image’s src, get -1.
Server:

//–Uploading multiple files
string filepath = “C:\\Uploads”;
HttpFileCollection uploadedFiles = Request.Files;

for (int i = 0; i < uploadedFiles.Count; i++)
{
HttpPostedFile userPostedFile = uploadedFiles[i];
}

July 29, 2006

“是否同意”按钮的实现

Filed under: ASP.NET, Code snippets

[script type=”text/javascript”]
ar secs = 3;
var agree = document.getElementById(”agreeb”);
agree.disabled=true;
for(i=1;i<=secs;i++)
{
window.setTimeout(”update(” + i + “)”, i * 1000);
}
function update(num)
{
if(num == secs)
{
agree.value =” 我 同 意 “;
agree.disabled=false;
}
else
{
printnr = secs-num;
agree.value = “请认真查看<服务条款和声明> (” + printnr +” 秒后继续)”;
}
}
[script]

July 26, 2006

看 Developing ASP.NET 2.0 Applications using Atlas

Filed under: ASP.NET

Video - Developing ASP.NET 2.0 Applications using “Atlas”
by Scott Guthrie, General Manager, .NET Development Platform

http://download.microsoft.com/download/8/5/8/85803fdd-fe9a-4783-ab37-e0c565172ffd/asp_net_atlas.wmv

讲座共18分26秒.
在12分44秒时开始涉及atlas.
在此之前,Scott搞了个page实现了以下的功能:
1.一个table adapter来充当数据访问层.用一个objectdatasource来进行数据绑定.

2.一个gridview, 显示数据,并可以edit, sort, paging
设置 gridview 的 CssClass属性和AlternatingRowStyle-CssClass,很直接.

3. 用一个dropdown list为驱动gridview的显示.

4.一个detailview, default mode设为inster, 在同一页面上实现inster

显然,此时的种种操作会引发页面提交和重画,用Atlas正好对症.

进入正题:
引用Microsoft.web.Atlas.dll
在 asp:content 内添加:
<atlas: ScriptManager ID=”s1″ EnablePartialRendering =”true” runat=”server” />

再添加
<atlas:UpdatePanel ID=”p1″ runat=”server”>
<ContentTemplate>

</ContentTemplate>

<Triggers>
<atals:ControlValue ControlID=”DropDownList1″ PropertyName=”SelectedValue”/>
</Triggers>
</atlas:UpdatePanel>

将gridview移至其中. 实现了gridview的局部重画.

————–
再添加
<atlas:UpdatePanel ID=”p2″ Mode=”Condition” runat=”server”>
<ContentTemplate>
将detail view置入其中,使detail view也实现局部重画
</ContentTemplate>
</atlas:UpdatePanel>
有关Condition见:
http://atlas.asp.net/docs/Server/Microsoft.Web.UI/T_UpdatePanelMode.aspx
If the Mode property is set to Always, the panel is updated as part of each postback.
If the Mode property is set to Conditional, the panel is updated only when a client
trigger defined in the UpdatePanel.Triggers property is raised, or when you call the
UpdatePanel.Update method during a postback.

注意 detailview的操作也可引发gridview的重画.

—————
下面是一个很花的功能
在页面上添加:
<atlas:UpdateProgress ID=”progress” runat=”server”>
<ProgressTemplate>
拖个图片过来,
</ProgressTemplate>
</atlas:UpdateProgress>
这就是一个进度条!
为了充分演示此功能,
在objectDataSource的Updating时间中sleep一下,

–The End

July 7, 2006

如何用enter key正确提交Form.

Filed under: ASP.NET

一开始我使用了这个方法.
&lt;script language="JavaScript" type="text/javascript"&gt;
    &lt;!–
    //event handler
    if (document.addEventListener)   //Mozilla
        document.addEventListener("keyup",OnKeyup,true);
    else
        document.attachEvent("onkeyup",OnKeyup);

    function OnKeyup(event)
    {
        if(event.keyCode == 13  && event.srcElement.id =="txtAccountID" ) //&& event.shiftKey==true
        {
            var b = document.getElementById("btnUpdateOne");
            b.click();
        }
    }
    //–&gt;
&lt;/script&gt;

在Textbox上,还有一个validator 来验证用户输入,如果输入非法的字符,再使用button来提交,
validator 会提示错误,页面也不会被提交.但如果使用enter key来提交,validator会提示错误,
同时页面也会被提交.
在asp .net 2.0中,这个问题已被修正,如果输入非法字符,再使用enter key,页面不会被提交.

后来我使用了一下的方法:

if (!Page.IsPostBack)
{
    TextBox1.Attributes.Add("onkeydown", "if(event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById(’" + this.Button_OK.ClientID + "’).click();return false;}} else {return true}; ");  

    StringBuilder sb = new StringBuilder();
    sb.Append("if(event.keyCode)");
    sb.Append("{");
    sb.Append("     if (event.keyCode == 13)");
    sb.Append("     {");
    sb.Append("         document.getElementById(’" + this.Button_OK.ClientID + "’).click();");
    sb.Append("          return false;");
    sb.Append("      }");
    sb.Append("}");
    sb.Append("else");
    sb.Append("{return true}; ");
    this.TextBox1.Attributes.Add("onkeydown", sb.ToString());
}

July 6, 2006

如何禁止重复提交

Filed under: ASP.NET

一开始我使用了
this.button_OK.Attributes.Add("onclick", "window.document.getElementById(’" + this.Button_OK.ClientID + "’).disabled = true;")
但这样做的结果是server端的button click处理函数不会被执行.

正确的做法是在Page Load中添加代码:
//.net 2.0
string script = ClientScript.GetPostBackEventReference(this.Button_OK, null);
if (!Page.IsPostBack)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append("window.document.getElementById(’" + this.Button_OK.ClientID + "’).disabled = true;");
    sb.Append(script);
    sb.Append(";");
    this.Button_OK.Attributes.Add("onclick", sb.ToString());
}
       

// .net 1.0
string script = this.GetPostBackEventReference(this.button_OK);

If (!Page.IsPostBack)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append("window.document.getElementById(’" + this.button_OK.ClientID + "’).disabled = true;");
    sb.Append(script);
    sb.Append(";")
    this.button_OK.Attributes.Add("onclick", sb.ToString());
}

GetPostBackEventReference会生成html代码:
<script type="text/javascript">
<!–
var theForm = document.forms[’form1′];
if (!theForm)
{
    theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
// –>
</script>

生成的script值为__doPostBack(’Button_OK’,'’)

June 26, 2006

CSS 入门

Filed under: ASP.NET

参考http://www.w3schools.com/css/css_syntax.asp
—————————————————————————————
语法: selector {property: value}
—————————————————————————————
1.Grouping
h1,h2,h3,h4,h5,h6
{
color: green
}

2.The class Selector
注意:Do NOT start a class name with a number! It will not work in Mozilla/Firefox.
* 对相同元素定义为不同风格
p.right {text-align: right}
p.center {text-align: center}
使用
<p class=”right”>
This paragraph will be right-aligned.
</p>
<p class=”center”>
This paragraph will be center-aligned.
</p>
注意:Only one class attribute can be specified per HTML element!

.center {text-align: center}
使用:
<h1 class=”center”>
This heading will be center-aligned
</h1>
<p class=”center”>
This paragraph will also be center-aligned.
</p>

3.The id Selector
注意:Do NOT start an ID name with a number! It will not work in Mozilla/Firefox.

match the element that has an id attribute with a value of “green”:
#green {color: green}

match the p element that has an id with a value of “para1″:
p#para1
{
text-align: center;
color: red
}

4.子选择器(descendant selectors)
div.item{….}
div.item div.itemEx{XXXXXX}

div.nav
{
text-transform: uppercase;
font-size: 18px;
}
div.nav a:visited
{
color: #000000;
}

<div class=”nav”>
<a href=”Default2.aspx”>aaaaa</a>
</div>

//——指定图片
span.title
{
background : transparent
url(imgs/xxx.gif) top left no-repeat;
}

//——引用

<head>
<link rel=”stylesheet” type=”text/css” href =”css/window.css”>
</head>

June 22, 2006

GridView的使用

Filed under: ASP.NET

GridView Examples for ASP.NET 2.0(by Scott Mitchell 4GuysFromRolla.com)
http://msdn.microsoft.com/library/en-us/dnaspp/html/GridViewEx.asp

[ 1 ]————–使用DatatSource control访问数据
1. 什么是数据(Data) : xml, database, 提供某些interface的class,如dataset.

2. 什么是data source controls:
封装了数据来源的差异,使用declarative syntax来配置,

3. GridView等数据显示控件如何使用data source control.
GridView.DataSourceID = DataSources.ID

3.1. 使用SqlDataSource
优点:简单, 缺点:增加了页面的复杂度,在页面上绑定数据访问逻辑.
配置DataSource时会设置SELECT,INSERT, UPDATE, 和 DELETE Statement,
<asp:SqlDataSource ID=”productsDataSource” Runat=”server”
“SelectCommand=”SELECT [ProductID], [ProductName], ” & _
“[QuantityPerUnit], [UnitPrice], [UnitsInStock] ” & _
“FROM [Products]”
ConnectionString=
“<%$ ConnectionStrings:NWConnectionString %>”
DataSourceMode=”DataReader”>
</asp:SqlDataSource>

3.2 使用ObjectDataSource
提供一个Data Access Layer (DAL).
注意,DAL和数据实体可以不在同一个class中,即可以有Product 和 ProductDAL两个class

在配置ObjectDataSource时指定执行Select, Update, delete, Insert操作的方法名.

3.3 使用 XmlDataSource

[ 2 ]—————Formatting the GridView
Format 相关的property:
BackColor, Font, ForeColor
HeaderStyle, RowStyle, AlternatingRowStyle, FooterStyle

使用Smart Tag上的Auto Formatting, 此功能只提供整体的配色方案

使用Smart Tag上的Edit Columns, 对单独的column进行format.
使用Bound Field的DataFormatString 来格式化输出,比如
日期column的DataFormatString: DataFormatString=”{0:yyyy.MM.dd}”
注意,出于安全上的考虑,还要设置HtmlEncode=”false”

使用Skin
一个project的Theme的目录结构
/app_themes/<ThemeName>/ .css .skin .Image

Theme : 多个Skin的集合.

Skin : 包含了某些control的外观的文件.
Skin的格式:
<!– Default Skin –>
<asp:GridView runat=”server” Font-Name=”Arial” />
<asp:GridView runat=”server” SkinID=”Professional” Font-Name=”Verdana”
Font-Size=”10pt” Cellpadding=”4″
HeaderStyle-BackColor=”#444444″
HeaderStyle-ForeColor=”White”
AlternatingRowStyle-BackColor=”#dddddd” />
<asp:GridView runat=”server” SkinID=”Fun” Font-Name=”Comic Sans MS”
Font-Size=”13pt” BackColor=”Khaki”
AlternatingRowStyle-BackColor=”Tan”
HeaderStyle-BackColor=”SaddleBrown”
HeaderStyle-ForeColor=”White”
HeaderStyle-Font-Bold=”True”/>

使用Skin
<%@ Page Language=”C#” StyleSheetTheme=”<Theme Name>” %>

<asp:GridView ID=”GridView1″ Runat=”server” SkinID=”<Skin Name>”>

根据数据动态Formatting the GridView,比如根据数据而使用不同的颜色.
void productsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// determine the value of the UnitsInStock field
int unitsInStock = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, “UnitsInStock”));
if (unitsInStock == 0)
{
// color the background of the row yellow
e.Row.BackColor = Color.Yellow;
}
}
}
RowDataBound event 在每个row被生成时触发,由于包含HeaderRow,所以使用e.Row.RowType来判断是否
需要fromatting.关键在于如何得到row的某个field:
DataBinder.Eval(e.Row.DataItem, “UnitsInStock”)

[ 3 ]—————Master/Detail
典型用法: ComboBox(DropDownList) + GridView
1. 把DropDownList的DataValueField设置为一个Field的Name 如”ProductID”, 意味着当DropDownList的一个Item被选中时,
DropDownList的SelectedValue等于字段”ProductID”的值,
2. 设置GridView对应的SqlDataSource的<SelectParameters>
指定使用DropDownList的SelectedValue属性来作为查询的条件.
<asp:SqlDataSource SelectCommand=”SELECT * FROM [OrderDetails] WHERE ([ProductID] = @ProductID)” ConnectionString=”…”>
<SelectParameters>
<asp:ControlParameter Name=”ProductID” Type=”Int32″ ControlID=”productSelector” PropertyName=”SelectedValue”>
</asp:ControlParameter>
</SelectParameters>
</asp:SqlDataSource>

使用DAL显示 Master/Detail 数据, 关键在于配置ObjectDataSource,指定其SelectMethod

<asp:ObjectDataSource ID=”orderDetailsForProduct”
Runat=”server” TypeName=”OrderDetailDAL”
SelectMethod=”GetOrderDetailsByProductID”>
<SelectParameters>
<asp:ControlParameter Name=”productID” Type=”Int32″
ControlID=”productSelector”
PropertyName=”SelectedValue”></asp:ControlParameter>
</SelectParameters>
</asp:ObjectDataSource>

[ 4 ]—————Paging and Soring
SqlDataSource 中的Paging and Soring只需要设置GridView的 AllowSorting=”True” 和AllowPaging=”True”
注意:
SqlDataSource 可以返回DataReader或DataSet,次行为可通过设置DataSourceMode属性来指定,
Default值为DataSet,如果要生成一个可”分页”的GridView, 必须使用DataSet.可”排序”的GridView
可以使用DataSet和DataReader,但使用DataReader时必须从一个接受sort expression的Stored procedure
中返回数据.
使用SqlDataSource的缺点是GridView 只能使用 default paging model, 即SqlDataSource会返回所有的数据.

ObjectDataSource 中的Paging and Soring
要支持 分页 ,DAL class的要多提供一个接受两个int参数的SELECT method ,
GetProducts(maximumRows, startRowIndex)
第一个参数表示返回的记录数, 第二个参数表示起始的row index.

要支持排序,DAL class的要多提供下列函数
GetProducts(SortExpression) //返回排序后的所有记录
GetProducts(maximumRows, startRowIndex, SortExpression) //排序 + 分页

然后需要设置ObjectDataSource的下列属性:
<asp:ObjectDataSource ID=”productsDataSource” Runat=”server” TypeName=”ProductDAL”
EnablePaging=”True”
SortParameterName=”SortExpression”
SelectMethod=”GetProducts”
SelectCountMethod=”TotalNumberOfProducts”>
</asp:ObjectDataSource>

ObjectDataSource的MaximumRowsParameterName 属性和StartRowIndexParameterName属性一般不用指定,
MaximumRowsParameterName缺省对应maximunRows, StartRowIndexParameterName缺省对应startRowIndex.

显示分页信息:
<i>You are viewing page<%=productsGridView.PageIndex + 1%>of<%=productsGridView.PageCount%></i>

[ 5 ]—————Displaying Images
文中推荐的做法是在数据库中存放一个PicureURL字段(形如”~/DisplayingImages/Images/Blue hills.jpg”)
真正的图片存放在file system中.
在进行data binding时,删除PicureURL字段, 添加一个ImageField, 并指定ImageField的DataImageUrlField
属性为”PicureURL”(datasource中包含picture url的字段名).

文中还用到了一个小技巧, 给GridView指定一个动态生成的data source:
DataTable GetData()
{

}

<asp:GridView Runat=”server” DataSource=’<%# GetData() %>’ …>

</asp:GridView>

[ 6 ]————–Working with TemplateFields
GridView 可以使用不同的Column类型:
BoundFiled, 显示DataSource的Fieled的内容
ImageField, 通过DataSource的image url 字段来显示图片
CommandField 显示command buttons.
TemplateField, 可以显示HTML markup, web contorl, data-binding syntax

1.使用Function来自定义输出.
<%# FunctionName(parameter1, parameter2, …, parameterN) %>
Sample:

<%# ComputeSeniorityLevel(DateTime.Now - (DateTime)Eval(”HireDate”)) %>
string ComputeSeniorityLevel(TimeSpan ts)
{
int numberOfDaysOnTheJob = ts.Days;
if (numberOfDaysOnTheJob >= 0 && numberOfDaysOnTheJob <= 1000)
return “Newbie”;
else if (numberOfDaysOnTheJob > 1000 && numberOfDaysOnTheJob <= 4000)
return “Associate”;
else if (numberOfDaysOnTheJob >= 4000 && numberOfDaysOnTheJob <= 8000)
return “One of the Regulars”;
else
return “An Ol’ Fogey”;
}
2.嵌入一个Web Control
<Columns>

<asp:TemplateField HeaderText=”Territories”>
<ItemTemplate>
<asp:BulletedList ID=”bltTerritories” Runat=”server”
DataTextField=”TerritoryDescription”
DataValueField=”TerritoryDescription”>
</asp:BulletedList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
注意: 把DataTextField和DataValueField设置为DataSet的Field name
处理Gridview的RowDataBound event
<asp:GridView ID=”employeesGridView” OnRowDataBound=”employeesGridView_RowDataBound” />

void employeesGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
// For each DataRow in the GridView,
// programmatically access the BulletedList, filter
// the DataView based on the GridView row’s
// EmployeeID value and bind the filtered DataView
// to the BulletedList
if (e.Row.RowType == DataControlRowType.DataRow)
{
BulletedList bl = (BulletedList)e.Row.FindControl(”bltTerritories”);
territoryData.RowFilter = “EmployeeID = ” + ((DataRowView) e.Row.DataItem)[”EmployeeID”].ToString();
bl.DataSource = territoryData;
bl.DataBind();
}
}

[ 7.1 ]————–Master/Slave
一个Orders表和一个Order Details表
1. 用一个SqlDataSource取回Orders表中所有的数据.
2. 添加一个主GridView,绑定到SqlDataSource,并选中这个GridView的”Enable Selection”选项,
设置主GridView 的DataKeyNames属性,使得GridView的SelectValue属性会等于DataKeyNames属性
对应的字段的值.
3. 添加一个子SqlDataSource.设置其Select 方法的where参数的”Parameter Source”为Control,
ControlID为主GridView的ID.
4. 注意当主GridView分页时,子GridView不能正确显示数据,添加如下代码Fix
void orderGridView_PageIndexChanged(object sender, EventArgs e)
{
orderGridView.SelectedIndex = -1;
}

[ 7.2 ]—————- Summary to Detail
主GridView只显示部分数据, DetailsView显示所有的数据.
设置主GridView的DataKeyNames 属性为 CustomerID
设置DetailsView的SqlDataSource的FilterException属性为CustomerID=’{0}’

[ 8 ]——————–Summary Data in the Footer
处理RowDataBound事件
void detailsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// add the UnitPrice and QuantityTotal to the running total variables
priceTotal += Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, _
“UnitPrice”));
quantityTotal += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, _
“Quantity”));
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[0].Text = “Totals:”;
// for the Footer, display the running totals
e.Row.Cells[1].Text = priceTotal.ToString(”c”);
e.Row.Cells[2].Text = quantityTotal.ToString(”d”);

e.Row.Cells[1].HorizontalAlign = _
e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Right;
e.Row.Font.Bold = true;
}
}

[ 9 ]———————Delete
在配置SqlDataSource时选中”Generate Insert, Update, and Delete Statements”check box.
如果使用了”Use optimistic concurrency”选项,当数据库中的数据和GridView中的当前数据
不一致时,对数据库的delete和update会失败.这个选项对应了SqlDataSource的ConflictDetection
属性的取值: CompareAllValues or OverwriteChanges.
设置GridView的 DataKeyNames 属性

GridView 提供了 RowDeleting Event:
e.Values, which provides data on the values of the row being deleted
e.Cancel.

Deleting from an ObjectDataSource
设置ObjectDataSource的ConflictDetection 属性.
如果使用了OverwriteChanges,需要提供方法
public static void DeleteMethod(int original_OrderID, int original_ProductID)
{

}

如果使用了CompareAllValues,需要提供方法:
public static void DeleteMethod(int original_OrderID, int original_ProductID, int original_Quantity, decimal original_UnitPrice)
{

}

Client Scitpt确认
注意:GridView’s CommandField does not include an OnClientClick property,故无法使用script.
<Columns>
<asp:TemplateField><ItemTemplate>
<asp:LinkButton ID=”LinkButton1″ Runat=”server” OnClientClick=”return confirm(’Are you sure you want to delete this record?’);”
CommandName=”Delete”>Delete Order Line Item</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>

[ 10 ]———————–Edit
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/GridViewEx10.asp
和Delete 类似

Customizing the Editing Interface!

GridView的SmartTag “Edit Columns”->Selected Fields->”Convert this field into a TemplateField”
使用GridView的SmartTag “Edit Templates”

1 . Validation
drag and drop the appropriate validation controls from the Toolbox into the EditItemTemplate

2. 在Combo中选择输入
Add a DropDownList to the EditItemTemplate and bind it to this SqlDataSource

June 16, 2006

DataField的DataFormatString

Filed under: ASP.NET

使用语法如下:
DataFormatString=”{0:格式字符串}”
如:
<asp:BoundField DataField=”StartTime” HeaderText=”活动开始时间” SortExpression=”StartTime” DataFormatString=”{0:yy-MM-dd}” HtmlEncode=”false”/>
DataFormatString=”Total: {0:C}” 12345.6789 显示为 Total: $12345.68

ASP.NET2.0出于安全性的考虑,除了设置DataFormatString,还需要设置HtmlEncode =”false” 才会格式化显示

June 14, 2006

Custom HTTP Handler

Filed under: ASP.NET

ASP.NET会按照被请求的文件的后缀把请求交给特定的Handler.
内置的Handler:
Page Handler Handles Web pages (.aspx)
User Control Handler Handles Web user control pages (.ascx)
Web Service Handler Handles Web service pages (.asmx)
Trace Handler Handles trace functionality(trace.axd)

同步的Hanlder实现
public interface IHttpHandler
{
//是用同一个Handler处理所有的request(高效),还是每个request都需要一个新的handler
bool IsReusable { get; }

// Enables processing of HTTP Web requests by a custom HttpHandler that implements
// the System.Web.IHttpHandler interface.
void ProcessRequest(HttpContext context);
}

异步的Handler实现
public interface IHttpAsyncHandler : IHttpHandler
{
IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
void EndProcessRequest(IAsyncResult result);
}

注册
<configuration>
<system.web>
<httpHandlers>
<add verb=”*” path=”*.myfile” type=”MyHandler”/>
</httpHandlers>
</system.web>
</configuration>

ASP.NET 提供了一个缺省的custom handler .ashx, 此handler会被自动注册给IIS,因为是
缺省的handler, 所以可以让.ashx来处理多种后缀的文件.
比如
<%@ WebHandler Language=”C#” Class=”ImageFetch” %>

using …;
public class ImageFetch : IHttpHandler
{

public bool IsReusable
{
get
{
return true;
}
}
}

参照
Use Custom HTTP Handlers in Your ASP.NET Applications
http://www.developer.com/net/asp/article.php/3565541

StarterKits Club Web Site
http://asp.net/downloads/starterkits/default.aspx?tabid=62

加密Web.config

Filed under: ASP.NET

比如要加密connnection string
<configuration>
<connectionStrings>
<add name=”mySqlServer” connectionString=”Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;” />
</connectionStrings>
</configuration>

//==使用aspnet_regiis
aspnet_regiis -pe “connectionStrings” -app “/MyApplication”
加密 MyApplication 应用程序的 Web.config 文件的 <connectionStrings> 节
aspnet_regiis -pe “connectionStrings” -app “/MyApplication”
解密

aspnet_regiis -pef “connectionStrings” “C:\PetShop4.0\Web”
加密指定的物理路径下的web.config
aspnet_regiis -pdf “connectionStrings” “C:\PetShop4.0\Web”
解密

aspnet_regiis -pa “NetFrameworkConfigurationKey” “NT AUTHORITY\NETWORK SERVICE”
授予 NETWORK SERVICE 帐户对计算机级别的 “NetFrameworkConfigurationKey” RSA 密钥容器的访问权限。

-pkm 对Machine.config 加密
-prov 指定要使用的加密提供程序,如 RsaProtectedConfigurationProvider.

//==如果无法控制物理的服务器,可以通过代码来加密web.congif
public void EncryptConfig(bool bEncrypt)
{
string path = “/tricks”;

Configuration config = WebConfigurationManager.OpWebConfiguration(path);
ConfigurationSection appSettings = config.GetSection(”connectionString”);

if(bEncrypt)
{
appSettings.SetionInformation.ProtectSection(”DataProtectionConfigurationProvider”);
}
else
{
appSettings.SetionInformation.UnprotectSection();
}
config.Save();
}

参考
受保护配置概述
http://msdn2.microsoft.com/zh-cn/library/hh8x3tas.aspx

使用受保护的配置加密配置信息
http://msdn2.microsoft.com/zh-cn/library/dtkwfdky.aspx

June 7, 2006

无Cookie 的 Session State

Filed under: ASP.NET

//–Session State是1997年 ASP引入的技术.
当用户首次连接到站点时,ASP会创建一个类似Hashtable的内存块来会保存Session State,同时
还会创建一个 ID 以便将其与当前用户唯一地联系起来。当下一次发出请求时,该用户将被要求提交该
Session ID,以便检索并正确地还原会话状态。Sessioin ID 是 ASP 和 ASP.NET 完全自主生成的字母
数字字符串. 浏览器会使用Cookie(最早由 Netscape 发明)在客户端保存Session ID,

//–在asp.net中使用无 cookie的session
修改web.config
<sessionState cookieless=”true” />

此时请求http://yourserver/folder/default.aspx,实际上发送的是
http://yourserver/folder/(session ID)/default.aspx

这种做法的缺点是如果在得到ID后浏览了别的网站,然后重新输入原来的URL,会得到一个新的ID
以前的session信息将丢失.

//—实现
无Cookie session的实现依赖于两个模块
1. SessionStateModule.这是一个Managed Http Module,需要ASP.NET 和CLR才能工作.
2. aspnet_filter.dll 这是一个win32 dll, 充当 ISAPI filter,由IIS调用.
二者都截获在请求处理过程中激发的 IIS 事件.

当新浏览器会话的第一个请求进入时,SessionStateModule 读取 web.config 文件中有关 Cookie
支持的设置。如果 节的 cookieless 属性设置为 true,则该模块生成一个Session ID,并把Session ID
填充到资源名称前,从而得到一个新的URL,并且使用 HTTP 302 命令将浏览器重定向到新的 URL。

当每个请求到达 IIS 入口时(远早于它被移交给 ASP.NET),aspnet_filter.dll 获得了一个查看
它的机会。如果该 URL 将会话 ID 嵌入到括号中,则会提取该会话 ID 并将其复制到一个名为
AspFilterSessionId 的请求标头中。然后,重写该 URL 以使其看起来像原来请求的资源,并且将其释放。
这一次,ASP.NET 会话状态模块从请求标头中检索会话 ID,并且通过会话-状态绑定继续工作。

只要该 URL 包含可用来获取会话 ID 的信息,无 Cookie 机制就可以很好地工作。

//—Thumbs Up
在 ASP.NET 中,Session state和forms authentication 证是仅有的两个在后台使用 Cookie 的系
统功能。ASP.NET 1.x 仍需要使用 Cookie 来实现表单身份验证。在 ASP.NET 2.0 中,表单身份验证可以
选择以无 Cookie 方式工作,在这种模式下,用户的身份信息也是通过URL来传递.

//—Thumbs Down
由于Session ID直接显示在浏览器的地址栏中!Cookieless的session是危险的,直接抓一个包含Session
ID的URL,就算换一个计算机使用,还是认为是同一个session.
每次同一个浏览器内部手动键入指向某个站点的URL,都将丢失Cookieless的Session state。

使用Cookieless Session还会引起与链接有关的问题。不能在 ASP.NET 页中具有绝对链接。如果这样做,
那么源自该链接的每个请求都将被视为新会话的一部分。无 Cookie 会话要求您总是使用相对 URL,就像在
ASP.NET 回发中一样。仅当可以将会话 ID 嵌入到 URL 中时,您才可以使用完全限定的 URL。但是,既然会
话 ID 是在运行时生成的,那么如何才能做到这一点呢?

下面的代码中断了该会话:

<a runat=”server” href=”/test/page.aspx”>Click</a>

要使用绝对 URL,可以使用 HttpResponse 类上的 ApplyAppPathModifier 方法:

<a runat=”server” href=<% =Response.ApplyAppPathModifier(”/test/page.aspx”)%> >Click</a>
ApplyAppPathModifier 方法采用一个表示 URL 的字符串作为参数,并且返回一个嵌入了会话信息的绝对 URL。
例如,当您需要从 HTTP 页重定向到 HTTPS 页时,该技巧尤其有用。

最后,请特别注意,还要请您注意的是,对于移动应用程序,如果设备无法处理专门格式化的 URL,Cookieless
Session 可能会出现问题。

参考
无 Cookie 的 ASP_NET (Dino Esposito)
http://www.microsoft.com/china/msdn/library/webservices/asp.net/asppcookieless.mspx
http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/cookieless.asp

ASP.NET Session State

Foiling Session Hijacking Attempts
http://msdn.microsoft.com/msdnmag/issues/04/08/WickedCode/default.aspx

Cookie and Form Authentication

Filed under: ASP.NET

ASP.NET 2.0中的Cookies Form Authentication

<authentication mode=”Forms”>
<forms name=”.ASPXCOOKIEDEMO” loginUrl=”login.aspx” defaultUrl=”default.aspx”
protection=”All” timeout=”30″ path=”/” requireSSL=”false”
slidingExpiration=”true” enableCrossAppRedirects=”false”
cookieless=”UseDeviceProfile” domain=”">
<!– protection=”[All|None|Encryption|Validation]” –>
<!– cookieless=”[UseUri | UseCookies | AutoDetect | UseDeviceProfile]” –>
</forms>
</authentication>

ASP.NET 2.0 Forms Authentication can store the forms authentication ticket in either a cookie,
or in a cookie-less representation on the URL.

UseDeviceProfile Default value, ASP.NET determines where to store the ticket based on
pre-computed browser profiles.

AutoDetect ASP.NET to dynamically determine if the browser supports cookies or not.

UseUri and UseCookies force cookieless and cookied tickets respectively.

ASP.NET QuickStart
http://www.asp.net/QuickStart/aspnet/doc/security/formsauth.aspx

ASP.NET Forms Authentication所生成Cookie的安全性
http://www.achot.com/Article/110/Article_33237_1.html

Role-based Security with Forms Authentication
http://www.codeproject.com/aspnet/formsroleauth.asp

Cookieless ASP.NET forms authentication
http://www.codeproject.com/aspnet/cookieless.asp

如何使用 Forms 身份验证创建 GenericPrincipal 对象
http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/BuildSucApp/BSSAsecmodsecmod18.mspx?mfr=true

June 5, 2006

webcast_How do I Video Series_Cache

Filed under: ASP.NET

How do I? Video Series : Caching (hilo_cache1_final.wmv ,hilo_cache2_final.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

//–Output Caching
<%@ Page Language=”C#” %>
<%@ OutputCache Duration=”10″ VaryByParam=”none”%>
<script runat=”server”>
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
}
</script>

<html>
<head runat=”server”>
<title></title>
</head>
<body>

</body>
</html>

注意, 对于OutputCache directive, Duration 和 VaryByParam要同时使用,VaryByParam
对应于GET方法的query string 或 POST方法的parameter, VaryByParam可以被设置为 none,
*,query string 或 POST方法的参数名.

//–Database caching
—Step 1
> aspnet_regsql -S <SqlServerName> -U sa -d <DatabaseName> -ed -et -t <TableName>

以上命令会在Database(<DatabaseName>)中生成一个custom table
dbo.AspNet_SqlCacheTableForXXXXXX
并在Table(<TableName>)上生成Trigger Customers_AspNet_SqlCacheNotification_Trigger

—Step2 修改web.Config
<system.web>
<caching>
<sqlCacheDependency enable =”true” pollTime=”2000″>
<databases>
<add connectionStringName=”XXX” name=”XXX” pollTime=”120000″>
</database>
</sqlCacheDependency>
</caching>
</system.web>

—Step 3
使用SqlCacheDependency Object 来监视数据库
<%@ OutputCache Duration=”60″ VaryByParam=”none” SqlDependency=”"ConnectionString1:Table1;ConnectionString2:Table2″%>
如果使用了相同的select 语句, asp.net会直接从catch table中取结果.

如果使用了sql2005,可以由sql2005来通知应用程序而不是由应用程序监视数据库,如果数据没有变化
不会有sql 语句在sql server上执行

<%@ OutputCache Duration=”60″ VaryByParam=”none” SqlDependency=”CommandNotification”%>
同时需要在Global.asax中添加
void Application_Start(object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings(”XXX”).ConnectionString);
}

CommandNotification 只能用于web page(.aspx),User Control只能使用table-based polling with
the @ OutputCache directive.

—-Testing
使用Sql server Profiler来监视TSQL event, 看TextData 列就可知道有什么sql语句被执行了.

//–Partial page caching
Page上可能使用多个User Control, 可以在某个user control内使用
<%@ OutputCache Duration=”10″ VaryByParam=”none”%>
从而实现部分caching

也可以在User Control中使用class attribute:
[PartialCaching(120)]
public partial class CachedControl : System.Web.UI.UserControl
{
// Class Code
}
注意,在create User control要选择”Place code in seperate file”

如果User Control所在的page也使用了<%@ OutputCache directive,User Control
的Duration 将优先使用.

[*]使用 Substitution Control

<script runat=”server”>
Private static string GetRealTime(HttpContext context)
{
return DateTime.Now.ToString()
}
</script>

<asp:Substitution ID=”" MethodName=”GetRealTime”>

//–Caching API
//–Code 1
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
stirng path =”names.xml”;
DataSet ds = new DataSet();
ds.ReadXml(path);

dataGrid.DataSource = ds;
dataGrid.DataBind();
}
}

//–Code 2
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
DataSet ds = (DataSet)(Cache(”names”));

if(ds==null)
{
stirng path =”names.xml”;
ds.ReadXml(path);

CacheDependency cd = new CacheDependency(path);
Cache.Insert(”names”, ds, cd);
Trace.Warn(”Names read from xml”);
}
else
{
Trace.Warn(”Names read from cache”);
}
dataGrid.DataSource = ds;
dataGrid.DataBind();
}
}

//–Testing
添加
<%@ Page Trace=”true” TraceMode=”SortByCategory”>
关调IE再打开,依然显示”Names read from cache”

Refresh Cache:
Cache.Remove(”names”);

参考
Caching Data with the SqlDataSource Control (MSDN)

May 31, 2006

webcast_How do I Video Series_Master Pages and Site Navigation

Filed under: ASP.NET

How do I? Video Series : Master Pages and Site Navigation (hilo_masterpages-nav_FINAL.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

1.Table的使用

2.使用TreeView, data source 设为Site Map, Site Maps会引用当前目录下的web.sitemap文件.

3.SiteMapPath,同TreeView.

4.Cool! 使用 File->Export Template 可以把当前project中的设置导出一个模板.下次再create web site时可以使用之.

5.对无权用户隐藏菜单

<system.web>
<siteMap defaultProvider=”defatult”>
<provider>
<clear/>
<add name=”default” type=”System.Web.XmlSiteMapProvider” SitMapFile=”web.sitemap” securityTrimmingEnable=”true” >
</provider>
</siteMap>
</system.web>

May 30, 2006

webcast_How do I Video Series_Localization

Filed under: ASP.NET

How do I? Video Series : Localization (hilo_localization_final.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

0. Resource 语法
显式: <%$ Resources:[filename prefix,]resource-key %>

隐式: <asp:Label ID=”Label1″ runat=”server” meta:resourcekey=”resource-key-prefix” />

1. 使用Local resource

可以使用菜单Tools->Generate Local Resource来生成local resource.
foo.aspx will refer to the /App_LocalResources/foo.aspx.resx

Create a special folder named “App_LocalResources”.
Create a resource file named “Default.aspx.resx” in it.
Create a resource file named “Default.aspx.fr.resx” in it.

3. Using the resource in the control
<asp:Button ID=”Button1″ runat=”server” Text=”Button” meta:resourceKey=”Button1″/>

4. Set culture for the page
<%@Page … UICulture=”auto”>

在IE中可以设置 default language,从而进行测试

5. 使用Global resource
所有的page, user-control都可以访问
Create a special folder named “App_GlobalResources”.
Create a resource file named “Resource.resx” in it.
Create a resource file named “Resource.fr.resx” in it.

6. 设置Control.Expressions 属性
Sample1:
Bindable properties 设为 Text
Expression Type 设为 Resource
Expression properties 的ClassKey 设为 Resource
Expression properties 的ResourceKey 设为 “资源名称”
Sample2:
Bindable properties 设为 BackColor
Expression Type 设为 Resource
Expression properties 的ClassKey 设为 Resource
Expression properties 的ResourceKey 设为 “资源名称”

7. 通过代码设置Culture

using System.Threading;
using System.Globalization;

protected override InitializeCulture()
{
string lang = Resuest(” “);

Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
Thread.CurrentThread.CurrentCulture = new CultureInfo.CreateSpecificCulture(lang);
}

参考

ASP.NET 2.0 Localization Features: A Fresh Approach to Localizing Web Applications

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

ASP.NET Event Validation

Filed under: ASP.NET

引用
ASP.NET Event Validation and "Invalid Callback Or Postback Argument"
http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
http://odetocode.com/Blogs/scott/archive/2006/03/21/3153.aspx

参照
Please, please, please, learn about injection attacks!
http://weblogs.asp.net/bleroy/archive/2004/08/18/216861.aspx

ASP.net 添加了"event validation"的功能, ASP.NET会检查 POST方法中的所带的参数,如果
认为不合法,就会抛出异常,信息如下

    Invalid postback or callback argument.
        Event validation is enabled using <pages enableEventValidation="true"/> in
    configuration or <%@ Page EnableEventValidation="true" %> in a page. 
        For security purposes, this feature verifies that arguments to postback or
    callback events originate from the server control that originally rendered them. 
        If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation
    method in order to register the postback or callback data for validation.
   
这个设计的目的是为了防止恶意用户利用post 方法发送一些恶意数据.但是有时一些常见的
case也会出错,比如使用客户端脚本,根据页面上的其他控件的内容来改变一个dropdown list的内容,最常见的case
就是省市县3级联动菜单.又比如在页面上添加一个dropdown list,然后给它添加3个item,再使用客户端脚本在
dropdown list中添加一个item,如果dropdown list的AutoPostBack="True",每次选择list item都会引起postback,
如果所选的item为dropdown list本来就有的,一切正常.如果所选的item是通过客户端脚本添加的,就会出现异常.

在asp.net render DropDownList 时,会遍历DropDownList的item,并记录所有可能的postback的值,其算法为
hash(DropDownList’s UniqueID XOR hash(ListItem’s Value property)),计算的结果会被保存在page中,

<input type="hidden"
       name="__EVENTVALIDATION"
       id="__EVENTVALIDATION"
       value="/wEWBQKGg9abDQKd9sHMBgKc9s…….."
/>
这个过程发生在control的Render()方法中
当页面postback时,ASP.NET会根据这个隐藏值检查postback values,如果找不到对应信息,就会报错

结局方案
1. 禁止这个功能, 但同时会失去一些安全保障:
//—-通过web.config
<system.web>
   <pages enableEventValidation="false"/>
</system.web>
//—-针对某个page
<%@ Page EnableEventValidation="false" … %>

2.Register For Event Validation
其原理就是让asp.net记录这个postback value.
RegisterForEventValidation必须在render时调用.

protected override void Render(HtmlTextWriter writer)
{
   ClientScript.RegisterForEventValidation(_recipeList.UniqueID,"4");
   base.Render(writer);
}

如果我们自己写了一个control,需要使用validate events功能,就需要使用SupportsEventValidation attribute,

[SupportsEventValidation]
public class DynamicDropDownList : DropDownList
{
  protected override void Render(System.Web.UI.HtmlTextWriter writer)
  {
     Page.ClientScript.RegisterForEventValidation(this.UniqueID, "4");
     base.Render(writer);
  }
}

目前,asp.net还不能单独禁止某个control的validate events功能.

May 29, 2006

webcast_How do I Video Series_Tips and Tricks

Filed under: ASP.NET

How do I? Video Series : Tips and Tricks (hilo_tips_final.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

通过代码加解密的connection string

public void EncryptConfig(bool bEncrypt)
{
    string path = "/tricks";
   
    Configuration config = WebConfigurationManager.OpWebConfiguration(path);
    ConfigurationSection appSettings = config.GetSection("connectionString");
   
    if(bEncrypt)
    {
        appSettings.SetionInformation.ProtectSection("DataProtectionConfigurationProvider");
    }
    else
    {
        appSettings.SetionInformation.UnprotectSection();  
    }
    config.Save();
}

保持滚动条的当前位置
    <%@ Page MaintainScrollPostionOnPostback = "true">
   
跨页面提交
    设置page1的PostBackUrl ="page2.aspx"
    设置page1的form1的
        DefaultButton和DefaultFocus
       
    在page2.aspx的page_load中写下:
    if(!Page.IsPostBack)
    {
        TextBox t = (TextBox)PreviousPage.FindControl("textbox1");
        this.lable1.Text = t.Text;
    }
   
使用BulletedList data binding到xml.
   
   
File Upload Control
   
    if(fileUpload1.HasFile)
    {
        fileUpload1.SaveAs("C:\upload\"+ fileUpload1.FileName);
    }

URL mapping 把一个很复杂的url map成一个简单的url.
    <System.web>
        <add url="…" mappedUrl="…">
    <System.web>
   
使用MultiView控件

webcast_How do I Video Series_Data Access

Filed under: ASP.NET

How do I? Video Series : Data Access(hilo_data_final.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

共14分钟,演示了
1. 使用mdf文件, 从pubs数据库authots表导入数据

2. 生成了数据访问层: 生成connection string , 生成和配置 dataset,

3. 针对dataset的data binding
共两个页面: default.aspx 和 details.aspx

defautl 页面上有一个combo box, 一个gridview,演示了级联数据显示.
        gridview 还添加了detail url,指向 details页面,显示详细信息.

details页面,使用了DetailsView, 根据url中传来的参数,显示详细信息.

详细步骤:
//—-使用mdf文件
1. 在vs 2005 中可以直接生成mdf文件, 生成table,但不能执行 create table 等sql语句.
使用 SQL Server Management Studio Attach上mdf文件,可进行高级操作

//—-操作dataset
dataset会被存放在app_code目录中

可把table或table中的field从db explorer上drag到date set的design view上来生成table adapter

按照Table Adapter Configuration的提示可生成connection string 和用于select, update, delete
的sql 语句.
select 语句的where 子句通过设置filter 来实现,比如把filter设为 Filter = @state,会生成语句
where(state = @state)

完成后可使用preview data 菜单来进行测试, Cool!

//—- data binding
使用dataset,要在为control设置数据源时,选择object.
combo box 用来显示state,并用于引发dataview的变化, 所以combo box 的"Enable AutoPostback" 要设为true.
注意data source 的参数可以来自其他control, 也可以来自url.
把一个page drag到另一个page上可以直接生成一个link.

//如何实现details page
1.给data view添加一个column
2.设置column类型为HyperLinkField
3.设置HyperLink URL
  get url from data field : authorId
  url fromat string : Detauls.aspx?AuthorId={0}
4.在DataSet中添加一个query: GetDataByAuthorID
5.生成details page,添加DetailsView,设置datasource 为object,
  设置Parameter source为QueryString, QueryStringField为AuthorId
  和dataview的HyperLink column的设置对应.

webcast_How do I Video Series_Create a Full-Featured Customer Login Portal

Filed under: ASP.NET

How do I? Video Series : Create a Full-Featured Customer Login Portal(hilo_intro_final.wmv)
http://asp.net/default.aspx?tabindex=4&tabid=3000
http://asp.net/learn/howdoi/default.aspx?tabid=63

全面介绍asp.net2.0 功能

1.DataView的data binding
使用northwinds.mdf数据库
在配置dataview 的data source时使用 select statement, 并设置 where clause,
指定source为QueryString, QueryString Field为CustomerID.
或指定source为control, ControlID为gridview1

如果要使用主从两个dataview,
需要在主gridview中设置DataKeyName,并添加select column

在从gridview中设置其data source的查询语句的source为control, ControlID为gridview1

2.使用Theme
App_Themes下建立某个theme对应的folder,将Theme相关的文件(包括.css,.skin, 图片) 放到文件夹中.

skin文件的写法:
<asp:TextBox BackColor=”Green” Runat=”Server” />
<asp:TextBox SkinID=”BlueTextBox” BackColor=”Blue” Runat=”Server” />
<asp:BulletedList BulletStyle=”CustomImage” BulletImageUrl=”BulletImages/OrangeBullet.gif” Runat=”Server” />
第一个skin不包含 SkinID,被当成默认skin,适用于所有的TextBox.

<system.web>
<pages theme=”ThemeName” styleSheetTheme=”ThemeName”/>
</system.web>

在某个Page中使用theme
<%@ Page Theme=”ThemeName” %>
<%@ Page StyleSheetTheme=”ThemeName” %>

将主题应用于页面时,主题中所设置的任何控件属性都优先于页面中所设置的任何属性。
例如,如果主题指定所有 TextBox 控件的背景都应当显示为橙色,那么即使个别 TextBox
控件的 BackColor 属性具有不同的值,页面中所有 TextBox 控件的背景也仍然都将显示为
橙色。

在 ASP.NET 中,优先级的顺序是:
Theme,包括 Web.config 文件中设置的主题。
Page
StyleSheetTheme
比如skin文件中定义:
<asp:Label runat=”server” ForeColor=”red” Font-Size=”14pt” Font-Names=”Verdana” />
Page中将Lable1.ForeColor 设置为 blue。
如果使用<pages theme=”ThemeName”>Lable1为 red,
如果使用<pages StyleSheetTheme=”ThemeName”>Lable1为 blue,

动态加载Theme

Protected void Page_PreInit(object sender, EventArgs e)
{
switch (Request.QueryString[”theme”])
{
case “Blue”:
Page.Theme = “BlueTheme”;
break;
case “Pink”:
Page.Theme = “PinkTheme”;
break;
}
}

3. 使用master page
快速修改一个page:
1. 删光所有代码,只剩<%@page
2. 在<%@page 中写 MasterPageFile=”"
3. 切换到design view, 选择”Create Custom Content”

4. 用户登录,权限
使用web site admin tool生成config, user account, user role
使用loginview
使用LinginStatus
使用CreateUserWizard

5. Site map
Web.sitemap
使用TreaView ,将datasource设为SitemapDatasource
使用SiteMapPath
在web.config中使用 securityTrimmingEnable=”true”,可过滤掉用户无权访问的链接.

6. 使用 profile
类似app setting,但是保存在sqlserver 中
在web.config中添加
<profile>
<properties>
<add name =”FullName” defaultValue= “”>
</properties>
</profile>
使用:
//读
if(!page.IsPostBack)
{
TextBox1.Text = Profile.FullName;
}
//写
Profile.FullName = TextBox1.text

参考
演练:在 Visual Studio 中使用主题自定义网站
http://msdn2.microsoft.com/zh-cn/library/zcsbskx7.aspx

May 20, 2006

MS 著名写手Dino Esposito

Filed under: ASP.NET

http://msdn.microsoft.com/asp.net/community/authors/dinoesposito/default.aspx

Scott Guthrie有关vs2005的一些文章(转载)

Filed under: ASP.NET

转自http://blog.joycode.com/saucer/archive/2005/08/30/62690.aspx

ASP.NET之父Scott Guthrie有关ASP.NET 2.0和VS 2005的文章,

1。VS 2005中的Web项目系统提供的新功能 (VS 2005 Web Project System: What is it and why did we do it?)

2。如何在VS 2005和Web项目系统中使用 IIS (Using IIS with VS 2005 and the new Web Project system)

3。如何设置 ASP.NET 2.0的应用服务使用SQL Server 2000和SQL Server 2005 (Configuring ASP.NET 2.0 Application Services to use SQL Server 2000 or SQL Server 2005)

4。更好地管理VS 2005Web项目中文件的几个技巧 (Some techniques for better managing files in VS 2005 Web Projects)

5。如何使用VS 2005建立可重用的ASP.NET用户控件和页面库 (Building Re-Usable ASP.NET User Control and Page Libraries with VS 2005)

May 13, 2006

ASP.NET 的Session State

Filed under: ASP.NET

1.Session的本质
每一个用户和web application交互过程被称为Session.
为了可以给每个Session存取一些信息,出现了Session state机制,SessionState实际上就是一个
在seesion 的生命周期中可以读写的hashtable或dictionary(在ASP时代,这个数据结构存放在内存中),
Session[”Stocks”] =” “; //写
string stockString = Session[”Stocks”];//读

如何区分不同用户的session state呢? 在ASP时代,每一个用户在session开始时会得到一个key,
这个key会被存在cookie中,每一个用户请求都会把这个key也发给server,server就能根据这个key
找到该用户对应的session state.

2.局限
以上是session最初的实现机制,很快,这个实现就被发现有如下的局限性
[1] ASP session state存放在asp的工作进程中,如果进程崩溃,或被回收,session state将丢失
[2] ASP session state存放在asp的工作进程中,所以在使用server farm的情况下,一个server上
的用户的session 信息在另一个server将不可用.
[3] 用户可能禁止cookie,这会导致session state不可用

3.ASP.NET的session state
ASP.NET支持3种session state的存储方式.
[1] in-process 和asp的session state兼容,Session Value被存放在ASP.net 的工作进程的内存中.
ASP.NET的工作进程为: aspnet_wp.exe或w3wp.exe(win 2003)

web.config的写法
<configuration>
<sessionstate mode=”inproc” timeout=”20″ />
</configuration>

[2] state server
session 会被存在state server上一个名为aspnet_state.exe的service的内存中,这个service是一个独立的进程,
可以运行在和IIS不同的机器上, 防止工作进程崩溃后session丢失.
首先要启动 service : net start aspstate
再在web.config中设定mode,server, port
<configuration>
<sessionstate mode=”stateserver”
cookieless=”false”
timeout=”20″
server=”127.0.0.1″
port=”42424″ />
</configuration>

[3] sql server
session会被存在sql server中,用于支持server farm
首先要安装相应的数据库,sql脚本存在于Microsoft.NET\Framework\[version]\
osql -S [server name] -U [user] -P [password] <InstallSqlState.sql

或执行

Microsoft.NET\Framework\[version]\\aspnet_regsql -S .\sql2k5 -E -ssadd -sstype p

再在web.config中设定mode,server, port
<configuration>
<sessionstate mode=”sqlserver”
cookieless=”false”
timeout=”20″
sqlconnectionstring=”data source=MySqlServer; user id=<…>; password=<…>”/>
</configuration>

同时ASP.NET还实现了无cookie的 session state访问.
ASP.NET通过ISAPI filter修改了URL,
http://localhost/(lit3py55t21z5v55vlm25s55)/Application/SessionState.aspx
这样就相当于提供了cookie.
–如何根据一个原始的用户请求来修改URL呢?

参考资料

ASP.NET Session State(2000)***

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

Underpinnings of the Session State Implementation in ASP.NET(Dino Esposito 2003.9)*****

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

.NET Framework Developer’s Guide: Session State

PRB: Session State Is Lost in Web Farm If You Use SqlServer or StateServer Session Mode
http://support.microsoft.com/default.aspx?scid=kb;en-us;325056

Working on a Web Farm(1999)
http://www.microsoft.com/mind/0699/basics/basics0699.asp

How to create keys by using Visual Basic .NET for use in Forms authentication
http://support.microsoft.com/kb/313091/






















Get free blog up and running in minutes with Blogsome
Theme designed by Hadley Wickham