posts - 73,  comments - 11,  trackbacks - 0

(一). 注册链接

 

http://www.waoindia.com/register.php?r=nacarat

 

复制到浏览器地址栏中注册.

 

(二). 使用说明介绍

 

点Register进入注册页面:

 
 

点击 Login 输入用户名、密码、验证码,点

 

Login登录。点击链接赚钱:

 

 

 

提示:若发现点击广告后很久没有出现倒计数,可以关闭页面,重新打开广告或先换其他广告点击。打开广告页面后必须等到广告页面倒计时完毕出现如下图中的"Done"字样才能关闭页面,否则将得不到此次点击的点击额。同时不能同时打开两个广告页面,一个广告页面Done以后才能点击另一个广告页面

 
 

其他按钮介绍
1、My Account:可以查看你的下线连接,推荐下线人数,收入所得等
2、Your Profile:可以修改你的个人资料
3、Your History:查看你的请款及支付记录
4、View Your Referrals:查看下线用户名和点击数量
5、Convert to Ads/Cash:请款按钮
6、Upgrade Your Account:升级帐户
7、Purchase Referrals:购买下线
8、Logout:退出

 
 

如何请款:


 

打开My Account,点击Convert to Ads/Cash请款按钮,然后点Convert to Cash via PayPal即可,请款2-5天内到帐!

 

 

使用其实很简单, 通过地址:

 

http://www.waoindia.com/register.php?r=nacarat

 

注册一下之后, 登录进入, 一看就会了.

posted @ 2009-02-05 16:54 nacarat 阅读(54) | 评论 (0)编辑

前一阵子,项目中的一个页面每秒只能处理300次,而这个页面的逻辑也不复杂,就是根据条件拼出一个字串然后输出。开始以为这里面逻辑太复杂,所以有问题。不过后面发现了vs里面带了性能分析工具,于是抱着试试看的想法,作了一下性能分析。最后的结果让人大吃一惊:string.format这个操作竟然用掉了一半的时间,为啥它会这么费时间呢?为了真相,我用.net reflector查看了string的实现:

public static string Format(IFormatProvider provider, string format, params object[] args)
{
    if ((format == null) || (args == null))
    {
        throw new ArgumentNullException((format == null) ? "format" : "args");
    }
    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
    builder.AppendFormat(provider, format, args);
    return builder.ToString();
}


很让人吃惊,string.format竟然是调用了StringBuilder的AppendFormat来实现的。再继续根下去(这个源码只是通过IL得来的,可能和原始的不太一样,但是差不多了),注意里面的红色的那句:

public StringBuilder AppendFormat(IFormatProvider provider, string format, params object[] args)
{
    int num3;
    if ((format == null) || (args == null))
    {
        throw new ArgumentNullException((format == null) ? "format" : "args");
    }
    char[] chArray = format.ToCharArray(0, format.Length);
    int index = 0;
    int length = chArray.Length;
    char ch = '\0';
    ICustomFormatter formatter = null;
    if (provider != null)
    {
        formatter = (ICustomFormatter) provider.GetFormat(typeof(ICustomFormatter));
    }
Label_004E:
    num3 = index;
    int num4 = index;
    while (index < length)
    {
        ch = chArray[index];
        index++;
        if (ch == '}')
        {
            if ((index < length) && (chArray[index] == '}'))
            {
                index++;
            }
            else
            {
                FormatError();
            }
        }
        if (ch == '{')
        {
            if ((index < length) && (chArray[index] == '{'))
            {
                index++;
            }
            else
            {
                index--;
                break;
            }
        }
        chArray[num4++] = ch;
    }
    if (num4 > num3)
    {
        this.Append(chArray, num3, num4 - num3);
    }
    if (index == length)
    {
        return this;
    }
    index++;
    if (((index == length) || ((ch = chArray[index]) < '0')) || (ch > '9'))
    {
        FormatError();
    }
    int num5 = 0;
    do
    {
        num5 = ((num5 * 10) + ch) - 0x30;
        index++;
        if (index == length)
        {
            FormatError();
        }
        ch = chArray[index];
    }
    while (((ch >= '0') && (ch <= '9')) && (num5 < 0xf4240));
    if (num5 >= args.Length)
    {
        throw new FormatException(Environment.GetResourceString("Format_IndexOutOfRange"));
    }
    while ((index < length) && ((ch = chArray[index]) == ' '))
    {
        index++;
    }
    bool flag = false;
    int num6 = 0;
    if (ch == ',')
    {
        index++;
        while ((index < length) && (chArray[index] == ' '))
        {
            index++;
        }
        if (index == length)
        {
            FormatError();
        }
        ch = chArray[index];
        if (ch == '-')
        {
            flag = true;
            index++;
            if (index == length)
            {
                FormatError();
            }
            ch = chArray[index];
        }
        if ((ch < '0') || (ch > '9'))
        {
            FormatError();
        }
        do
        {
            num6 = ((num6 * 10) + ch) - 0x30;
            index++;
            if (index == length)
            {
                FormatError();
            }
            ch = chArray[index];
        }
        while (((ch >= '0') && (ch <= '9')) && (num6 < 0xf4240));
    }
    while ((index < length) && ((ch = chArray[index]) == ' '))
    {
        index++;
    }
    object arg = args[num5];
    string str = null;
    if (ch == ':')
    {
        index++;
        num3 = index;
        num4 = index;
        while (true)
        {
            if (index == length)
            {
                FormatError();
            }
            ch = chArray[index];
            index++;
            switch (ch)
            {
                case '{':
                    if ((index < length) && (chArray[index] == '{'))
                    {
                        index++;
                    }
                    else
                    {
                        FormatError();
                    }
                    break;

                case '}':
                    if ((index < length) && (chArray[index] == '}'))
                    {
                        index++;
                    }
                    else
                    {
                        index--;
                        if (num4 > num3)
                        {
                            str = new string(chArray, num3, num4 - num3);
                        }
                        goto Label_0253;
                    }
                    break;
            }
            chArray[num4++] = ch;
        }
    }
Label_0253:
    if (ch != '}')
    {
        FormatError();
    }
    index++;
    string str2 = null;
    if (formatter != null)
    {
        str2 = formatter.Format(str, arg, provider);
    }
    if (str2 == null)
    {
        if (arg is IFormattable)
        {
            str2 = ((IFormattable) arg).ToString(str, provider);
        }
        else if (arg != null)
        {
            str2 = arg.ToString();
        }
    }
    if (str2 == null)
    {
        str2 = string.Empty;
    }
    int repeatCount = num6 - str2.Length;
    if (!flag && (repeatCount > 0))
    {
        this.Append(' ', repeatCount);
    }
    this.Append(str2);
    if (flag && (repeatCount > 0))
    {
        this.Append(' ', repeatCount);
    }
    goto Label_004E;
}

发现里面会有new string,这时候会有新的内存分配出现,也就是说string.format会产生很多临时的string对象,这个会费时间,同时也会使GC的工作量增加.既然这里面调用了stringbuilder来实现的,那为啥不直接调用stringbuilder.append来实现。于是我就把原来的实现改成了stringbuilder的append,同时设置它初始容量为我们预期的大小,通过测试,这部分的性能提高了十倍。于是性能问题解决了。

最后,我觉得如果程序的性能很重要,而在这里面又经常有string.format的时候,还是改用stringbuilder.append来实现,虽然麻烦一些,代码也不好看,但是效果还是会很明显的。

posted @ 2008-12-19 11:17 nacarat 阅读(57) | 评论 (0)编辑
     摘要:   http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000022.asp摘要:本文介绍了怎么在ASP.NET 2.0中使用Membership新特性,并且介绍了怎么两种不同的Membership的Provider:ActiveDirectoryMembershipProvider和SqlMembershipPro... 阅读全文
posted @ 2008-12-12 10:06 nacarat 阅读(47) | 评论 (0)编辑
     摘要: 应用程序安全设计策略登陆页面后台如果管理后台可以公网访问,后台登陆页面不能出现标志性文本,例如“新浪XX管理平台”这样的文字,否则有被搜索引擎收入的风险,特别要注意原代码中的<title>里面为空,页面上需要例如“新浪XX管理平台”这样的文字时,全部使用图片表现。 登陆流程登陆页面:为了避免用户登陆的时候,登陆密码被第三者截取,所以采用以... 阅读全文
