ASP.net难点解析

认识Asp.net 中相对路径与绝对路径

分类: 技术文档2010-01-1217:051490人阅读评论(1)收藏举报

好多人对相对路径与绝对路径老是混淆记不清楚,我从整理了一下,希望对大家的认识有帮助。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1.Request.ApplicationPath->当前应用的目录
Jsp中, ApplicationPath指的是当前的application(应用程序)的目录,ASP.NET中也是这个意思。
对应的--例如我的服务器上有两个web应用域名都是mockte.com 一个映射到目录mockte.com/1/ 另一个影射到 http://mockte.com/2/
那么mockte.com/1/就是第一个应用的ApplicationPath 同理 mockte.com/2/就是第二个应用的ApplicationPath

2.Request.FilePath->对应于iis的虚拟目录
如 URL http://mockte.com/1/index.html/pathinfo
FilePath = /1/index.html

3.Request.Path->当前请求的虚拟路径
Path 是 FilePath 和 PathInfo 尾部的串联。例如 URL http://mockte.com/1/index.html/pathinfo
那么Path = /1/index.html/pathinfo

4.Request.MapPath(stringurl)->将url映射为iis上的虚拟目录
这个目录都是相对于application的根目录的
于Server.MapPath相比,不会包含类似c:/这样的路径
可以理解为是相对路径(对比的Server.MapPath就是绝对路径)

5.Server.MapPath(stringurl)->将url映射为服务器上的物理路径
例如 http://mockte.com/1/index.html 假设你的应用程序在c:/iis/MySite中
那么就是 c:/iis/MySite/1/index.html

//本地路径转换成URL相对路径
private string urlconvertor(string imagesurl1)
{
string tmpRootDir =Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录
string imagesurl2 =imagesurl1.Replace(tmpRootDir, ""); //转换成相对路径
imagesurl2 =imagesurl2.Replace(@"/", @"/");
//imagesurl2 =imagesurl2.Replace(@"Aspx_Uc/", @"");
return imagesurl2;
}
//相对路径转换成服务器本地物理路径
private stringurlconvertorlocal(string imagesurl1)
{
string tmpRootDir =Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录
string imagesurl2 =tmpRootDir + imagesurl1.Replace(@"/", @"/"); //转换成绝对路径
return imagesurl2;
}

 

1.使用filePath="/Logs/abc.txt",被认为是根目录,即网页文件所在的盘符,默认的是C盘,则在这里这个路径被解释为"C:/Logs/abc.txt"

2.使用filePath="~/Logs/abc.txt",被认为是服务器的目录

3.使用filePath="./Logs/abc.txt",仍然是服务器目录下

 

 

〈%# 〉与〈%=〉的区别,显示数据与绑定数据

分类: 技术文档2010-01-1118:29368人阅读评论(0)收藏举报

有很长时间没来 CSDN 的博客了。今天在社区里看到一个网友提问关于 asp.net 中“<%# %>” 的问题,所以还是想把这篇文章发到自己的博客上。虽然不是非常很高深的问题,但是还是应该多加留意……


aspx页面中,<%= %> 与 <%# %> 的区别

关于这个问题,在多数的 ASP.NET 的教材中,都提到了一些。<%= %>与<%# %>的区别在于:绑定时机不同,<%# %>是在控件调用DataBind函数的时候才被确定。对于<%= %>,我想你应该不会陌生,在ASP时代,它就相当于 Response.Write。在ASP.NET时代也一样。暂时先不去理会教材中说的,也先把“绑定时机”放到一边。<%= %>与<%# %>的区别是:前者是输出,而后者是赋值!即:

<%="A" %> 相当于:Response.Write("A");

<%#"A" %> 相当于:变量="A";


先来看一个例子:


<html>

<body>

<asp:Button Text=<%# "Hello, the Internet!" %> RunAt="Server" ID="testButton"/>

</body>

</html>



这句话相当于赋值,把上面这个勾黑句子翻译成后台代码就是:testButton.Text="Hello,the Internet!";

第二个例子:

<html>

<body>

<%="Hello, the Internet!" %>

<%#"Hello, the Internet!" %>

</body>

</html>

<%="Hello, the Internet!" %> 就相当于:Response.Write("Hello,the Internet!");

那么第二个<%# %>怎么解释呢?如果按照我“赋值”的说法,它把值赋给谁了呢?

