Case by Case..

Wang Ting's Tech Blog
随笔 - 40, 评论 - 250, 引用 - 12

导航

关于

勿发广告,谢谢配合

标签

每月存档

最新留言

广告

隐藏IE下载对话框的Save As按钮...

这件事,这些年来已经和客户说了无数遍:这是客户端浏览器的行为,我们在服务器端的代码|程序中没有控制,所以是做不到的……

今天一个偶然的机会发现原来我竟然错了,Windows XP SP2带的IE 6早已经实现了这个功能了……

CONTENT Attribute | content Property
http://msdn2.microsoft.com/en-us/library/ms533689.aspx

技术的车轮原来就这么不停的在向前滚动着……

 

posted on 2007-12-03 11:38:00 by TingWang  评论(6) 阅读(4932)

_ctl0 vs ctl00

ASP.Net 2.0中把默认的control ID前缀_ctl0改为ctl00了,可能有很多依赖control ID的代码会无法正常工作。

其实Web.Config中有下面这个选项可以控制:

xhtmlConformance Element (ASP.NET Settings Schema)
http://msdn2.microsoft.com/en-us/library/ms228268.aspx

<system.web>

<xhtmlConformance mode="Legacy"/>

当然最理想的做法还是动态取Control.ClientID。

posted on 2006-11-22 16:25:00 by TingWang  评论(2) 阅读(7344)

System.Web.RegularExpressions..

又一个被遗忘的Namespace,没有文档……

 

Reflector打开,可以看到很多有用的正则表达式:

 

Directives:

 

"\\G<%\\s*@(\\s*(?\\w+(?=\\W))(\\s*(?=)\\s*\"(?[^\"]*)\"|\\s*(?=)\\s*'(?[^']*)'|\\s*(?=)\\s*(?[^\\s%>]*)|(?)(?\\s*?)))*\\s*?%>"

 

Server Tag:

 

"<%(?!#)(([^%]*)%)*?>"

?

Tag:

?

"\\G<(?[\\w:\\.]+)(\\s+(?[-\\w]+)(\\s*=\\s*\"(?[^\"]*)\"|\\s*=\\s*'(?[^']*)'|\\s*=\\s*(?<%#.*?%>)|\\s*=\\s*(?[^\\s=/>]*)|(?\\s*?)))*\\s*(?/)?>"

 

这次做ASCX Design Time多亏这些Regex,配上System.Web.UI.Design.ControlParser..

 

只是不明白“\G”是什么意思,似乎文档上找不到,加了以后似乎要从StringPosition的头一个字符开始匹配……

 

 

posted on 2005-06-13 01:00:00 by TingWang  评论(6) 阅读(3979)

在ASP.Net 1.1中实现Script Callback框架

Dino写了三篇文章介绍Script Callback

 

Script Callbacks in ASP.NET

http://msdn.microsoft.com/msdnmag/issues/04/08/CuttingEdge/

 

Custom Script Callbacks in ASP.NET

http://msdn.microsoft.com/msdnmag/issues/05/01/CuttingEdge/

 

Implications of Script Callbacks in ASP.NET

http://msdn.microsoft.com/msdnmag/issues/04/12/CuttingEdge/

 

我在ASP.Net 1.1里写了一个Page的继承类,可以像ASP.Net 2.0一样使用Script Callback

 

Implementing Callback framework in ASP.Net 1.1

http://blog.joycode.com/tingwang/articles/47304.aspx

 

没什么难度,估计别人也早已经写过,权当灌水……

 

posted on 2005-04-08 22:20:00 by TingWang  评论(1) 阅读(4814)

ASP.Net 中运行需要很长时间处理的任务

经常看到用户要在ASP.Net 中跑一些需要很长时间才能返回的任务(如DTS Package等等)。这样一来一个页面可能很长时间无法Render到客户端,而使用户对当前任务的状态产生疑惑。

 

MSDN上看到了一些解决方案:

 

Build Your ASP.NET Pages on a Richer Bedrock

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

 

Asynchronous Wait State Pattern in ASP.NET

http://msdn.microsoft.com/msdnmag/issues/03/12/DesignPatterns/

 

它们都将用户重定向到一个等待页面,然后再重定向到执行任务的页面。任务的执行过程中,用户看到的是等待页面,等任务执行完,整个执行任务的页面就会彻底返回到客户端。这种做法还是发现有个问题,因为任务执行过程中IE和服务器之间没有任何通讯,IIS服务器会将非活动的连接关闭。这个超时值虽然可以在网站属性(Web Site)里设得更长一点,但是这个超时太大会对整个网站的性能会有影响。

 

这里可以采用另外一种方法:在服务器端另起一个线程执行任务,并通过客户端脚本不停刷新页面来给用户反馈,只到任务运行结束。这样也可以防止同一个任务被同时执行多次:

 

ASP.Net Lengthy Task Visual Feedback Page

http://blog.joycode.com/tingwang/articles/47292.aspx

 

 

posted on 2005-04-08 20:51:00 by TingWang  评论(5) 阅读(4757)