posted @ 2008-12-10 09:51 nacarat 阅读(97) | 评论 (0)编辑
 

--基本资料--
    
姓名:林涛          性别:男                年龄:23            
     学历:大专          现所在地:北京           电话:13718708034    MSN:admin@nacarat.cn

 

--自我评价
    个性随和、乐观、积极向上。在工作中能始终保持极大的热情,善于学习新技术。参与分过较大规模系统的开发,在开发过程中能很好的协同他人完成各种开发任务。

 

--教育经历
    2003.9 ~ 2006.7    福州职业技术学院    web应用程序设计

 

--工作经验
    2007-10 ~ 至今     厦门吉联科技有限公司    .net高级软件工程师
    工作职责:负责公司物流类系统的开发与设计工作

2006-2 ~ 2007-10   厦门易名网络有限公司    .net软件工程师
    工作职责:从事电子交易类的网站开发工作。
 

 

--项目经历--  
    
中海集装箱运输有限公司集装箱班轮运输信息系统 B/S架构

项目规模: 25

系统特点:该系统采用三层架构开发,具有高度稳定性,兼容性、可扩展性、易升级性、易维护性,能够承受大负荷的业务量和用户数量;并引入XML标准和深化XML-EDI技术,使本系统能与外部系统及第三方软件实现无缝对接;并且应用了如:多主题、Ajax、角色化权限管理、URL重写、静态页面生成、跨数据库管理平台、WEB服务器控件、HttpModule、Web Services、orm映射,等多种先进的主流技术。

    工作职责:1.担当TeamLeader角色;2.协调项目组成员工作内容;3.编写系统代码;4.指导新人完成开发工作;5.编制设计文档;

 

民生银行信用卡中心 B/S架构

项目规模: 8

项目地址:http://creditcard.cmbc.com.cn

 

民生银行信用卡商城 B/S架构

项目规模: 8人

项目地址:http://shop.cmbc.com.cn

 

国际空运货代管理系统 B/S架构

项目规模: 12

 

易名域名电子商务系统      B/S架构

项目规模: 2

项目地址:http://bid.ename.cn


--
技术特长--
    HTML
:                熟练            两年以上
    JavaScript:          熟练            两年以上
    Ajax:                熟练            两年以上 
    Asp.Net:             熟练            两年以上
    WEB SERVICES:        熟练            两年以上
    SQL SERVER 2000:     熟练            两年以上

posted @ 2008-11-12 12:59 nacarat 阅读(145) | 评论 (1)编辑
在Web标准中的页面布局是使用Div配合CSS来实现的。这其中最常用到的就是使整个页面水平居中的效果,这是在页面布局中基本,也是最应该首先掌握的知识。不过,还是经常会有人问到这个问题,在这里我简单总结一下使用Div和CSS实现页面水平居中的方法:

一、margin:auto 0text-aligh:center
    在现代浏览器(如Internet Explorer 7、Firefox、Opera等)现代浏览器实现水平居中的方法很简单,只要设定到左右两侧的空白为自动即可。意即:
  1. #wrap { margin:0 auto;}  

上面这段代码的意思是说使wrap这个div到左右两侧的距离自动设置,上下为0(可以为任意)。请在现代浏览器
(如Internet Explorer 7、Firefox、Opera等)中运行现在的代码:
点击此处查看运行效果

    上面的效果很好。但是这在Internet Explorer 6及改正的版本中是不起作用的,不过幸好它有自己的解决办法。在Internet Explorer中text-align属性是可继承的,即在父元素中设置后在子元素中就默认具有了该属性。因此我们可以在body标签中设置text-align属性值为center,这样页面内所有的元素都会自动居中,同时我们还要加一个hook把页面中的文字变成我们习惯的阅读方式——居左对齐。因此我们要如此来写代码:
  1. body {text-align:center;}  
  2. #wrap {text-align:left;}  

这样在Internet Explorer中我们就轻松实现了Div的居中对齐。因此要在所有的浏览器中显示居中的效果,我们就可以这样写我们的代码:
  1. body { text-align:center; }  
  2. #wrap { text-align:left;  
  3.              margin:0 auto;  
  4. }  