其实翻译成后台代码是这样的:(newSystem.Web.UI.LiteralControl()).Text="Hello, the Internet!";


一段文本,虽然它不被包含在任何开始结束标签之间,但是[font='Courier]ASP.NET[/font]也认为它是一个控件。一个[font='Courier]LiteralControl[/font]控件。所以,[font='Courier]<%# %>[/font]就是把值赋给[font='Courier]LiteralControl[/font]控件的Text属性。

我做过一个生成静态 HTML 代码的类,使用的手法是包装了 HtmlTextWriter这个类。并且我做了跟踪调试。跟踪的结果令我感到很意外。ASP.NET 会把所有的未标有“runat=server”属性的标记,统统看作是一个LiteralControl 控件。例如在上面那些 HTML 代码里,例如在文章开始处的那些 HTML 代码里,ASP.NET会认为是有三个服务器控件,分别是:LiteralControl、Button、LiteralCtontrol。第一个LiteralControl 的 Text 值为“<html><body>Hello,theInternet!”,而最后一个 LiteralControl 的 Text值是“</body></html>”。也就是说,<%= %> 应早于 <%#%>,先被“翻译”出来……

----------------------à>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

在.aspx的文件中经常会碰到如下的代码,如:

1、<%=%> 里面放的变量名,如:

<div>
<h1>Hello World</h1>
<p>Welcome to Beginning ASP.NET 3.5 on <%=
DateTime.Now.ToString() %>
</p>
</div>
输出结果为:

HelloWorld

Welcome to BeginningASP.NET 3.5 on 2009-11-10 15:53:08

2、 <%#%> 这里是数据的绑定

:<%# DataBinder.(Container.DataItem,"ClassName") %>

完整代码:<asp:DataList ID="ClassList" runat="server">
<ItemTemplate> <%# DataBinder.(Container.DataItem,"ClassName") %>
</ItemTemplate>
</asp:DataList></td>

3、<%@ %> 表示:引用

如在很多.aspx页面中,都可以看到如下的代码:

<%@ PageLanguage="C#" CodeFile="Default.aspx.cs"Inherits="_Default" %>

4、<%%>中间一般放函数或者方法,典型的asp程序写法。

例如:<trbgcolor="#ffffff">
<td height="20">
<div align="center">类别:</div>
</td>
<td height="9">&nbsp;
<%ST_getList();%>
</td>
</tr>

-----------------------------------------------------------__________________________________________________________________________________________________________________________

MVCModel数据验证

MVC Model数据验证已经实现了前后台统一验证,那为什么我又要重新实现一个呢,因为我懒,不想去写一个个Model,总结不方便的地方如下:

1. 一个form页面要写一个model,不能重用.

2. 验证和提示信息都写在特性上,书写麻烦,修改一个信息也要重新编译,当然你可以读取xml,但还是麻烦,当提示信息写在xml里,修改时要找,检查时不直观,多加一个验证还是要编译

关于Model验证可以参考: Asp.net MVC2学习笔记8-数据验证(前后台统一验证)

我想要的验证

微软的Model 验证需要在html页面写:

@Html.ValidationMessage("UserName")

也就是程序要对 那一个控件进行验证,既然写都写了,为什么不把所有验证信息都写在这呢,由此就产生了这篇文章的想法,我希望在页面这样写:

@VD1.Bind("UserName").NotEmpty("用户名不能为空"). MinLength(5).ToString()

这句的意思是:对UserName验证,不能为空,最小长度5.这样每个页面管好自己就行.优点如下:

1.不用多余的后台代码,有代码提示,点点就搞定.

2.html里的提示和记在xml效果一样,而且检看时直观.

3.很多时候一个重要的项目,你不敢更新整个项目,但更新一个页面,大家都轻松,反正这个我感受比较深.

4.提示信息可以不写,有默认的.

5.自己生成js可控性强,比如你想改成对话框显示信息,或者右下角提示,写几个重载都可以轻松搞定.

围绕着这个想法,就有了此类的实现,部分代码如下:

1. 验证项的接口

public interface IUniValidate

