人生是一场不能存盘的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” 才会格式化显示