ASP.Net Web Application shutdown on idle?

不知为何很多人都有这么一种印象:一个ASP.Net Web Applicationidle很长时间以后会被worker process关闭,当我们再发request的时候Web Application会被重新动态编译,重新启动,会很慢……有这种印象的人还包括ASP.Net MVP

 

Force ASP.NET Apps to Keep-Alive

http://authors.aspalliance.com/paulwilson/articles/?id=12

 

我从来没有听说过ASP.Net(至少1.1)有这么的功能。我只听说过ASP.Networker process会因为idleshutdown,而且这是可以通过machine.configinetmgr设置的,但从来没有见过什么文档说Web ApplicationWeb ApplicationAppDomain会被关闭……如果有谁见过还望不吝赐教,我不想发布错误信息,误人……

 

下面的链接介绍了Application restart的原因:

 

Why does App restart? (FAQ)

http://asp.net/Forums/retired/ShowPost.aspx?PostID=232621

 

posted on 2005-03-03 21:39:00 by TingWang  评论(2) 阅读(3799)

在ASP.Net DataGrid中制作弹出式的日期选择Calendar

客户要在DataGrid里绑定日期数据,并显示一个按钮,按钮按了以后弹出一个Calendar,可供选择日期。选择的结果要还给原来的DataGrid。给他做了一个:

 

How to implement popup Calendar dialog box with DataGrid

http://blog.joycode.com/tingwang/articles/40933.aspx

 

特此留念,以备复用……

 

有一点,在DataGrid.ItemCreated事件里取不到control的正确的Client IDUnique ID,老是返回“TextBox1”,弄得client side script很难写……而在DataGrid.ItemDataBound事件里就能取到“DataGrid1__ctl2_TextBox1”……未及深究,不知道有没有人能给个solid的解释……

 

posted on 2004-12-10 20:27:00 by TingWang  评论(2) 阅读(7920)

为WebControl实现设计时(Design Time)的Left, Top属性

有没有试过给ASP.Net Web Control实现Left和Top属性?就像WinForm的control一样,当在Designer里拖动control的时候,Properties window里的Left和Top跟着一起改变。当在Properties window里修改Left和Top时,control在Designer里位置跟着移动。

看似简单的问题,真的要做的话就会发现其难度了……

How to interact with Style["LEFT"] and Style["TOP"] of the WebControl during design time
http://blog.joycode.com/tingwang/articles/39633.aspx

posted on 2004-11-24 22:45:00 by TingWang  评论(5) 阅读(3561)

Small Trick: How to add "Follow Up" flag for mails sent by System.Web.Mail

Outlook里发出去的mail都可以设Follow Up flagDue time,这个功能蛮实用……如何编程实现?

 

有人在Newsgroup里贴了段CDOExcode:

 

http://groups.google.com/groups?q=outlook+follow+up&hl=zh-CN&lr=&c2coff=1&selm=eApolE7pEHA.2864%40TK2MSFTNGP12.phx.gbl&rnum=5%20&hl=zh-CN&lr=&c2coff=1&selm=eApolE7pEHA.2864%40TK2MSFTNGP12.phx.gbl&rnum=5

 

CDOEx只有装了Exchange Server的机器上才有……

 

其实只要给System.Web.Mail.MailMessage设置相应的Header就可以了:

 

message.Headers.Add("X-Message-Flag", "Follow up");

message.Headers.Add("Reply-By", "Tue, 26 Oct 2004 01:00:00 +0900");

 

posted on 2004-10-25 12:07:00 by TingWang  评论(1) 阅读(3221)

思归的“动态控件的状态问题”的分析

思归的“动态控件的状态问题”很有意思:

http://blog.joycode.com/saucer/archive/2004/10/20/35927.aspx

 

希望写下这样的logic对大家做troubleshooting有所帮助。我们可以这样分析这个问题:

 

第一步,简化一下Page。建一个新的ASP.Net Web Application,用下面的code

 

private void Page_Load(object sender, System.EventArgs e)

{

        DropDownList ddlDynamic = new DropDownList();

        ddlDynamic.ID = "ddlDynamic";

        HtmlForm form1 = (HtmlForm)this.FindControl("Form1");

        if (!IsPostBack)

        {

                ddlDynamic.Items.Add("Before");

        }

        form1.Controls.Add(ddlDynamic);

        if (!IsPostBack)

        {

                ddlDynamic.Items.Add("After");

        }

}

 

Page上扔个Button,以便可以PostBack。运行后Postback的结果,“Before” item没被保留,“After”被保留了。问题被isolate:问题不在于DropDownList或者ListCollection对于view state的处理出问题,而是特定一个ListItem view state的处理有异。

 

现在有目标了,接下来看ListItem source code:

 

internal object SaveViewState()

{

      if (this.misc.Get(2) && this.misc.Get(3))

      {

            return new Pair(this.Text, this.Value);

      }

      if (this.misc.Get(2))

      {

            return this.Text;

      }

      if (this.misc.Get(3))

      {

            return new Pair(null, this.Value);

      }