{

#region 验证接口

/// <summary>最后必需调用</summary>

MvcHtmlStringToString();

/// <summary>不能为空</summary>

IUniValidateNotEmpty(string message = "不能为空");

2. 验证项

public class UniValidate: IUniValidate

{

/// <summary>不能为空</summary>

public IUniValidate NotEmpty(stringmessage)

{

if(isNew)

{

AddJs("required","true", message);

ValidE += (HttpRequestBase request) =>

{

if(request[_inputName] == null || request[_inputName].Length == 0)AddErrStr(message);

returnchecked1;

};

}

returnthis;

}

之所以可以实现前后台统一验证,原理就在这,增加前台的js和后台验证所需的匿名方法,然后返回自己

3.验证Helper

public class UniValidateHelper

{

private static Dictionary<string, Dictionary<string, UniValidate>> all_valids = new Dictionary<string, Dictionary<string, UniValidate>>();

private static Dictionary<string, string> all_Js = new Dictionary<string, string>();

public bool CheckAll(Controllercontr)

{

boolres = valids.Count > 0;

foreach(varitem invalids)

{

lock(item.Value)

{

item.Value.checked1 = true;

item.Value.errStr = "";

if(item.Value.ValidE != null) res = item.Value.ValidE(contr.Request)&& res;

ErrStr += item.Value.errStr;

}

}

contr.ViewData["ErrStr"] = ErrStr;//asp.net下没有contr.ViewBag

returnres;

}

缓存验证项,验证相关的一此方法

调用及注意事项

1. html页面js引用,母板里引用即可

<script src="http://www.cnblogs.com/Scripts/jquery-1.4.4.js"type="text/javascript"></script>

<script src="http://www.cnblogs.com/Scripts/jquery.validate.js"type="text/javascript"></script>

<script src="http://www.cnblogs.com/Scripts/jquery.validate.messages_cn.js"type="text/javascript"></script>

<script src="http://www.cnblogs.com/Scripts/jquery.validate.extension.js"type="text/javascript"></script>

2. 新建验证对象

UniValidateHelper VD1 = new UniValidateHelper("Valid/Index", Request["refresh"] != null);

或者

UniValidateHelper VD1 = new UniValidateHelper(ViewContext.RouteData,Request["refresh"] != null);

3. 控件验证如

@VD1.Bind("UserName").NotEmpty("用户名不能为空").MinLength(5).ToString()

4. 服务端错误信息,母板里写一次就可,也可以不显示,因为只有很少的情况会绕过端验证,比如js实效,人为攻击等

@ViewData["ErrStr"]

5. 客户js输出,母板里写一次就可

@VD1.ValidEnd()

6. 服务端验证

UniValidateHelper vd = new UniValidateHelper(this.RouteData);

bool rs= vd.CheckAll(this);

最后

具体看源码,类非常简单,写的时候就以简单实用为原则,生成的js验证用的是jquery.validate插件,个人感觉还是非常强大的,当然你也可以自己修改使用其他的验证库,类还有很多不足,您有什么建议请留在回复里,你的参与也许会使这个类 更加完善及强大,虽然感觉已经很强大了,开个玩笑.

代码的风格可能不合你意,但请不要骂娘,你可以自己改进,至少比重新写省事

比如这样的注释/// <summary>不能为空</summary> 为了减少行数,为了折叠后还可以看的到

项目环境:vs2010,mvc3.0