下载文件 点击此处查看运行效果

    不过这里有一个前提,就是设置居中的元素要有固定的宽度,比如这里我们设定了为760像素。

二、相对定位与负的边距
    对于wrap进行相对定位,然后使用负的边距抵消偏移量。这种方法比较简单还很容易实现:
  1. #wrap {  
  2. position:relative;  
  3. width:760px;  
  4. left:50%;  
  5. margin-left:-380px  
  6. }  

这段代码的意思是,设置wrap的定位是相对于其父元素body标签的,然后将其左边框移动到页面的正中间(也就是left:50%含意);最后我们再从中间位置向左偏移回一半的距离来,这样就实现了水平居中了。

下载文件 点击此处查看运行效果

    同样,在设定水平居中前你需要设定一个固定的宽度。

P.S.究竟选择哪个方法?
    上面两个方法究竟选择哪种方法好呢?在第一种方法中貌似使用了Hack技术,其实并没有,它是中规中矩的Web标准写法,完全符合规范,因此,两个种方法中完全可以随便的选取其中的任一种进行使用,他们不存在CSS hack的问题。

三、其它的居中方式
    上面所说的都是设定了具体宽度的情况下水平居中的实现。有时候我们想做一个弹性布局,或者当一个元素处于一个容器中时我们只想让它居中并不想设定一个具体的宽度。其实这并不是真正的居中布局,就像对一个100%长度的元素来说,你说它是居中对齐还是居左对齐呢?所以所有不高宽度的居中都不是真正的居中。这样的设计我们是使用的像元素的padding来设置的,实际中我们是改变了父元素的容器大小:
如我们希望wrap元素长度随窗口而改变,同时又维持居中,我们就可以这样写:
  1. body {  
  2.  padding:10px 150px;  
  3. }  
  4.   

这里,我们只需要保持父元素左右两侧的填充是相等的就可以了。
下载文件 点击此处查看运行效果
当然这只是“貌似居中”,不过却常常很有用处。
posted @ 2008-11-06 15:17 nacarat 阅读(261) | 评论 (0)编辑

在使用 ASP.NET 的时候,我们仍然在许多情况下需要使用客户端脚本。以下是笔者根据自己的经验和一些粗浅的研究,对此作一个简要的总结。

  一、在 HTML 里直接写脚本

  这个方法是最简单的,直到如今我写网页的时候也几乎还是使用最多的一种方式。也许一些经常使用 RegisterClientScriptBlock 的人会觉得这种方法老土,不过在我看来,它除了可以减少编译时间以外,更主要的是可以减少代码量,可读性也要好一些,更或许还可以避免一些潜在的错误。

  但是有些情况下,直接写的方法是很难完成要求的,比如说当脚本需要依赖我们在代码中动态生成的控件时,就必须要采用 Register 的方法了。

  二、使用 Literal 控件写脚本

  Literal 控件基本上就是写一段文字或代码,所以当然也可以写出客户端脚本来,实质上这个方法与第一个方法基本相同。以我个人来说,此种方法一般是用在写控件上。设想一个情况:我们需要根据某种条件来判断一批具有客户端脚本事件的控件是否显示,当然我们可以使用如 Panel 一类的容器,可是这些容器多半都要套一个 div 之类的东西,如果在某种情况下我们不希望这时出现 div 呢?当然或许是有更好更漂亮的办法,只是我都是简单地用一个 Literal 了事。^_^

  三、使用 Register Script 函数

  在 ASP.NET 1.x 中,Page 类提供了 RegisterClientScriptBlock、RegisterOnSubmitStatement 以及 RegisterStartupScript 函数,使得可以在代码中进行 ClientScript 绑定。不过到了 ASP.NET 2.0 当中,将这些函数统通移到了一个 ClientScriptManager 类中,并且还添加了类似的 RegisterClientScriptInclude 函数。在使用这个类的时候,我们可以通过 Page.ClientScript 来访问。下面介绍一下这几个函数的区别。

  RegisterClientScriptBlock:这个函数将 ClientScript 加到页面顶部,一般是在紧接着 <form> 标签的地方。需要注意的是,这个函数中的脚本在写入页面甚至执行的时候,页面的其它元素可能还没有载入完毕,因此可能不能正确地调用页面中的元素。这个函数比较常见的应用是一些客户端事件处理函数。

  RegisterClientScriptInclude:这个函数是 ASP.NET 2.0 新加入的,它一般用于将一个外部的 ClientScript 文件,比如一个 .js 文件链接入页面的时候。除此之外,它和 RegisterClientScriptBlock 基本一样,包括注意事项。

  RegisterStartupScript:这个函数将 ClientScript 加入到页面的底部,由此带来的好处自然就是可以正确地处理对页面元素的引用了。注意这里的脚本将会在页面的 onload 事件之前执行。一般来说,这里的代码都是一次性执行的。最常见的比如说是希望页面载入完毕之后弹出一个消息提示框,又或者在一个有框架的页面中,需要在一个页面装载完毕之后更新另一个页面的情况。

  RegisterOnSubmitStatement:这个函数则是将 ClientScript 与 onsubmit 事件绑定起来。

  一般的,在使用 RegisterClientScriptBlock 定义了事件处理函数后,我们可以采用以下的代码将函数与控件关联起来,这里,假定我们已经定义了一个 confirmDelete 函数:

1string script = @"return confirmDelete();";
2btnDelete.Attributes.Add("onclick", script);

  四、关于 RegisterClientScriptResource

  除了前一节提过的四个函数外,ASP.NET 2.0 还增加了一个 RegisterClientScriptResource 函数。这个函数与前几个的差异在于:它联接的是经过编译成资源的脚本。比如如下一行

1Page.ClientScript.RegisterClientScriptResource(this.GetType(), "script_resource.js");

  这里的 script_resource.js 必须是在服务端被编译进 assembly 中去,其方法是在服务端代码中添加如下一行

1[assembly: WebResource("script_resource.js""application/x-javascript")]

  如此一来之后,在生成的页面中,我们可以看到类似下面的代码(为了节省版面,我删减了 d 和 t 的长度):

1<script src="/webclient/WebResource.axd?d=oZ35V30&amp;t=63204" type="text/javascript"></script>

  这里的 WebResource.axd 的请求被送到服务端之后,由一个特定的 axd HttpHandler 来处理以取得相关的资源(这里就是 script-resource.js 文件)。在后面我们还可以看到,这个技术还有着更广泛的应用。

  五、GetPostBackClientHyperlink 与 GetPostBackEventReference

  这两个函数都可以取得一个字符串,它可以用来作为客户端向服务端提交 PostBack 之用。总体上两者的用途是一样的,主要区别在于:前者返回的串以 "javascript:" 打头,而后者则没有。看以下的例子:

1ClientScriptManager cs = Page.ClientScript;
2btnDelete2.Attributes.Add("onclick", cs.GetPostBackEventReference(btnDelete, btnDelete2.ID.ToString());
3linkDelete.HRef = cs.GetPostBackClientHyperlink(btnDelete, linkDelete.ID.ToString());

  看看这一段代码生成的相关 HTML 源码:

1<input name="btnDelete2" type="button" id="btnDelete2" value="Delete2" onclick="__doPostBack('btnDelete','btnDelete2')" />
2<href="javascript:__doPostBack('btnDelete', 'linkDelete')" id="linkDelete">Delete</a>

  从这个例子我们可以看到两个函数的使用,对于超链接的 HRef 来说,应当采用 GetPostBackClientHyperlink,否则浏览器可能不能正确地执行。

  六、通过客户端触发服务端事件

  有一些情况下,我们需要通过客户端的事件来触发服务端事件。比如说,我们想在一个 TextBox 的 onchange 事件中加一个检测,如果遇上了用户输入回车,那么就触发一个 btnGo 的服务端事件。(当然实际上这个例子我们也可以完全用 javascript 办到,这里仅作说明)。能办到吗?以下是一段代码:

1string sCommand = Page.ClientScript.GetPostBackClientHyperlink(btnGo, "");
2string script = @"javascript:keyClick(""EVAL_COMMAND"")";
3script = script.Replace("EVAL_COMMAND", strCommand);
4txtSearch.Attributes.Add("onkeydown", script);

  以下的相关的 javascript 代码:

1function keyClick(cmd)
2{
3  if (event.keyCode == 13{
4    eval(cmd);
5  }

6}

  好,根据前面所讲的 GetPostBackClientHyperlink 的功能,我们很容易地推断出第一段代码所生成的 HTML 源码:

<input type="text" id="txtSearch" onkeydown="javascript:keyClick(&quot;javascript:__doPostBack('btnGo','')&quot;);" />

  可以看到在 txtSearch 的 onkeydown 处理函数 keyClick 中,通过 eval 函数再次调用了 btnGo 的服务端事件从而实现了由客户端事件触发 PostBack。是不是有些奇妙?

  七、ASP.NET 中的 Ajax?-- Client Callback

  Ajax 技术由于其无刷新的页面更新而使许多老式 Web 应用显得极为笨重。并且我们知道有不少 Ajax 其实内部就是 XmlHttpRequest 或是一个 xmlRequestFrame 来实现的,而这两个 IE 早就支持。那么微软有提供基于或是类似于 Ajax 的实现么?我知道最近出了一个 Atalas,但其实除此之外,在 ASP.NET 2.0 中就已经有了实现类似功能的办法了。

  首先,我们必须要使页面继承自 ICallbackEventHandler 这个接口。方法可以有如下两种,分别对应于 Code-Inside 和 Code-Behind 模式:

1<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

1public partial class CallbackPage : System.Web.UI.ICallbackEventHandler 

  该接口是 ASP.NET 2.0 新加入的。接下来我们要实现它的两个成员方法(在我的本机 MSDN 里,有一些地方使用此接口的成员方法与实际成员不符,比如 RaiseCallbackEvent 的返回类型变成了 string 且没有 GetCallbackResult 方法,我估计是早期写好的但后来没有更新,大家看的时候要注意):

 1public int nCount = 0;
 2
 3public void RaiseCallbackEvent(String eventArgument)
 4{
 5  nCount = Convert.ToInt32(eventArgument) + 1;
 6}

 7
 8public string GetCallbackResult()
 9{
10  return nCount.ToString();
11}

  我们先写好接收回调函数的方法,用 javascript 写:

1function ReceiveServerData(rvalue, context)
2{
3  labelResult.innerText = rvalue;
4}

  好,随后我们需要将 Callback 链入页面,注意,关键部分到了:

1void Page_Load(object sender, EventArgs e)
2{
3  ClientScriptManager cs = Page.ClientScript;
4  String cbReference = cs.GetCallbackEventReference(this"arg""ReceiveServerData""context");
5  String callbackScript = "function CallServer(arg, context) {" + cbReference + ";}";
6  cs.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
7}

  最后,还需要写好调用的地方:

1<input type="button" value="TestCallback" onclick="CallServer(value, alert('数据递增!'))" />

  这里的 value 是需要实现递增的数据。注意递增过程是在 RaiseCallbackEvent 函数内完成的,它就相当于 Ajax 中加上了 AjaxMethodAttribute 的函数。运行一下测试,我们可以发现确实也实现了类似 Ajax 的无刷新页面!

  看看生成的 HTML 源码,我们可以看到一行 javascript 脚本资源链接,也是 "WebResource.axd?" 后跟一串参数的一个请求,如同之前讲过的 RegisterClientScriptResource 生成的结果一样。此外还可以看到页面最后有一个用 RegisterStartupScript 生成的一段:

1<script type="text/javascript"><!--
2WebForm_InitCallback();// -->
3</script>

  而 CallServer 函数则被扩展成了类似下面的样子: 

1function CallServer(arg, context) 
2{
3  WebForm_DoCallback('__Page',arg,ReceiveServerData,"",null,false); 
4}

  这里的 WebForm_InitCallback 和 WebForm_DoCallback 显然是在 WebRequest.Axd 的请求所生成的 javascript 文件里,如果我们从 Temporary Internet Files 里打开它,可以看到这两个函数的实现,细细研究一番,能够发现它还是使用了 XmlHttpRequest 和 IFrame 来实现的。有兴趣的朋友们,去研究吧。

posted @ 2008-10-04 14:13 nacarat 阅读(65) | 评论 (1)编辑
ASP.NET(1.0/1.1)给我们提供了一个开发WebControl的编程模型,于是我们摆脱了asp里面的include模式的复用方式。不过1.0/1.1提供的Web控件开发模型对于处理没有image、css等外部资源的组件还算比较得心应手,script虽然很多时候也是外部资源,但在开发控件的时候我们习惯把script使用Page.Register...Script()来嵌入模块,因为紧凑的东西更便于我们复用,用一个dll就可以解决问题又何必要节外生枝呢。

     ASP.NET 2.0提供的Web Resources管理模型,很好的解决了image、css、script等外部资源的管理问题。现在只需要在solution explorer把资源文件的build action属性设为Embedded Resource。然后在assemblyinfo.cs里添加一句:
[assembly: WebResource("WebCtrl.cutecat.jpg""image/jpg")]
    我们可以看msdn里有WebResource的参数说明:第一个是资源的名字,第二个是资源的mime-type名。
    其实这个语句放任何cs文件里,保证放在最高级namespace外就行。

    然后在程序中调用如下:
m_Image.ImageUrl = this.Page.GetWebResourceUrl(typeof(WebCustom), "WebCtrl.cutecat.jpg");
    GetWebResourceUrl的第一个参数是用户定义的类型(这个是用来确定assembly用的),第二个参数是资源名。

    上面的语句返回给browser的代码是:
<img src="WebResource.axd?a=pWebCtrl&amp;r=WebCtrl.cutecat.jpg&amp;t=632390947985312500" style="border-width:0px;" />
    其中的src就是GetWebesourceUrl执行后返回的,它有3个参数(这里的&被解析成了&amp;,不过IIS也认的),第一个参数a是就是通过typeof(WebCustom)来确定的assembly的名字,第二个参数r很明显就是资源的名字了,第三个参数t是一个a所指的assembly的timestamp。这个t是为了让资源的引用能享用browser缓存的优化,因为IE对相同的url有自己的cache机制。又因为这个r同时又是用户assembly文件的timestamp,如果用户更新了代码,重新编译后t也会变化,这样也就保证了browser能获得最新的资源更新。如果我们能确定嵌入资源是确实不用再更新的,我们可以在typeof()里写一个bcl里的类型,比如typeof(string),那么他将只在freamwork升级后才会变动这个t。

    当然这个WebResource.axd是不存在的,它只是IIS中的一个ISAPI影射。

    使用示例代码如下:
#region WebResource Demo

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: WebResource(
"WebCtrl.cutecat.jpg""image/jpg")]

namespace WebCtrl
{
    [DefaultProperty(
"Text")]
    [ToolboxData(
"<{0}:WebCustom runat=server></{0}:WebCustom>")]
    
public class WebCustom : WebControl
    
{
        
private string text;
        
private Image m_Image;

        [Bindable(
true)]
        [Category(
"Appearance")]
        [DefaultValue(
"")]
        
public string Text
        
{
            
get return text; }
            
set { text = value; }
        }


        
protected override void CreateChildControls()
        
{
            m_Image 
= new Image();
            
this.Controls.Add(m_Image);
        }


        
protected override void Render(HtmlTextWriter output)
        
{
            m_Image.ImageUrl 
= this.Page.GetWebResourceUrl(typeof(WebCustom), "WebCtrl.cutecat.jpg");
            
this.RenderChildren(output);
        }

    }

}

#endregion
posted @ 2008-10-04 14:13 nacarat 阅读(44) | 评论 (0)编辑
     摘要: 让UpdatePanel支持文件上传(1):开始   UpdatePanel从一开始就无法支持AJAX的文件上传方式。Eilon Lipton写了一篇文章解释了这个问题的原因。文章中提供了两个绕开此问题的方法: 将“上传”按钮设为一个传统的PostBack控件而不是异步PostBack。您可以使用多种方法来这么做:例如将一个按钮放置在UpdatePanel外,将按钮设为某个... 阅读全文
posted @ 2008-10-01 12:34 nacarat 阅读(165) | 评论 (1)编辑

与我联系

搜索

 

常用链接

留言簿

我的标签

随笔分类

随笔档案

文章分类

收藏夹

友情博客

积分与排名

  • 积分 - 14488
  • 排名 - 3609

最新评论

阅读排行榜

评论排行榜