      return null;

}

 

可以看到只有misc.Get(2)misc.Get(3)符合一定条件才存view state,鉴于miscprivate member,继续在ListItemcode里找什么会影响misc.Get(2) or misc.Get(3)的值,结果如下:

 

internal bool Dirty

{

       set

      {

            this.misc.Set(2, value);

            this.misc.Set(3, value);

      }

}

 

找到了唯一的可能,在Reflector里看Set方法的Callee Graph,找到System.Web.UI.WebControls.ListItemCollection.Add(ListItem):Void方法。接续看source code:

 

public void Add(ListItem item)

{

      this.listItems.Add(item);

      if (this.marked)

      {

            item.Dirty = true;

      }

}

 

这里有一个private bool marked flag。继续在ListItemCollection里找:

 

internal void TrackViewState()

{

      this.marked = true;

      for (int num1 = 0; num1 < this.Count; num1++)

      {

            this[num1].TrackViewState();

      }

}

 

void IStateManager.TrackViewState()

{

      this.TrackViewState();

}

 

好了,看来这个方法就是关键了……由于是Interface的方法,我们可以尝试一下在Page2里调用它:

 

((IStateManager)(ddlDynamic.Items)).TrackViewState();

if (!IsPostBack)
{
for (int i=1; i <=3; i++)
ddlDynamic.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
form1.Controls.Add(ddlDynamic);

 

确实是起作用了……鉴于如此,我们可以猜测ControlCollection.Add一定调用了System.Web.UI.WebControls.ListItemCollection.TrackViewState()这个方法。要证明这点容易多了……

 

WinDbg,在System.Web.UI.WebControls.ListItemCollection.TrackViewState()方法上设个断点。Call Stack如下:

 

019cf8b0 06538fd0 [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListItemCollection.TrackViewState()
019cf8b4 06538fbe [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListControl.TrackViewState()
019cf8bc 06538e53 [DEFAULT] [hasThis] Void System.Web.UI.Control.InitRecursive(Class System.Web.UI.Control)
019cf8d8 0653758a [DEFAULT] [hasThis] Void System.Web.UI.Control.AddedControl(Class System.Web.UI.Control,I4)
019cf8f4 06537462 [DEFAULT] [hasThis] Void System.Web.UI.ControlCollection.Add(Class
System.Web.UI.Control)
019cf904 063c06fc [DEFAULT] [hasThis] Void WebApplication37.WebForm3.Page_Load(Object,Class System.EventArgs)
at [+0x13c] [+0x8c] c:\inetpub\wwwroot\webapplication37\webform3.aspx.cs:36
019cf944 065391a4 [DEFAULT] [hasThis] Void System.Web.UI.Control.OnLoad(Class System.EventArgs)



好了……一切都明了……

posted on 2004-10-21 13:11:00 by TingWang  评论(5) 阅读(3328)

有滚动条、固定Header的ASP.Net DataGrid实现

如果要render出滚动条,我们可以把DataGrid放在<div>里。如果还要一个不随滚动条滚动的Header,我们可以在<div>外另外render一个Header。我写过一个Web Control Library详见:

Fixed Header Scrollable DataGrid control
http://blog.joycode.com/tingwang/articles/32789.aspx

(最可恨的customer居然要pager和滚动条同时用……)

posted on 2004-09-07 22:49:00 by TingWang  评论(10) 阅读(6133)

ASP.Net 1.x 中 __doPostBack实现的问题

ASP.Net 1.x的client side postback script是这样的:
<!--
 function __doPostBack(eventTarget, eventArgument) {
  var theform;
  if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
   theform = document.forms["Form1"];
  }
  else {
   theform = document.Form1;
  }
  theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
  theform.__EVENTARGUMENT.value = eventArgument;
  theform.submit();
 }
// -->

它是通过form.submit()去submit的。这样就有一个问题,form.onsubmit事件不会被触发,这么一来可能有些client side validation script就被绕过了。在ASP.Net 2.0里,这个问题被fix了。对于ASP.Net 1.x,据我所知,SP1也没有解决这个问题。我们可以使用下面的代码解决这个问题:

string myDoPostBack = @"
<script language=""javascript"">
<!--
 function __myDoPostBack(eventTarget, eventArgument) {
  var theform;
  if (window.navigator.appName.toLowerCase().indexOf(""netscape"") > -1) {
   theform = document.forms[""Form1""];
  }
  else {
   theform = document.Form1;
  }
  theform.__EVENTTARGET.value = eventTarget.split(""$"").join("":"");
  theform.__EVENTARGUMENT.value = eventArgument;
  if ((typeof(theform.onsubmit) == ""function"") && theform.onsubmit()!=false) {
   theform.submit();   
  }
 
 }
 __doPostBack = __myDoPostBack
// -->
</script>";
RegisterStartupScript("myDoPostBack", myDoPostBack);

posted on 2004-09-07 22:11:00 by TingWang  评论(2) 阅读(4281)

Powered by: Joycode.MVC引擎 0.5.2.0