    [源码下载]

支持的所有验证如下

ViewCode

public interfaceIUniValidate
    {
        /// <summary>最后必需调用</summary>
        MvcHtmlStringToString();
        /// <summary>不能为空</summary>
        IUniValidateNotEmpty(string message = "不能为空");
        /// <summary>是否为Email格式</summary>
        IUniValidateEmailAddress(string message = "必需为Email格式");
        /// <summary>正则验证</summary>
        IUniValidate Regex(stringregex, string message = "不正确");
        /// <summary>中文</summary>
        IUniValidateAllChinese(string message = "必需为中文");
        /// <summary>与另一个控件值是否相等</summary>
        IUniValidateEqualTo(string equalElement, stringmessage = "不相同");
        /// <summary>不能与另一个控件相等</summary>
        IUniValidateNotEqualTo(string equalElement, stringmessage = "不能相同");
        /// <summary>不能小于最小值</summary>
        IUniValidate Min(int num, stringmessage = "数字太小");
        /// <summary>不能大于最大值</summary>
        IUniValidate Max(int num, stringmessage = "数字太大");
        /// <summary>长度不能小于</summary>
        IUniValidateMinLength(int num, string message = "长度太短");
        /// <summary>长度不能大于</summary>
        IUniValidateMaxLength(int num, string message = "长度太长");
        /// <summary>验证长度在指定的区间内</summary>
        IUniValidate Length(int min, int max, stringmessage = "长度不正确");
        /// <summary>身份证号码验证</summary>
        IUniValidateIsIDCardNo(string message = "不是有效的身份证");
        /// <summary>远程验证 使用post方式 根据远程返回的Boolen值进行验证 true:表示可以提交,不显示错误提示false:表示不可以提交,显示错误提示</summary>
        IUniValidate Ajax(string url, stringmessage);
        /// <summary>日期验证</summary>
        IUniValidate Date(stringmessage = "日期不正确");
        /// <summary>网址验证</summary>
        IUniValidate Url(stringmessage = "网址不正确");
        /// <summary>Decimal型数字验证</summary>
        IUniValidateDecimal(string message = "不是有效的数字");
        /// <summary>检测是否为IP地址</summary>
        IUniValidate IsIP(stringmessage = "IP不正确");
        /// <summary>不包含Html代码</summary>
        IUniValidate NoHtml(stringmessage = "不能包含标示符");
        /// <summary>不能包含中文或全角字符验证</summary>
        IUniValidateNoChinese(string message = "不能是中文");
        /// <summary>判断是否是标准字符 如果包含非标准字符 报错</summary>
        IUniValidateIsLegalXmlString(string message = "xml格式错误");
        /// <summary>非 正则表达式,即不匹配此正则</summary>
        IUniValidateNotRegex(string regex, string message);
        /// <summary>Char最大长度</summary>
        IUniValidateCharCodeLength(int num, string message = "长度不正确");

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ASP.NET前台代码绑定后台变量方法总结

经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题。一般有<%= str%>和<%# str %>两种方式,这里简单总结一下。如有错误或异议之处,敬请各位指教。

一方面,这里所讲的前台即通常的.aspx文件,后台指的是与aspx相关联的CodeBehind,文件后缀名为.aspx.cs;另一方面,这里的绑定是指用户发出访问某一页面指令后,服务器端在执行过程中就已经将前台代码进行了赋值,而后生成html格式回传客户端显示,而并非已经显示到客户端后,然后通过其他方法(如ajax)去服务器端获取相应变量。

备注:上面说的两个文件是常见的代码隐藏(code-behind)模式,还有一种是代码嵌入(code-beside, inline)模式,那就是只存在aspx一个文件,而后台代码则写入此文件的<scripttype="text/javascript" runat="server"></script>之中(还有一些语法上区别),这对于本文讨论的问题略有影响,因为代码嵌入是声明性代码与C#/VB.NET代码都一起编译到一个类里面,而代码隐藏则将声明性代码与C#/VB.NET代码分开几次进行翻译/编译,因此前者是局部与局部(partial)的关系后者基类与派生类的关系,但这仅仅影响所能绑定变量的范围(与修饰符有关),下面会提到。以下均以代码隐藏模式为例。

一般来说,在前台代码的三种位置可能会用到(绑定)后台变量:

·        服务器端控件属性或HTML标签属性

·        JavaScript代码中

·        Html显示内容的位置(也就是开始标签与结束标签之间的内容,如<div>这里</div>(Html标签)或者<asp:LabelID="Label2" runat="server" Text="Label">这里</asp:Label>(服务器端控件),它作为占位符把变量显示于符号出现的位置)

对于第一种位置,有一些约束条件:

(1)一般的属性要求是字符串型或数值型(下面会提到有些服务器端属性支持属性为数据集合);

(2)并不是所有的属性都可以绑定变量,有些属性例如runat属性必须是"server"常量,即使绑定的字符串是server,也会导致分析器分析时出错;

(3)有一种属性,他要求属性值有约束(类型约束,比如服务器端控件要求TabIndex属性是short类型,或者字符串内容有约束),也应该在绑定时满足,否则依然可能编译时报错;

(4)还一种属性,虽然属性本身有约束,但即使绑定的变量不满足约束,也可以编译通过,比如input的checked属性,它只有checked字符串是合法的,但如果通过绑定获取到的字符串不是checked,那么这些属性将有自己内部处理机制,来保证可以正常使用;

(5)还要注意,即使对于同一类属性,服务器端和HTML的属性的处理机制也不同,同样是TabIndex(tabIndex),前者如果不满足,则分析器错误,后者则忽略这一问题。

对于第二种位置,一般只要绑定的后台变量和JavaScript中数据类型兼容即可。

对于第三种位置,如果绑定出现的位置不在服务器端控件内部,则没有约束条件,只要是常量字符串可以出现的位置,均可以绑定。但是对于置于服务器端控件内部,也就是上面那种<asp:LabelID="Label2" runat="server" Text="Label">这里</asp:Label>的方式,则有约束条件。通过总结,归纳为四类服务器端控件,如果绑定的代码出现在这些控件的开始和结束标签之间(这里所说的控件,是指如果绑定代码外有多层的嵌套控件包围,则是指包围绑定代码的最内层控件),有不同的显示结果:

(1)约束型控件:这类控件要求它的开始标签和结束标签中只能包含指定的子控件,因此如果在这里出现代码块,将编译错误。例如:

<asp:DataListrunat="server"></asp:DataList>,在它之间,要求必须嵌套<ItemTemplate></ItemTemplate>。

(2)非嵌套类控件:这类控件,不允许在内部嵌套其他控件或标签,只能是常量字符串,它会将开始标签和结束标签中常量字符串内容作为他的属性。例如上面提到的TextBox,它会将标签间内容作为它的Text属性值。

(3)嵌套类控件:这类控件,可以嵌套其他任意控件,也可以包含字符串,因此可以正常显示绑定代码块所表示的字符串内容。例如Label控件、Panel等。

(4)数据绑定类控件:这类控件是ASP.NET提供的服务器端控件,除了可以绑定普通的变量类型,也可以绑定一个数据集合(只能采取下面的第二种方式实现)。

关于是否加引号:在以上三个位置使用时,是否应该将<%= str%>或<%# str %>置于单引号或双引号中呢?对于在不同位置,处理的方式是不同的:(具体请在下面两种方式的具体介绍时,加以体会)

(1)对于第一种位置,由于JavaScript是弱类型的,如果绑定时加引号,显然就认为就当做字符串来处理,这始终是正确的;如果绑定时不加引号,它将认为这是个数值型的,那么如果获取的真是数值,当然可以,如果是非数值型,则将产生脚本错误,这即使对于JavaScript赋值常量时,也是同样的:

        var test1 = 123b;//运行时报错
        var test2=123;//正确,是数值型
        var test3="123b";//正确,字符串型

(2)对于第二种位置,经过测试,无论是对于服务器端控件属性还是HTML标签属性,加引号总是正确的;如果不加引号,则两种属性的处理方式不同:

·        对于服务器端控件属性,如果绑定的代码块不加引号,则编译时会提示“验证(ASP.NET):特性值前后必须加引号”的警告信息,但是生成为HTML后,对应生成的HTML属性已经被加上引号并获取了正确的绑定结果,因此加不加引号不会影响使用,但是建议对于规范的代码,还是加上为好;

·        对于HTML标签属性,如果不加引号,则编译时会提示“验证(XHTML 1.0 Transitional): 特性值前后必须加引号”的警告信息,并且生成为HTML属性也确实没有加上引号,那么虽然属性后面确实是没有加上引号的正确的绑定值,但是不一定能展示出想要看到的结果。比如对于input标签的value属性,如果绑定的字符串是" hello world fromvariable”,则在客户端的input显示出的内容实际上只是"hello”字符串,生效的属性值是一个被截断的字符串,它从属性后的一串字符串(若未加引号)的第一个非空字符开始,截止到下一个空字符的前一个字符为止(比如对于" hello world”,结果将是"hello”),因此,加上引号是必须的。

(3)对于第三种位置,加与不加引号,获取的值及其显示均不受影响。

因此建议,所有绑定表达式都加上引号,作为字符串获取,然后根据实际需求,用相应函数进行转换,得到所需要的类型。

另外,这里所说的后台变量是泛指的,包括如下:

·        成员变量

·        方法或属性的返回值

·        表达式,也就是所有后台能够执行的代码,运行后所得到的值(也就是直接将后台代码写在前台代码中,记得使用完全限定名或在后台中using相关namespace)

·         数据集合

后台变量有一些约束条件,需要满足:

(1)变量修饰符要求。变量是静态或者实例字段均可。对于代码隐藏模式的ASP.NET,以上的所述的变量必须为public或protected类型(因为是基类与派生类的关系),private或者internal都不行,而代码嵌入模式则任何修饰符的变量均可访问(一个类内部的关系)。

(2)变量类型要求。由于前台属性一般是字符串类型,而JavaScript基本类型也就是字符串型、数字型、布尔型,因此对应的变量应该也是这几种方式,其余类型如果不被支持(如复杂类型、数组、引用类型等),前台获取的就是调用了变量的ToString()方法所得到的字符串。因此,在绑定时,要根据情况看是否能进行隐式类型转换,必要时还要用相关函数来强制转换,以保证前台可以获得正确的值。当然,对于数据绑定类控件,它的有些属性可以为数据集合,但这时的绑定只能通过下面第二种方式才被支持。

以上是一些概念和基本约束,这些都是两种方式都应该满足的,下面具体介绍两种方式,来实现前台代码中(以下称为代码块)绑定后台变量的功能。

一. <%= str%>

此种方式其实是ASP 时代就支持的,ASP 通过包含在 < % 和 %>中的表达式将执行结果输出到客户浏览器 , 如:< % =test %>就是将变量test的值发送到客户浏览器中。在ASP.NET中,这个表达式依然可以使用,并可以出现在前台代码的上述三个位置,但是要注意,除了上述的一般性约束外,对于控件属性,还必须是绑定到服务器端控件的属性。另外,它只能绑定上面讲的前三种变量类型,不支持绑定数据集合。例子如下:

后台代码

public partial class WebForm2 : System.Web.UI.Page
   {
  
       public string GetVariableStr;//注意变量的修饰符
       protected void Page_Load(object sender, EventArgs e)
       {
  
           if (!IsPostBack)
           {
  
               GetVariableStr = "hello world from variable";
           }
       }
       protected string GetFunctionStr()//注意返回值的修饰符
       {
  
           return "hello world from Function";
       }
   }

前台代码

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        function fun() {
  
 
            var str = '<%= DateTime.Now %>';
            //前台位置1,绑定的是第三种变量类型(也是第二种方式,?因为Now是个属性)
            alert(str);
        }
    </script>
</head>
<body οnlοad="fun()">
    <form id="form1" runat="server">   
        <div>
             <input type="text" value="<%= GetVariableStr %>" />
                                                  <%--前台位置2,绑定的是成员变量--%>
             "<%= GetFunctionStr() %>"
                                                  <%--前台位置3,绑定的是一个方法的返回值>--%>
        </div>
    </form>
</body>
</html>

一些错误的使用:

之所以说第一种绑定方式要用于非服务器端控件的属性,是因为如果应用于这些服务器端属性时,这些代码实际上不被解析。 比如:

 <asp:Label ID="Label1" runat="server" Text="<%= GetVariableStr %>"></asp:Label>
 <asp:TextBox ID="TextBox1" runat="server" Text="<%= GetVariableStr %>"></asp:TextBox>

则显示出来的Label1的文本是空,而TextBox中文本是"<%= GetVariableStr %>”,所以记住,对服务器端控件的属性加这样的代码块,将不被解析,而是将这一字符串直接作为属性值了,所以不是想要的结果。如果引号也不加上,将会编译错误,提示“服务器标记不能包含 <% ... %> 构造。”。

这里结合开篇提到的关于将绑定代码快置于“Html显示内容的位置”时,如果在服务器端控件内,那四类控件如何显示的问题。如下:

  <asp:Label ID="Label1" runat="server" >"<%= GetVariableStr %>"</asp:Label>
  <asp:TextBox ID="TextBox1" runat="server" >"<%= GetVariableStr %>"</asp:TextBox>

其中,Label1属于嵌套类控件,Label1确实显示了正确的结果,TextBox属于非嵌套类控件,TextBox如果用这种方式,将会产生编译错误,提示“此上下文中不支持代码块。”

二. <%# str %>

ASP.NET 引入了一种新的声明语法 <%# %>。该语法是在 .aspx 页中使用数据绑定的基础,所有数据绑定表达式都必须包含在这些字符中。这里从用法和适用范围等方面与第一种绑定方式进行区分。

从出现的位置来看,除了能出现在第一种代码块出现的所有位置外,他还可以出现在服务器端控件的属性中。

从绑定的变量类型上看,他还可以配合ASP.NET的数据绑定类控件,来绑定上述的第四种“变量”类型,就是数据集合(DropDownList,DataList,DataGrid,ListBox这些是数据绑定类控件,数据集合包括ArrayList(数组),Hashtable(哈稀表,DataView(数据视图),DataReader等)。

用法上看,在前台代码中除了在相应位置写上<%# %>外,在后台代码中,还需要使用DataBind()方法。以下是实例:

前台代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        function fun() {
  
 
            var str = '<%# DateTime.Now %>';
 
            alert(str);
        }
    </script>
</head>
<body οnlοad="fun()">
    <form id="form1" runat="server">
    <div>
        <input type="text" value="<%# GetVariableStr %>" /><br />
        "<%# GetVariableStr %>"
        <asp:Label ID="Label1" runat="server" Text="<%# GetVariableStr %>"></asp:Label>
            <%--此种方式可以绑定服务器端控件的属性--%>
        <asp:DropDownList ID="DropDownList1" runat="server" DataSource='<%# arraylist %>'>
            <%-- 将集合绑定到数据绑定类控件,通过DataSource属性来实现,从而在下拉框看到集合中的内容--%>
        </asp:DropDownList>
        <asp:DataList ID="DataList1" runat="server" DataSource='<%# dt %>'>
            <%--  同上,绑定了DataTable数据集合?--%>
            <ItemTemplate>
                <table border="1" cellpadding="0" cellspacing="0">
                    <tr>
                      <td>
                       <asp:Label ID="Label2" runat="server" Text='<%# Bind("row0")%>'></asp:Label>
                       <%--由于绑定的数据集合具有多列,并且此数据绑定类控件支持模板,
                           因此需要在模板中指定需要绑定的列以及格式--%>
                      </td>
                      <td>
                       <%# Eval("row1")%>
                      </td>
                    </tr>
                </table>
            </ItemTemplate>
        </asp:DataList>
    </div>
    </form>
</body>
</html>

可以看出,这种方式在使用时,不但可以实现(取代)<%=... %>所满足的功能,还可以绑定服务器控件属性(如上面的Label1),也可以将集合类型绑定到支持的数据绑定类控件。在用法上,前台代码除了对数据绑定类控件绑定数据集合外有所差别,其他的使用上与第一种没区别。在绑定类控件的模板中,如何使用Eval、Bind、DataBinder.Eval等,不在此文讨论中,可以参考下面链接的参考文章。

后台代码

public partial class WebForm2 : System.Web.UI.Page
{
  
    public string GetVariableStr;
    public ArrayList arraylist;
    public DataTable dt;
    protected void Page_Load(object sender, EventArgs e)
    {
  
        if (!IsPostBack)
        {
  
            GetVariableStr = "hello world from variable";
 
            arraylist = new ArrayList();
            arraylist.Add("选?项?1");
            arraylist.Add("选?项?2");
 
            dt = new DataTable();
            dt.Columns.Add("row0");
            dt.Columns.Add("row1");
            DataRow dr1 = dt.NewRow();
            dr1[0] = "1.1";
            dr1[1] = "1.2";
            DataRow dr2 = dt.NewRow();
            dr2[0] = "2.1";
            dr2[1] = "2.2";
            dt.Rows.Add(dr1);
            dt.Rows.Add(dr2);
 
            Page.DataBind();
            //DropDownList1.DataBind();
            //DataList1.DataBind();
        }
    }
}

在后台代码中,与第一种方式唯一不同的,就是需要调用DataBind方法。只有执行了相应控件的DataBind方法,前台代码中这些控件中使用<%# %>的绑定才会发生(并且控件内部的所有绑定也会发生,比如又嵌套了一个绑定后台数据的控件),否则得话将不会被赋值,而是默认空值。上面我们用的是Page的DataBind方法,那么整个页面所有绑定都会执行。当然,如果我们只执行DataList1或者DropDownList1的DataBind方法,那么只有相应控件的绑定才会发生。需要注意的是,这里说的需要执行DataBind包括了显示和隐式执行,有些数据绑定类控件,当它们通过 DataSourceID 属性绑定到数据源控件时,会通过隐式调用 DataBind 方法来执行绑定。这时就不必显示的再次调用了。

两者区别:

两种绑定方式上,他们的约束基本相同,都要求与属性匹配,出现在他们可以出现的位置。后者的使用位置更广泛,尤其是支持服务器端控件和绑定数据集合。后台代码方面,后者需要调用DataBind才能完成绑定,前者则没有这方面要求。这里主要区别一下两者在执行机制上的区别:<%=...%>是在程序执行时调用(应该是在页面的RenderControl事件过程中完成的,也就是通常情况下我们可以看到的后台代码都执行完毕后再去到前台代码中进行赋值绑定),而<%#... %>是在DataBind()方法之后被调用,一旦调用了DataBind(),则它对应的控件将绑定变量,因此,请注意:如果在DataBind()后再修改变量,那么绑定的就不是最新值了,这就需要在完成变量的赋值后,再去DataBind()。其实这两种方式,它的运行过程可以在VS中通过设置断点来看看,看两者的绑定赋值分别是在什么时候发生的。

尚存的疑问:

1.不知道为什么不能获取到internal修饰的变量?

答:此问题已经在下一篇文章《ASP.NET前台无法访问后台internal类型变量的问题》中分析并解决。(2010-10-25日更新)

补充1:回答关于9楼的提到的ASP.NET 4.0中的<%: xxxx%>(2010-11-4)

答:这种方式是ASP.NET4.0中新加入的绑定方式,常用于MVC中,但普通webform中也可使用。他的功能其实就是对绑定的值进行一下编码,因此,一下两者是等同的:

 <%= Server.HtmlEncode("<b>test</b>") %>
 <%: "<b>test</b>" %>;

补充2:关于各种百分号的功能区分(2010-11-4)

答:本文上面讲了两种百分号的用法,在加上补充1中的,一共讲了三种,其实还有一种百分号用法就是<% func(xx)%>,也就是百分号后不带任何符号,然后执行一段代码,一句话概括:

在百分号內 , 如果百分号后面不带任何符号(冒号、等号、井号) , 即表示要执行一段代码而已,此处不包含任何输出信息;若带符号,即表示执行此处的代码,并且将执行后返回的值绑定(或者显示)在此处。

参考文章:

--------------------------------------------------------------------------______________________________________________________________________________________________________________-

Cookie的深入理解

Cookie虽然是个很简单的东西,但它又是WEB开发中一个很重要的客户端数据来源,而且它可以实现扩展性很好的会话状态,所以我认为每个WEB开发人员都有必要对它有个清晰的认识。本文将对Cookie这个话题做一个全面的描述,也算是我对Cookie的认识总结。

Cookie 概述

Cookie是什么?Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息。

为什么需要Cookie? 因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。所以,需要额外的数据用于维护会话。 Cookie 正是这样的一段随HTTP请求一起被传递的额外数据。

Cookie能做什么?Cookie只是一段文本,所以它只能保存字符串。而且浏览器对它有大小限制以及它会随着每次请求被发送到服务器,所以应该保证它不要太大。 Cookie的内容也是明文保存的,有些浏览器提供界面修改,所以,不适合保存重要的或者涉及隐私的内容。

Cookie 的限制。 大多数浏览器支持最大为 4096 字节的 Cookie。由于这限制了 Cookie 的大小,最好用 Cookie 来存储少量数据,或者存储用户 ID 之类的标识符。用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息。浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的Cookie 总数作出绝对限制,通常为 300 个。

通过前面的内容,我们了解到Cookie是用于维持服务端会话状态的,通常由服务端写入,在后续请求中,供服务端读取。下面本文将按这个过程看看Cookie是如何从服务端写入,最后如何传到服务端以及如何读取的。

Cookie的写、读过程

在Asp.net中,读写Cookie是通过使用HttpCookie类来完成的,它的定义如下:

public sealed class HttpCookie

{

    // 获取或设置将此 Cookie 与其关联的域。默认值为当前域。

    publicstring Domain { get; set; }

    // 获取或设置此 Cookie 的过期日期和时间(在客户端)。

    publicDateTime Expires { get; set; }

    // 获取一个值,通过该值指示 Cookie 是否具有子键。

    publicbool HasKeys { get; }

    // 获取或设置一个值,该值指定 Cookie 是否可通过客户端脚本访问。

    // 如果 Cookie 具有 HttpOnly 属性且不能通过客户端脚本访问,则为 true;否则为 false。默认为false。

    public bool HttpOnly { get; set; }

    // 获取或设置 Cookie 的名称。

    publicstring Name { get; se

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值