针对有网友说看不见文章内容, 现提示如下: 点击每一个标题行任一地方都会展开和隐藏此文章内容(不要点击标题). 目前展开隐藏功能只支持IE浏览器,虽然可以改成支持FF浏览器,不过现在一直没时间去弄,等有时间再修改了。 |
blog名称:乱闪Blog 日志总数:267 评论数量:1618 留言数量:-26 访问次数:2655163 建立时间:2005年1月1日 |
|

| |
ASP.NET 2.0无刷新页面新境界
|
“无刷新页面”,只是一种不确切的效果描述(其实还有其他各种方法来实现这个效果),更确切的说法是:在页面上用JavaScript调用服务器端的一个方法,然后处理返回的数据。实现它最标准的方法当然是XMLHTTP。但是,程序员都是懒惰的家伙,每个人都希望能有更方便的方法,或者,更佳的包装。比如,Lostinet的Rane就是对XMLHTTP的一个很好的包装。
终于,在ASP.NET 2.0里面,我们可以轻松的来做到这点了。服务器端任何实现了System.Web.UI.ICallbackEventHandler接口的控件,都可以通过RaiseCallbackEvent()方法来处理从页面上的JS脚本传递过来的请求和数据,处理后,再将结果传回给页面。这项能力的底层仍然是XMLHTTP。
下面是一个简单的演示:
在页面上,我们放上两个文本框和一个按钮:
<INPUT id="txtMessage">
<INPUT onclick="callToServer();" type="button" value="Call to Server">
Result : <INPUT id="txtResult" >
当点击按钮的时候,将调用JS脚本方法callToServer(),JS脚本如下:
function callToServer()
{
var param = document.getElementById("txtUsername").value;
var context = "";
<% = ClientScript %>
}
function handleResultFromServer(result, context)
{
document.getElementById("txtResult").value = result;
}
handleResultFromServer()方法则负责将从服务器传回的数据写到txtResult这个文本框里面。
再看看服务器端的代码:
public partial class Default_aspx : System.Web.UI.ICallbackEventHandler
{
private String ClientScript
{
get
{
return this.GetCallbackEventReference(this, "param", "handleResultFromServer", "context");
}
}
public string RaiseCallbackEvent(string eventArgument)
{
return "客户端在[" + DateTime.Now.ToString() + "]传送来 [" + eventArgument + "].";
}
}
我们让页面直接实现ICallbackEventHandler接口,然后接口定义的RaiseCallbackEvent()方法中将服务器的时间和传来的数据一起返回回去。
ClientScript属性的作用是,它调用了页面的GetCallbackEventReference()方法,获得了让客户端有能力调用服务器端方法的JS脚本,并输出到页面的callToServer()方法中,这样,点击页面按钮时,就开始执行页面上包含了调用服务器方法的的callToServer()方法。
注意GetCallbackEventReference()方法的参数,在参数中,我们定义了客户端的哪个变量包含了要传递给服务器,服务器方法执行后,调用客户端的哪个方法等信息。GetCallbackEventReference()的详细参看请看这里。
最后,我们这个页面的执行效果就是:
560)this.style.width=560;"> |
|
ASP.NET文件上传程序的源代码
|
本文件用VB.NET编辑,在WIN2000+IIS(安装有.NET支持)中调试通过,可以上传许多常用的文件类型.如 RAR、ZIP、DOC、TXT、JPG、GIF等等! 直接下载保存为ASPX格式就可以 ------------------------------------------------------------ <html> <title>文件上传</title>
<body> <form enctype="multipart/form-data" runat=server> <Input type=file id=fileup runat=server size="20"><p> <asp:button id=upload_button onclick=uploadfile text="上传" runat=server/> </form> <p> <asp:label id=uptype runat=server/> </body> </html> <script language=VB runat=server> Sub uploadfile(sender as object,e as eventargs) If fileup.postedfile.contentlength=0 Then uptype.text="你还没有选择需要上传的文件!" Else Dim filesplit() as string=split(fileup.postedfile.filename,"\") Dim filename as string=filesplit(filesplit.length-1) fileup.postedfile.saveas(server.mappath(".")&"\"&filename) uptype.text="文件名称:"&fileup.postedfile.filename &"<br>"& _ "文件大小:"&fileup.postedfile.contenttype &"<br>"& _ "文件类型:"&fileup.postedfile.contentlength End If End Sub </script> |
|
制作最清晰缩略图的完整类
|
Public Class ClassUpPic Private vPicFile As System.Web.UI.HtmlControls.HtmlInputFile Private vSmallPicSize, vUpFileSize As Integer Private vUpPicPath, vNewPicName, vTmpPicName As String Private PicMin, PicMax, vPicMax As System.Drawing.Image Private PicFormat As System.Drawing.Imaging.ImageFormat Private MinHeight, MinWidth As Decimal Private Myfile As IO.File
Public Sub New(ByVal PicFile As System.Web.UI.HtmlControls.HtmlInputFile, ByVal UpPicType As PicType) vPicFile = PicFile vUpFileSize = HttpContext.Current.Application("UpFileSize") Select Case UpPicType Case PicType.Face vUpPicPath = "upload/images/Face" vSmallPicSize = 150 vNewPicName = HttpContext.Current.Session("MemberID") & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") Case PicType.Photo vUpPicPath = "upload/images/Photo" vSmallPicSize = 150 vNewPicName = System.Guid.NewGuid.ToString() & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") Case PicType.Pic vUpPicPath = "upload/images/Pic" vSmallPicSize = 550 vNewPicName = System.Guid.NewGuid.ToString() & "." & GetRightByChar(vPicFile.PostedFile.FileName, ".") End Select End Sub
Public Function GetSavedFileName() As String ’检验图片类型================================================================= If vPicFile.PostedFile.FileName = "" Then Throw New NotSupportedException("文件为空,请您选择上传的图片文件!") End If If Left(vPicFile.PostedFile.ContentType, 5) <> "image" Then Throw New NotSupportedException("文件格式不合法,请选取有效的图片文件!" & vPicFile.PostedFile.ContentType) End If If vPicFile.PostedFile.ContentLength > vUpFileSize Then Dim MaxNumber As Decimal = vUpFileSize / 1024 / 1024 Throw New NotSupportedException("上传的图片文件太大,最大支持" & Format(MaxNumber, "##,##0") & "M!") End If
’检验数量限制=================================================================
’保存大文件================================================================= vPicFile.PostedFile.SaveAs(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vNewPicName) vPicFile.Dispose()
’缩略图片文件================================================================= PicMax = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vNewPicName) If Not (PicMax.RawFormat Is PicFormat.Gif Or PicMax.RawFormat Is PicFormat.Png) Then If PicMax.Height > vSmallPicSize Or PicMax.Width > vSmallPicSize Then vTmpPicName = System.Guid.NewGuid.ToString() & ".png" vPicMax = PicMax PicMax.Save(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName, PicFormat.Png) vPicMax.Dispose() PicMax = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName) End If End If ’保存小文件================================================================= GetMinPic(PicMax).Save(HttpContext.Current.Server.MapPath(vUpPicPath & "/min/") & vNewPicName, PicFormat.Jpeg) PicMax.Dispose()
’删除临时png文件================================================================= If vTmpPicName <> "" Then Myfile.Delete(HttpContext.Current.Server.MapPath(vUpPicPath & "/max/") & vTmpPicName)
Return vNewPicName End Function
Private Function GetMinPic(ByVal MaxPic As System.Drawing.Image) As System.Drawing.Image If MaxPic.Height > vSmallPicSize Or MaxPic.Width > vSmallPicSize Then If MaxPic.Height > MaxPic.Width Then MinWidth = MaxPic.Width / (MaxPic.Height / vSmallPicSize) MinHeight = vSmallPicSize Else MinWidth = vSmallPicSize MinHeight = MaxPic.Height / (MaxPic.Width / vSmallPicSize) End If Return MaxPic.GetThumbnailImage(CInt(MinWidth), CInt(MinHeight), Nothing, New System.IntPtr()) Else Return MaxPic End If End Function
Enum PicType Face = 1 Photo = 2 Pic = 3 End Enum
Private Function GetRightByChar(ByVal StrValue As String, ByVal CharValue As String) As String Dim MyStr() As String = Split(StrValue, CharValue) Return MyStr(MyStr.Length - 1) End Function End Class |
|
ASP.NET学习手记:验证用户表单输入
|
运行环境:Win2000 Advance Server+IIS5.0+NGWS SDK(80M的). 其中验证email地址的函数用的是廖兄精华区中的代码. <%@ Page Language="C#" %>
<html> <script language="javascript"> function ClientValidateEmail(source, value) { var strr; re=/(\w+@\w+\.\w+)(\.{0,1}\w*)(\.{0,1}\w*)/i; re.exec(value); if (RegExp.$3!=""&&RegExp.$3!="."&&RegExp.$2!=".") strr=RegExp.$1+RegExp.$2+RegExp.$3 else if (RegExp.$2!=""&&RegExp.$2!=".") strr=RegExp.$1+RegExp.$2 else strr=RegExp.$1 if (strr!=value) return false; else return true; } </script> <body>
<h3>ASP.NET验证用户输入</h3>
<form method=post runat=server> <hr width=600 size=1 noshade> <table> <tr> <td> <asp:ValidationSummary ID="valSum" runat="server" HeaderText="你必须输入下面这些表单域:" DisplayMode="bulletlist" Font-Name="宋体" Font-Size="12" /> </td> </tr> </table> <center> <p> <!-- 登陆信息 --> <table border=0 width=600 > <tr><td colspan=3> <table border=0 cellpadding=0 cellspacing=0 width="100%"> <tr><td> <b>登陆信息</b> </td></tr> </table> </td></tr> <tr> <td align=right> Email地址: </td> <td> <asp:TextBox id=email width=200px maxlength=60 runat=server /> </td> <td> <asp:RequiredFieldValidator id="emailReqVal" ControlToValidate="email" ErrorMessage="Email地址" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:CustomValidator id="emailRegexVal" runat="server" ControlToValidate="email" ClientValidationFunction="ClientValidateEmail" Display="Static" Font-Name="宋体" Font-Size="12"> 非法Email地址 </asp:CustomValidator> </td> </tr>
<tr> <td align=right> 密码: </td> <td> <asp:TextBox id=passwd TextMode="Password" maxlength=20 runat=server/> </td> <td> <asp:RequiredFieldValidator id="passwdReqVal" ControlToValidate="passwd" ErrorMessage="用户密码" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="passwdRegexBal" ControlToValidate="passwd" ValidationExpression=".*[!@#$%^&*+;:].*" Display="Static" Font-Name="宋体" Font-Size="12" Width="100%" runat=server> 密码必须包含如下字符: (!@#$%^&*+;:) </asp:RegularExpressionValidator> </td> </tr> <tr> <td align=right> 确认密码 </td> <td> <asp:TextBox id=passwd2 TextMode="Password" maxlength=20 runat=server/> </td> <td> <asp:RequiredFieldValidator id="passwd2ReqVal" ControlToValidate="passwd2" ErrorMessage="确认密码" Display="Dynamic" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> <asp:CompareValidator id="CompareValidator1" ControlToValidate="passwd2" ControlToCompare="passwd" Display="Static" Font-Name="宋体" Font-Size="12" runat=server> 密码不符合 </asp:CompareValidator> </td> </tr> <tr><td colspan=3> </td></tr>
<!-- 私人信息 --> <tr><td colspan=3> <table border=0 cellpadding=0 cellspacing=0 width="100%"> <tr><td> <b>个人信息</b> </td></tr> </table> </td></tr> <tr> <td align=right> 姓名: </td> <td> <asp:TextBox id=pname maxlength=20 width=200px runat=server /> </td> <td> </td> </tr> <tr> <td align=right> 地址: </td> <td> <asp:TextBox id=address width=200px runat=server /> </td> <td> </td> </tr> <tr> <td align=right> 邮编: </td> <td> <ASP:TextBox id=postcode width=60px maxlength=6 runat=server /> </td> <td> <asp:RegularExpressionValidator id="RegularExpressionValidator1" ControlToValidate="postcode" ValidationExpression="^\d{6}$" Display="Static" Font-Name="宋体" Font-Size="12" runat=server> 邮编必须是6位数字 </asp:RegularExpressionValidator> </td> </tr> <tr> <td align=right> 性别: </td> <td> <ASP:RadioButtonList id=sexType runat=server> <asp:ListItem>男</asp:ListItem> <asp:ListItem>女</asp:ListItem> </ASP:RadioButtonList> </td> <td> <asp:RequiredFieldValidator id="sexTypeReqVal" ControlToValidate="sexType" ErrorMessage="性别" Display="Static" InitialValue="" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> </td> </tr> <tr> <td align=right> 出生年份: </td> <td> <ASP:DropDownList id=expYear runat=server> <asp:ListItem></asp:ListItem> <asp:ListItem >1976</asp:ListItem> <asp:ListItem >1975</asp:ListItem> </ASP:DropDownList> </td> <td> <asp:RequiredFieldValidator id="expDateReqVal" ControlToValidate="expYear" ErrorMessage="出生年份" Display="Static" InitialValue="" Font-Name="宋体" Font-Size="12" runat=server> * </asp:RequiredFieldValidator> </td> </tr> </table> <p> <input runat="server" type=submit value="提 交"> <p> </form> </center> </body> </html>
|
|
认识ASP.NET配置文件Web.config
|
一、认识Web.config文件
Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中。当你通过VB.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认的 Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置,你可以在该子目录下新建一个Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息,也可以重写或修改父目录中定义的设置。
在运行时对Web.config文件的修改不需要重启服务就可以生效(注:<processModel> 节例外)。当然Web.config文件是可以扩展的。你可以自定义新配置参数并编写配置节处理程序以对它们进行处理。
二、web.config配置文件(默认的配置设置)以下所有的代码都应该位于
<configuration> <system.web>
和
</system.web> </configuration>
之间,出于学习的目的下面的示例都省略了这段XML标记
1、<authentication> 节
作用:配置 ASP.NET 身份验证支持(为Windows、Forms、PassPort、None四种)。该元素只能在计算机、站点或应用程序级别声明。<authentication> 元素必需与<authorization> 节配合使用。
示例:
以下示例为基于窗体(Forms)的身份验证配置站点,当没有登陆的用户访问需要身份验证的网页,网页自动跳转到登陆网页。
<authentication mode="Forms" > <forms loginUrl="logon.aspx" name=".FormsAuthCookie"/>
</authentication>
其中元素loginUrl表示登陆网页的名称,name表示Cookie名称
2、<authorization> 节
作用:控制对 URL 资源的客户端访问(如允许匿名用户访问)。此元素可以在任何级别(计算机、站点、应用程序、子目录或页)上声明。必需与<authentication> 节配合使用。
示例:以下示例禁止匿名用户的访问
<authorization> <deny users="?"/> </authorization>
注:你可以使用user.identity.name来获取已经过验证的当前的用户名;可以使用 web.Security.FormsAuthentication.RedirectFromLoginPage方法将已验证的用户重定向到用户刚才请求的页面.具体的实例请参考:
Forms验证 http://www.fanvb.net/websample/dataauth.aspx
3、<compilation>节
作用:配置 ASP.NET 使用的所有编译设置。默认的debug属性为“True”.在程序编译完成交付使用之后应将其设为True(Web.config文件中有详细说明,此处省略示例)
4、<customErrors>
作用:为 ASP.NET 应用程序提供有关自定义错误信息的信息。它不适用于 XML Web services 中发生的错误。
示例:当发生错误时,将网页跳转到自定义的错误页面。
<customErrors defaultRedirect="ErrorPage.aspx" mode="RemoteOnly"> </customErrors>
其中元素defaultRedirect表示自定义的错误网页的名称。mode元素表示:对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。
5、<httpRuntime>节
作用:配置 ASP.NET HTTP 运行库设置。该节可以在计算机、站点、应用程序和子目录级别声明。
示例:控制用户上传文件最大为4M,最长时间为60秒,最多请求数为100
<httpRuntime maxRequestLength="4096" executionTimeout="60" appRequestQueueLimit="100"/>
6、 <pages>
作用:标识特定于页的配置设置(如是否启用会话状态、视图状态,是否检测用户的输入等)。<pages>可以在计算机、站点、应用程序和子目录级别声明。
示例:不检测用户在浏览器输入的内容中是否存在潜在的危险数据(注:该项默认是检测,如果你使用了不检测,一要对用户的输入进行编码或验证),在从客户端回发页时将检查加密的视图状态,以验证视图状态是否已在客户端被篡改。(注:该项默认是不验证)
<pages buffer="true" enableViewStateMac="true" validateRequest="false"/>
7、<sessionState>
作用:为当前应用程序配置会话状态设置(如设置是否启用会话状态,会话状态保存位置)。
示例:
<sessionState mode="InProc" cookieless="true" timeout="20"/> </sessionState>
注:
mode="InProc"表示:在本地储存会话状态(你也可以选择储存在远程服务器或SAL服务器中或不启用会话状态)
cookieless="true"表示:如果用户浏览器不支持Cookie时启用会话状态(默认为False)
timeout="20"表示:会话可以处于空闲状态的分钟数
8、<trace>
作用:配置 ASP.NET 跟踪服务,主要用来程序测试判断哪里出错。
示例:以下为Web.config中的默认配置:
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
注:
enabled="false"表示不启用跟踪;requestLimit="10"表示指定在服务器上存储的跟踪请求的数目
pageOutput="false"表示只能通过跟踪实用工具访问跟踪输出;
traceMode="SortByTime"表示以处理跟踪的顺序来显示跟踪信息
localOnly="true" 表示跟踪查看器 (trace.axd) 只用于宿主 Web 服务器
三、自定义Web.config文件配置节
自定义Web.config文件配置节过程分为两步。
一是在在配置文件顶部 <configSections> 和 </configSections>标记之间声明配置节的名称和处理该节中配置数据的 .NET Framework 类的名称。
二是在 <configSections> 区域之后为声明的节做实际的配置设置。
示例:创建一个节存储数据库连接字符串
<configuration> <configSections> <section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections>
<appSettings> <add key="scon" value="server=a;database=northwind;uid=sa;pwd=123"/> </appSettings>
<system.web> ...... </system.web> </configuration>
四、访问Web.config文件
你可以通过使用ConfigurationSettings.AppSettings 静态字符串集合来访问 Web.config 文件示例:获取上面例子中建立的连接字符串。
Dim sconstr As String = ConfigurationSettings.AppSettings("SconStr") Dim scon = New SqlConnection(sconstr) |
|
如何在ASP.NET中使用JavaScript脚本
|
简单点的
如要在一个按钮上增加认证脚本,可以这样
<%@ Page Language="C#" %>
<SCRIPT language="javascript">
function getconfirm ()
{
if (confirm("Do you want to delete record?")==true)
return true;
else
return false;
}
</SCRIPT>
<script runat="server">
public void Page_Load(Object sender, EventArgs E) {
btnSubmit.Attributes.Add("onclick","return getconfirm ();");
}
void btnSubmit_Click(object sender, EventArgs e) {
Message.Text = "You entered your name as: " + txtName.Text;
}
</script>
<html>
<head>
</head>
<body>
<form runat="server">
Name: <asp:Textbox id="txtName" runat="server"/>
<asp:Button id="btnSubmit" onclick="btnSubmit_Click" runat="server" Text="Submit"></asp:Button><br/>
<asp:Label id="Message" runat="server"/>
</form>
</body>
</html>
注意关键的地方btnSubmit.Attributes.Add("onclick","return fffkkk();");这句话,就相当于在静态页面标签上添加 “onclick = “return fffkkk();” 一样
二)复杂一点的
有的时候我们要在DataGrid的删除列上添加认证,可以这样
首先建一个DataGrid,然后给她增加一个删除列
<asp:DataGrid id="DataGrid1" runat="server">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:LinkButton id="cmdDel"
runat="server" Text="Delete"
CommandName="Delete" CausesValidation="false">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
然后在DataGrid 的ItemDataBound事件中这样写
Private Sub DataGrid1_ItemDataBound
(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
Handles DataGrid1.ItemDataBound
Dim l As LinkButton
If e.Item.ItemType = ListItemType.Item Or
e.Item.ItemType = ListItemType.AlternatingItem Then
l = CType(e.Item.Cells(0).FindControl("cmdDel"), LinkButton)
l.Attributes.Add("onclick", "return getconfirm();")
End If
End Sub
Getconfirm()函数和第一个是一样的
function getconfirm()
{
if (confirm("Do you want to delete record?")==true)
return true;
else
return false;
}
这样就可以了,呵呵,以上是我在编程中从资料里总结出来的,也许对你有用。 |
|
【算法】C#快速排序类
|
快速排序的基本思想是基于分治策略的。对于输入的子序列ap..ar,如果规模足够小则直接进行排序,否则分三步处理:
分解(Divide):将输入的序列ap..ar划分成两个非空子序列ap..aq和aq+1..ar,使ap..aq中任一元素的值不大于aq+1..ar中任一元素的值。 递归求解(Conquer):通过递归对p..aq和aq+1..ar进行排序。 合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在ap..aq和aq+1..ar都排好序后不需要执行任何计算ap..ar就已排好序。 这个解决流程是符合分治法的基本步骤的。因此,快速排序法是分治法的经典应用实例之一。
using System;
namespace VcQuickSort { /// <summary> /// ClassQuickSort 快速排序。 /// 范维肖 /// </summary> public class QuickSort { public QuickSort() { }
private void Swap(ref int i,ref int j) //swap two integer { int t; t=i; i=j; j=t; } public void Sort(int [] list,int low,int high) { if(high<=low) { //only one element in array list //so it do not need sort return; } else if (high==low+1) { //means two elements in array list //so we just compare them if(list[low]>list[high]) { //exchange them Swap(ref list[low],ref list[high]); return; } } //more than 3 elements in the arrary list //begin QuickSort myQuickSort(list,low,high); }
public void myQuickSort(int [] list,int low,int high) { if(low<high) { int pivot=Partition(list,low,high); myQuickSort(list,low,pivot-1); myQuickSort(list,pivot+1,high); } }
private int Partition(int [] list,int low,int high) { //get the pivot of the arrary list int pivot; pivot=list[low]; while(low<high) { while(low<high && list[high]>=pivot) { high--; } if(low!=high) { Swap(ref list[low],ref list[high]); low++; } while(low<high && list[low]<=pivot) { low++; } if(low!=high) { Swap(ref list[low],ref list[high]); high--; } } return low; }
} } |
|
[ASP.net]Loading制作
|
方法很简单。把代码放上来大家看看! 打了包成了个控件。下载地址: http://upserver4.ys168.com/ys168up/D1/YY1.aspx?f=050P1D8E0E3E5D9D5G6ALI7A00A05AKA03D6A00A08A08I5F9G0E0D9E0D8D6E1A24E6E1D9E5D9C3
下面是源码:
===================================
using System;
namespace HDControl { /// <summary> /// Summary description for Loading. /// </summary> public class Loading { private System.Web.UI.Page Sender; private string strImagePath;
public object Page { get { return Sender; } set { Sender = (System.Web.UI.Page)value; } }
public string ImageMapth { get { return strImagePath; } set { strImagePath = value; } }
public Loading() { // }
public Loading( object sender ) { Page = sender; }
public Loading( object sender,string ImageMapth ) { Page = sender; this.strImagePath = ImageMapth; }
/// <summary> /// Load script to page /// </summary> public void Load() { if ( !this.Sender.IsClientScriptBlockRegistered( "startScript" ) ) { this.Sender.RegisterClientScriptBlock( "startScript",this.Start() ); this.Sender.RegisterStartupScript( "endScript",this.End() ); } }
/// <summary> /// Script start. /// </summary> /// <returns></returns> private string Start() { string strStyle = "BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"; System.Text.StringBuilder strScript = new System.Text.StringBuilder(); strScript.Append( "<div id=\"loading\">" ); strScript.Append( "<table width=\"100%\" height=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\""+ strStyle + "\">" ); strScript.Append( "<tr style=\"" + strStyle + "\" ><td width=\"100%\" height=\"100%\" align=\"center\" valign=\"middle\" style=\"" + strStyle + "\">" ); strScript.Append( "<img src=\"" + this.ImageMapth + "\" border=\"0\">" ); strScript.Append( "</td></tr>" ); strScript.Append( "</table></div>" ); return strScript.ToString(); }
/// <summary> /// Script end. /// </summary> /// <returns></returns> private string End() { System.Text.StringBuilder strScript = new System.Text.StringBuilder(); strScript.Append( "<script language=\"javascript\">" ); strScript.Append( "window.document.getElementById(\"loading\").style.display = \"none\";" ); strScript.Append( "</script>" ); return strScript.ToString(); } } }
=========================
先在面页中
using HDControl;
调用方法(在Page_Load里):
LoadingControl.Loading objLoad = new LoadingControl.Loading( this,"Images/loading.gif" ); objLoad.Load();
或:
LoadingControl.Loading objLoad = new LoadingControl.Loading( ); objLoad.Page = this; objLoad.ImageMapth = "Images/loading.gif"; objLoad.Load(); |
|
JavaScript和ASP.NET的传值
|
JavaScript和ASP.NET的传值
作者:陈缘 联系:luandao2000@21cn.com 网页:http://blog.csdn.net/luandao2000
因项目需要,最近一段时间里对于js的开发有了一定的了解。在基于ASP.NET的开发中,经常性的需要JS脚本来增加一些客户端的控制,比如限制输入字符,日期控件等等。一般这样的控制基本上在客户端完成就比较好,无需回传到服务端。总结了最近的开发中使用的一些js的技巧,提供给大家
1、js脚本如何访问服务器控件的值 界面上有一个TextBox控件,ID为Name,js里可以采用如下脚本取Name的值 var myvalue=document.all('Name').value;
2、服务器控件如何取js中变量的值 目前未发现比较好的办法,我通常采用的方法是在界面上放一个隐藏的控件HtmlInputHidden,然后设置为以服务器控件运行,这样在js脚本中和ASP.NET代码里都可以访问到该控件的值 js中给服务器控件赋值: var bt=document.all('Name').value; bt.value='名称'; ASP.NET中使用Name.Value来访问。
3、如何遍历界面上所有TextBox元素 var inputList = document.body.getElementsByTagName("INPUT"); for(var i=0;i<inputList.length;i++) { if(inputList[i].disabled==false && (inputList[i].type=='text' || inputList[i].type=='password')) { inputList[i].value=""; } }
4、让dropdownlist选择到指定项 选择dropdownlist中值为“我得选择”得项 var handl=document.all('List1'); var my_value='我得选择'; for(var index=0;index<handle.options.length;index++) { if(handle.options[index].text==my_value) { handle.selectedIndex=index; } }
|
|
ASP.NET网站建设之代码分离
|
ASP.NET网站建设之代码分离
刘峰 2005-1-20
在我们传统的网站建设中通常是先设计网站页面,再利用开发工具,在网站的框架内进行功能设计。这样的网站建设存在很多弊端,其中最突出的缺点是不利于小组共同开发,各环节之间依赖性太强。
在ASP.NET中我们可以利用后台编码,把HTML用户界面设计(颜色、美学等)与页面代码区分开来。这样就可以解决我们小组的并行开发问题。
其主题思想是:美工来进行网站页面的设计,程序员对网站要实现的功能分模块开发。待到页面和功能模块开发完毕后,我们只要在美工界面中对其HTML代码稍加修改,就可以完成对应的功能。
下面就用一个小例子来进行说明。
程序员完成的功能有如下模块:
1. 在左边的Column1处点击,中间的三个内容显示小组三条新闻
2. 在Column2处点击,中间的三个内容显示三个人员情况
3. 在Column3处点击,弹出一个窗口显示一张照片。
为了测试,我们可以将这三个功能分别交给两个程序员来做。
甲程序员:完成模块1和2
1. 甲可以先建立一个WebApplication,在界面上放入两个ImageButton:IBtnNews,IBtnMember和六个Label:Lb1Title,Lb1Detail, Lb2Title,Lb2Detail, Lb3Title,Lb3Detail。生成一个Web应用程序,点击IBNews,六个Label显示小组新闻,点击IBMember,六个Label显示小组三名成员。这样我们就为建立源文件创建好了条件。
2. 我们建立一个C#类文件CodeBehind.cs。
3. 由于我们是建立的Web程序,则需要在添加引用中,添加System.Web.dll应用。
4. 去掉构造函数,因为后台编码不需要创建类。
5. 让类从Page对象上继承功能,即
public class CodeBehind:System.Web.UI.Page
6. 将刚才生成的WebApplication中的相关代码复制进来,主要有两个部分:声明部分和方法部分,在这里把应用程序中的可访问级别protected,改为public,因为只有这样外部的代码才可以访问我们的方法和变量,要注意的是页面上所有与后台编码文件交户的控件都要有一个对应的本地变量。
7. 生成一个CodeBehind.cs。
至此,甲程序员的工作完成。乙程序员可以用同样的方式生成他的CodeBehind.cs文件。甲乙两位程序员进行代码合成,完成一个完整的CodeBehinde.cs;
代码如下:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace codetest
{
public class News:System.Web.UI.Page
{
public System.Web.UI.WebControls.Label Lb1Title;
public System.Web.UI.WebControls.Label Lb1Detail;
public System.Web.UI.WebControls.Label Lb2Title;
public System.Web.UI.WebControls.Label Lb2Detail;
public System.Web.UI.WebControls.Label Lb3Title;
public System.Web.UI.WebControls.Label Lb3Detail;
public System.Web.UI.WebControls.ImageButton IBtnNews;
public System.Web.UI.WebControls.ImageButton IIBtnMember;
public System.Web.UI.WebControls.ImageButton IBtnContact;
public void IBtnNews_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
…………………………
}
public void IIBtnMember_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
…………………………
}
public void IBtnContact_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
string strScript="<script language=javascript>\n";
strScript+="window.alert("+"\"电话:66763467\""+");";
strScript+="</script>";
Response.Write(strScript);
}
}
}
下面我们来说明如何将建好的后台代码和美工好的网页结合起来。
1.集成工程师生成一个新的WebApplication,将CodeBehind.cs文件保存在bin目录下,并将其加入引用。
2.集成工程师将美工好的网页的图片加入对应的引用,复制HTML代码,放入新的WebApplication的页面中,这样,我们就可以看到美工好的页面展现在我们的.aspx文件中。
3.更改页面最上面的黄色代码,其中Codebehind="CodeBehind.cs":让页面后台支持的代码指向我们写好的cs文件。Inherits="codetest.CodeBehind":让页面继承于类CodeBehind中的功能,codetest为我们定义的名词空间。
4.在HTML代码中<body>内填入< form id="Form1" method="post" runat="server">在</body>上面加上</form>。
5.相对应的地方拖入Web控件,注意这里的ID要与cs文件中的定义对应。
6.在HTML代码中,找到Web控件,添加对应的方法名称。
这样就结合完毕。运行看看效果如何。
大家看上面在改动HTML代码的时候稍显麻烦,我们还有一种更简单的方法,只要在后台文件中加入几行代码,我们就不必在HTML中找到控件的位置,加入事件引用了。
在后台文件中加入
protected override void OnInit(EventArgs e)
//此方法引发Init事件,当服务器控件初始化是发生。
{
初始化控件方法()
base.OnInit(e);
}
private void初始化控件方法();
{
this.控件名.Click+=new EventHandler(控件事件响应方法);
}
上面两个方法的加入,我们可以看到,只要我们在后台代码中加入初始化控件的方法,就可以将对应的事件加入进去,而不用在HTML代码中加入事件引用了。同样,我们将常用的Page_Load事件也可以实现
只要加入:
Private void Page_Load(object sender,System.EventArgs e)
{
代码;
}
private void初始化控件方法();
{
this.控件名.Click+=new System.EventHandler(控件事件响应方法);
this.Load+=new System.EventHandler(this.Page_Load);
}
EventHandler:是表示将处理不包含事件数据的事件的方法。
控件事件响应方法只要符合:方法名(object sender,System.EventArgs e)就可以。
目前存在的问题:
1. 如何保持美工所作的效果不因使用了Web控件而受影响。
2. 多人在做同一个网页的时候,只能通过合并cs文件的方法来集成后台代码。不利于代码的维护。
|
|
[C#]结束Excel的进程的方法
|
在论坛中经常看到问如何结束Excel进程的帖子,很多人给出 的方法是先得到系统进程列表,然后和“Excel”匹配,是Excel 的进程就杀死,我个人认为这个方法是不可行的,如果软件用这种方法 杀死自己启动的进程,应该算是Bug(有可能将用户Excel进程杀掉)。 我在网上找到了另一种杀死Excel 进程的方法,如下: System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheets); System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet); ... System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp); System.Runtime.InteropServices.Marshal.ReleaseComObject(range); worksheets=null; worksheet=null; ... excelApp=null; range=null;
把操作Excel文件用到的对象实例全部释放。
然后资源回收! GC.Collect();
以上的代码最好能放在finally中,防止操作Excel文件时发生异常而执行不到!
在打开任务管理器看看,excel进程是不是已经不在了!
|
|
最佳ASP.NET编程习惯
|
初学编程的朋友往往喜欢收集一些很“奇妙”的编程技巧,然而,技巧的积累往往并没有提高程序质量,反而引导一些编程者一味追求奇和新,忘记了基本编程习惯的培养,不利于团队的合作,可能,这也是中国并不缺少聪明的程序员,但是缺少聪明的开发团队的一个原因吧。在ASP.NET的开发中,可以学习的技巧不少,但是,一些基本的编程习惯我们一定要养成,这样不但能根本上提高程序质量和开发效率,而且,也利于程序的阅读和团队开发。如果自己写的程序只有自己可以看懂或者只有几个人可以看懂,即使程序技巧神乎其技,对于程序的升级和维护都是致命问题。
一、 错误(以外)的处理 程序健壮性最基本要求就是程序错误的处理与捕捉,在ASP.NET中,错误的处理有和其他编程语言一样的机制,可以使用Try…Catch…Finally等方式,这一点和ASP相比具有较大的进步。而且,使用这些错误处理方法,可以大大提高程序的可读性和程序调试速度,在这几个优势结合的情况下,我们更加应该注意这一点。 关于错误的处理,我们可以参考这篇文章(英文): http://www.123aspx.com/redir.aspx?res=28336
二、 字符串的处理 网页设计中,字符串的处理几乎是最常见的了。使用ASP.NET以后,字符串的处理比ASP的速度快,而且,在ASP.NET中,专门增加一个字符串处理类StringBulider,使用这个类可以完成一些常见的字符串操作,而最主要的,使用StringBuilder可以大大提高字符串处理速度。 在ASP.NET中,最常见的就是使用“&”来连接两个字符串: Dim myOutputString As String = "My name is" Dim myInputString As String = " Alex" myOutputString = myOutputString & myInputString Response.Write(myoutputString) 现在,我们来看看StringBuilder的使用,在使用StringBuilder的时候,我们对字符串可以做一些基本的操作,比如Append、Replace、Insert、Remove等,现在我们来看具体举例。 (1)StringBuilder中Append的使用 Append和其他语言的Append一样,就是在字符串最后增加其他字符。 Dim sb as StringBuilder = New StringBuilder() sb.append( "<table border='1' width='80%'>" ) For i = 0 To RowCount - 1 sb.Append("<tr>") For k = 0 To ColCount - 1 sb.Append("<td>") sb.Append( dt.Rows(i).Item(k, DataRowVersion.Current).toString()) sb.Append( "</td>" ) Next sb.Append("<tr>") Next sb.Append( "</table>") Dim strOutput as String = sb.ToString() lblCompany.Text = strOutput 在以上的程序中,用Append方法实现了一个表格的输出,需要注意的一点是,StringBulider必须首先使用ToString()方法将其转化为String类型才可以直接输出。在以上的举例中,我们看到的全部是Append一个直接的字符串,其实,这个方法有一个很方便的功能,那就是可以直接Append其他类型的变量,比如可以直接Appemd一个Integer类型的数值,当然,我们输出以后自动转化为一个字符串: Sub Page_Load(Source As Object, E As EventArgs) Dim sb As System.Text.StringBuilder Dim varother As Integer varother=9999 sb =new System.Text.StringBuilder() sb.append("<font color='blue'>可以Append其他类型:</font>") sb.append(varother) Response.write(sb.toString()) End Sub (2)字符串中其他方法的使用 我们还可以使用其他方法,我们来看看常见的: Insert方法,可以在指定位置插入其他字符,使用方法:Insert(插入位置,插入字符); Remove方法,可以在指定位置删除指定字数字符,使用方法:Remove(其实位置,字符数); Replace方法,可以替换指定字符,使用方法:replace(被替换字符串,替换字符串) 字符串的具体介绍和使用方法可以参考以下文章(英文): http://aspfree.com/aspnet/stringbuilder.aspx http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextStringBuilderClassTopic.asp
三、 数据库链接Connection和DataReader的关闭 在使用ASP编程的时候,我们就已经知道,在使用数据库连接以后,一定要将连接关闭,然后设置为NoThing。在Asp.NET中,我们仍然需要这样使用,不过,在ASP.NET中,由于使用了ADO.NET,所以,在一些相关的处理方面,实际还是有一些细微的区别,而这些区别,往往也就是我们设计的时候最需要注意的。现在,我们通过举例,来看看在常见的ADO.NET操作中,需要注意哪些问题。 (1)举例一 Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs")) Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection) Dim myDataReader As SqlDataReader Try myConnection.Open() myDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection) DropDownList1.DataSource = myDataReader DropDownList1.DataBind() Catch myException As Exception Response.Write("An error has occurred: " & myException.ToString()) Finally If Not myDataReader Is Nothing Then '关闭DataReader myDataReader.Close() End If End Try 在以上的举例中,我们注意到,这里只关闭了DataReader,并没有关闭Connection。为什么呢?仔细观察以上的ExecuteReader方法,原来,设置了ExecuteReader参数,当执行完ExecuteReader以后,会自动关闭Connection。所以,这样设置以后,就没有必要再手动关闭Connection了。 (2)举例二 Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs")) Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection) Try myConnection.Open() DropDownList1.DataSource = myCommand.ExecuteReader() DropDownList1.DataBind() Catch myException As Exception Response.Write("An error has occurred: " & myException.ToString()) Finally If Not myConnection Is Nothing AndAlso ((myConnection.State And ConnectionState.Open) = ConnectionState.Open) Then myConnection.Close() End If End Try 在以上的举例中,我们发现,居然没有关闭DataReader。为什么呢?其实上面的代码中,没有直接生成DataReader对象,当然也就无从关闭了。需要注意一点的是,在关闭Connection之前,程序首先判断Connection是否已经打开,如果没有打开,也就没必要关闭了。
四、使用Web.Config/Maching.Config保存常用数据 一些数据我们需要时常使用,比如使用ADO.NET的时候,最常见的就是数据库连接语句,在ASP中,我们常常将这些信息保存在Application中。当然,在ASP.NET中,也可以这样,不过,ASP.NET已经提供一个配置文件WEB.Config,所以,我们最好将这些信息保存在WEB.Config中,当然,我们也可以保存在Machine.Config中,不过,这样的话,整个网站都必须使用,所以,一般我们都使用Web.Config。现在,我们来看具体这个文件的使用。 (1)Web.Config文件的设置 首先,我们来看Web.Config的设置,我们在这个文件中增加设置以下两个项目,设置如下: <configuration> <appsettings> <add key="dsn" value="myserver"/> <add key="someotherkey" value="somevalue"/> </appsettings> </configuration> (2)变量的使用 以上XML文件设置了dsn和someotherkey两个变量,现在我们看看程序中怎样使用: <html> <script language="VB" runat=server> Sub Page_Load(Sender as Object, E as EventArgs) Dim AppSettings as Hashtable = Context.GetConfig("appsettings") DSN.Text = AppSettings("dsn") SomeOther.Text = AppSettings("someotherkey") End Sub </script> <body> DSN Setting: <asp:label id="DSN" runat=server/> <br> Some Other Setting: <asp:label id="SomeOther" runat=server/> </body> </html> 上面的程序我们看到,使用这样定义的变量很简单也很方便。
五、使用.NET的方式调试程序 ASP程序的调试一直是编写ASP最难的地方,这一点,ASP程序员大概都深有体会,因为大家都是使用Response.write来调试。而这样调试最大的缺点是,当我们调试完毕,必须一个个来删除或者注释掉这些信息,想一想,如果程序代码达到几百行或者页面很多的程序,这样的工作是多么枯燥,最怕一点,忘记将这些调试用的write删除,可能在用户使用的时候就会出现一些不雅的调试信息。 使用ASP.NET以后,我们可以直接定义Trace来实现程序的调试。以上提到的麻烦可以轻松解决,熟悉,Trace可以通过具体页面和在Web.Config配置文件中来定义实现,这样,当程序调试完毕以后,直接将Trace设置为Off就可以了,这样,程序就不会有调试功能了。 (1)页面调试的实现 在一个具体的页面需要实现调试功能的时候,我们可以这样设置: <%@ Page Language="VB" Trace="True" %> (2)定义WEB.Config实现 在WEB.CONFIG中,我们也可以实现程序调试的打开: <configuration> <system.web> <trace enabled="true" requestLimit="10" localOnly="false"/> </system.web> </configuration> 使用以上的设置打开Trace以后,我们在具体的程序中就可以使用Trace来调试程序了,比如: Trace.Write("This is some custom debugging information") 或者调试程序变量: Trace.Write("This is is my variable and it's value is:" & myVariable.ToString()) 以上设置我们可以看出,在ASP.NET中,程序调试功能已经很方便简单了,我们在程序设计中如果忽略这些特点,继续采用ASP的思维来设计程序,那么我们的程序不但效率没有提高,也增加了其他开发者合作的难度。
六、总结 以上的一些程序编写习惯,我们可以慢慢养成,在程序设计的时候,不要太在意程序是否最简洁灵活,对于一般开发者而言,程序规范化和可读性可能比追求程序的灵活性更加重要。在互联网资源越来越丰富的情况下,我们可以参考一些很规范的程序源代码来学习,当然,最好的莫过于微软自己的东西,我们可以参考以下网址:http://www.asp.net,关于更多的程序编写问题,我们可以参考以下网址: http://www.gotdotnet.com/team/asp/ASP.NET%20Performance%20Tips%20and%20Tricks.aspx |
|
ASP.NET 2.0里轻松获取数据库连接统计数据
|
ASP.NET 2.0中的SqlConnection多了一个StatisticsEnabled属性和ResetStatistics()、RetrieveStatistics()两个方法,用于获取SQLServer的连接统计数据。
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <%@ page language="C#" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { string connString = "Northwind的连接串"; SqlConnection conn = new SqlConnection(connString); conn.StatisticsEnabled = true; conn.ResetStatistics(); conn.Open(); SqlCommand cmd = new SqlCommand("SELECT * FROM Orders", conn); SqlDataReader reader = cmd.ExecuteReader(); reader.Close(); conn.Close();
Hashtable ht = (Hashtable)conn.RetrieveStatistics(); foreach (string key in ht.Keys) { Label1.Text += "Key: " + key + " = " + ht[key] + "<BR />"; } } </script> <html> <head id="Head1" runat="server"> <title>Untitled Page</title> </head> <body> <form id="Form1" runat="server" autocomplete="on"> <asp:Label ID="Label1" Runat="server" Text=""></asp:Label> </form> </body> </html>
运行后的结果就是SQLServer连接统计数据结果:
Key: NetworkServerTime = 0 Key: BytesReceived = 156913 Key: UnpreparedExecs = 1 Key: SumResultSets = 1 Key: SelectCount = 1 Key: PreparedExecs = 0 Key: ConnectionTime = 30 Key: ExecutionTime = 30 Key: Prepares = 0 Key: BuffersSent = 1 Key: SelectRows = 830 Key: ServerRoundtrips = 1 Key: CursorOpens = 0 Key: Transactions = 0 Key: BytesSent = 48 Key: BuffersReceived = 20 Key: IduRows = 0 Key: IduCount = 0 |
|
Asp.NET常用函数 (VB.net)
|
作者: love610 加入时间: 2004-09-21 文档类型: 来自: 浏览统计: total: 100 year: 100 quarter: 100 month: 100 week: 62 today: 8
Asp.NET常用函数 (新手必读!)
Ucase(string) 将字符串转换为大写。 Val(string) 将代表数字的字符串转换为数值型态,若字符串中含有非数字的内容则会将其去除后,合并为一数字。 Weekday(date) 取的参数中的日期是一个星期的第几天,星期天为1、星期一为2、星期二为3 依此类推。 WeekDayName(number) 依接收的参数取得星期的名称,可接收的参数为1 到7,星期天为1、星期一为2、星期二为3 依此类推。 Split(expression[, delimiter]) 以delimiter 参数设定的条件字符串来将字符串分割为字符串数组。 Sqrt(number) 取得一数值得平方根。 Str(number) 将数字转为字符串后传回。 StrReverse(expression) 取得字符串内容反转后的结果。 Tan(number) 取得某个角度的正切值。 TimeOfDay() 取得目前不包含日期的时间。 Timer() 取得由0:00 到目前时间的秒数,型态为Double。 TimeSerial(hour, minute, second) 将接收的参数合并为一个只有时间Date 型态的数据。 Timavalue(time) 取得符合国别设定样式的时间值。 Today() 取得今天不包含时间的日期。 Trim(string) 去掉字符串开头和结尾的空白。 TypeName(varname) 取得变量或对象的型态。 Ubound(arrayname[, dimension]) 取得数组的最终索引值,dimension 参数是指定取得第几维度的最终索引值。 MonthName(month) 依接收的月份数值取得该月份的完整写法。 Now() 取得目前的日期和时间。 Oct(number) 将数值参数转换为8 进制值。 Replace(expression, find, replace) 将字符串中find 参数指定的字符串转换为replace 参数指定的字符串。 Right(string,length) 由字符串右边开始取得length 参数设定长度的字符。 RmDir(path) 移除一个空的目录。 Rnd() 取得介于0 到1 之间的小数,如果每次都要取得不同的值,使用前需加上Randomize 叙述。 Rtrim(string) 去掉字符串的右边空白部分。 Second(time) 取得时间内容的秒部分,型态为Integer。 Sign(number) 取得数值内容是正数或负数,正数传回1,负数传回-1,0 传回0。 Sin(number) 取得一个角度的正弦值。 Space(number) 取得number 参数设定的空白字符串。 IsDate(expression) 判断表达式内容是否为DateTime 型态,若是则传回True,反之则为False。 IsDbNull(expression) 判断表达式内容是否为Null,若是则传回True,反之则为False。 IsNumeric(expression) 判断表达式内容是否为数值型态,若是则传回True,反之则为False。 Join(sourcearray[, delimiter]) 将字符串数组合并唯一个字符串,delimiter 参数是设定在各个元素间加入新的字符串。 Lcase(string) 将字符串转换为小写字体。 Left(string, length) 由字符串左边开始取得length 参数设定长度的字符。 Len(string) 取得字符串的长度。 Log(number) 取得数值的自然对数。 Ltrim(string) 去掉字符串的左边空白部分。 Mid(string, start[, length]) 取出字符串中strat 参数设定的字符后length 长度的字符串,若length 参数没有设定,则取回start 以后全部的字符。 Minute(time) 取得时间内容的分部分,型态为Integer。 MkDir(path) 建立一个新的目录。 Month(date) 取得日期的月部分,型态为Integer。 FormatDateTime(date[,namedformat]) 传回格式化的日期或时间数据。 FormatNumber(expression[,numdigitsafterdecimal [,includeleadingdigit]]) 传回格式化 的数值数据。Numdigitsafterdecimal 参数为小数字数,includeleadingdigit 参数为当整数为0 时是否补至整数字数。 FormatPercent(expression[,numdigitsafterdecimal [,includeleadingdigit]]) 传回转换为百分比格式的数值数据。numdigitsafterdecimal 参数为小数字数,includeleadingdigit 参数为当整数为0 时是否补至整数字数。 GetAttr(filename) 传回档案或目录的属性值。 Hex(number) 将数值参数转换为16 进制值。 Hour(time) 传回时间的小时字段,型态是Integer。 Iif(expression, truepart, falsepart) 当表达式的传回值为True 时执行truepart 字段的程序,反之则执行falsepart 字段。 InStr([start, ]string1, string2) 搜寻string2 参数设定的字符出现在字符串的第几个字符,start 为由第几个字符开始寻找,string1 为欲搜寻的字符串,string2 为欲搜寻的字符。 Int(number) 传回小于或等于接收参数的最大整数值。 IsArray(varname) 判断一个变量是否为数组型态,若为数组则传回True,反之则为False。 Day(datetime) 依接收的日期参数传回日。 Eof(filenumber) 当抵达一个被开启的档案结尾时会传回True。 Exp(number) 依接收的参数传回e 的次方值。 FileDateTime(pathname) 传回档案建立时的日期、时间。 FileLen(pathname) 传回档案的长度,单位是Byte。 Filter(sourcearray, match[, include[, compare]]) 搜寻字符串数组中的指定字符串,凡是数组元素中含有指定字符串,会将它们结合成新的字符串数组并传回。若是要传回不含指定字符串的数组元素,则include 参数设为False。compare 参数则是设定搜寻时是否区分大小写,此时只要给TextCompare 常数或1 即可。 Fix(number) 去掉参数的小数部分并传回。 Format(expression[, style[, firstdayofweek[, firstweekofyear]]]) 将日期、时间和数值资料转为每个国家都可以接受的格式。 FormatCurrency(expression[,numdigitsafterdecimal [,includeleadingdigit]]) 将数值输出为金额型态。 numdigitsafterdecimal 参数为小数字数,includeleadingdigit 参数为当整数为0 时是否补至整数字数。 CObj(expression) 转换表达式为Object 型态。 CShort(expression) 转换表达式为Short 型态。 CSng(expression) 转换表达式为Single 型态。 CStr(expression) 转换表达式为String 型态。 Choose (index, choice-1[, choice-2, ... [, choice-n]]) 以索引值来选择并传回所设定的参数。 Chr(charcode) 以ASCII 码来取得字符内容。 Close(filenumberlist) 结束使用Open 开启的档案。 Cos(number) 取得一个角度的余弦值。 Ctype(expression, typename) 转换表达式的型态。 DateAdd(dateinterval, number, datetime) 对日期或时间作加减。 DateDiff(dateinterval, date1, date2) 计算两个日期或时间间的差值。 DatePart (dateinterval, date) 依接收的日期或时间参数传回年、月、日或时间。 DateSerial(year, month, day) 将接收的参数合并为一个只有日期的Date 型态的数据。 Datevalue(datetime) 取得符合国别设定样式的日期值,并包含时间。 Abs(number) 取得数值的绝对值。 Asc(String) 取得字符串表达式的第一个字符ASCII 码。 Atn(number) 取得一个角度的反正切值。 CallByName (object, procname, usecalltype,[args()]) 执行一个对象的方法、设定或传回对象的属性。 CBool(expression) 转换表达式为Boolean 型态。 CByte(expression) 转换表达式为Byte 型态。 CChar(expression) 转换表达式为字符型态。 CDate(expression) 转换表达式为Date 型态。 CDbl(expression) 转换表达式为Double 型态。 CDec(expression) 转换表达式为Decimal 型态。 CInt(expression) 转换表达式为Integer 型态。 CLng(expression) 转换表达式为Long 型态
|
|
ASP.NET 页面对象模型
|
作者: Dino 加入时间: 2004-08-07 文档类型: 来自: 浏览统计: total: 20 year: 20 quarter: 20 month: 20 week: 9 today: 4
摘要:了解为 ASP.NET Web 页面建立的事件模型,以及 Web 页面转变为 HTML 过程中的各个阶段。ASP.NET HTTP 运行时负责管理对象管道,这些对象首先将请求的 URL 转换成 Page 类的具体实例,然后再将这些实例转换成纯 HTML 文本。本文将探讨那些作为页面生命周期标志的事件,以及控件和页面编写者如何干预并改变标准行为。(本文包含一些指向英文站点的链接。)
目录
简介 真正的 Page 类 页面的生命周期 执行的各个阶段 小结
简介
对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道。HTTP 管道由一系列托管对象组成,这些托管对象按顺序处理请求,并将 URL 转换为纯 HTML 文本。HTTP 管道的入口是 HttpRuntime 类。ASP.NET 结构为辅助进程中的每个 AppDomain 创建一个此类的实例。(请注意,辅助进程为每个当前正在运行的 ASP.NET 应用程序维护一个特定的 AppDomain。)
HttpRuntime 类从内部池中获取 HttpApplication 对象,并安排此对象来处理请求。HTTP 应用程序管理器完成的主要任务就是找到将真正处理请求的类。当请求 .aspx 资源时,处理程序就是页面处理程序,即从 Page 继承的类的实例。资源类型和处理程序类型之间的关联关系存储在应用程序的配置文件中。更确切地说,默认的映射集是在 machine.config 文件的 <httpHandlers> 部分定义的。但是,应用程序可以在本地的 web.config 文件中自定义自己的 HTTP 处理程序列表。以下这一行代码就是用来为 .aspx 资源定义 HTTP 处理程序的。<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
扩展名可以与处理程序类相关联,并且更多是与处理程序工厂类相关联。在所有情况下,负责处理请求的 HttpApplication 对象都会获得一个实现 IHttpHandler 接口的对象。如果根据 HTTP 处理程序来解析关联的资源/类,则返回的类将直接实现接口。如果资源被绑定到处理程序工厂,则还需要额外的步骤。处理程序工厂类实现 IHttpHandlerFactory 接口,此接口的 GetHandler 方法将返回一个基于 IHttpHandler 的对象。
HTTP 运行时是如何结束这个循环并处理页面请求的?ProcessRequest 方法在 IHttpHandler 接口中非常重要。通过对代表被请求页面的对象调用此方法,ASP.NET 结构会启动将生成浏览器输出的进程。
真正的 Page 类
特定页面的 HTTP 处理程序类型取决于 URL。首次调用 URL 时,将构建一个新的类,这个类被动态编译为一个程序集。检查 .aspx 资源的分析进程的结果是类的源代码。该类被定义为命名空间 ASP 的组成部分,并且被赋予了一个模拟原始 URL 的名称。例如,如果 URL 的终点是 page.aspx,则类的名称就是 ASP.Page_aspx。不过,类的名称可以通过编程方式来控制,方法是在 @Page 指令中设置 ClassName 属性。
HTTP 处理程序的基类是 Page。这个类定义了由所有页面处理程序共享的方法和属性的最小集合。Page 类实现 IHttpHandler 接口。
在很多情况下,实际处理程序的基类并不是 Page,而是其他的类。例如,如果使用了代码分离,就会出现这种情况。代码分离是一项开发技术,它可以将页面所需的代码隔离到单独的 C# 和 Microsoft Visual Basic® .NET 类中。页面的代码是一组事件处理程序和辅助方法,这些处理程序和方法真正决定了页面的行为。可以使用 <script runat=server> 标记对此代码进行内联定义,或者将其放置在外部类(代码分离类)中。代码分离类是从 Page 继承并使用额外的方法的类,被指定用作 HTTP 处理程序的基类。
还有一种情况,HTTP 处理程序也不是基于 Page 的,即在应用程序配置文件的 <pages> 部分中,包含了 PageBaseType 属性的重新定义。<pages PageBaseType="Classes.MyPage, mypage" />
PageBaseType 属性指明包含页面处理程序的基类的类型和程序集。从 Page 导出的这个类可以自动赋予处理程序扩展的自定义方法和属性集。
页面的生命周期
完全识别 HTTP 页面处理程序类后,ASP.NET 运行时将调用处理程序的 ProcessRequest 方法来处理请求。通常情况下,无需更改此方法的实现,因为它是由 Page 类提供的。
此实现将从调用为页面构建控件树的 FrameworkInitialize 方法开始。FrameworkInitialize 方法是 TemplateControl 类(Page 本身从此类导出)的一个受保护的虚拟成员。所有为 .aspx 资源动态生成的处理程序都将覆盖 FrameworkInitialize。在此方法中,构建了页面的整个控件树。
接下来,ProcessRequest 使页面经历了各个阶段:初始化、加载视图状态信息和回发数据、加载页面的用户代码以及执行回发服务器端事件。之后,页面进入显示模式:收集更新的视图状态,生成 HTML 代码并随后将代码发送到输出控制台。最后,卸载页面,并认为请求处理完毕。
在各个阶段中,页面会触发少数几个事件,这些事件可以由 Web 控件和用户定义的代码截取并进行处理。其中的一些事件是嵌入式控件专用的,因此无法在 .aspx 代码级进行处理。
要处理特定事件的页面应该明确注册一个适合的处理程序。不过,为了向后兼容早期的 Visual Basic 编程风格,ASP.NET 也支持隐式事件挂钩的形式。默认情况下,页面会尝试将特定的方法名称与事件相匹配,如果实现匹配,则认为此方法就是匹配事件的处理程序。ASP.NET 提供了六种方法名称的特定识别,它们是 Page_Init、Page_Load、Page_DataBind、Page_PreRender 和 Page_Unload。这些方法被认为是由 Page 类提供的相应事件的处理程序。HTTP 运行时会自动将这些方法绑定到页面事件,这样,开发人员就不必再编写所需的粘接代码了。例如,如果命名为 Page_Load 的方法绑定到页面的 Load 事件,则可省去以下代码。this.Load += new EventHandler(this.Page_Load);
对特定名称的自动识别是由 @Page 指令的 AutoEventWireup 属性控制的。如果该属性设置为 false,则要处理事件的所有应用程序都需要明确连接到页面事件。不使用自动绑定事件的页面性能会稍好一些,因为不需要额外匹配名称与事件。请注意,所有 Microsoft Visual Studio® .NET 项目都是在禁用 AutoEventWireup 属性的情况下创建的。但是,该属性的默认设置是 true,即 Page_Load 等方法会被识别,并被绑定到相关联的事件。
下表中按顺序列出了页面的执行包括的几个阶段,执行的标志是一些应用程序级的事件和/或受保护并可覆盖的方法。
表 1:ASP.NET 页面生命中的关键事件
阶段
页面事件
可覆盖的方法
页面初始化
Init
加载视图状态
LoadViewState
处理回发数据
任意实现 IPostBackDataHandler 接口的控件中的 LoadPostData 方法
加载页面
Load
回发更改通知
任意实现 IPostBackDataHandler 接口的控件中的 RaisePostDataChangedEvent 方法
处理回发事件
由控件定义的任意回发事件
任意实现 IPostBackDataHandler 接口的控件中的 RaisePostBackEvent 方法
页面显示前阶段
PreRender
保存视图状态
SaveViewState
显示页面
Render
卸载页面
Unload
以上所列的阶段中有些在页面级是不可见的,并且仅对服务器控件的编写者和要创建从 Page 导出的类的开发人员有意义。Init、Load、PreRender、Unload,再加上由嵌入式控件定义的所有回发事件,就构成了向外发送页面的各个阶段标记。
执行的各个阶段
页面生命周期中的第一个阶段是初始化。这个阶段的标志是 Init 事件。在成功创建页面的控件树后,将对应用程序触发此事件。换句话说,当 Init 事件发生时,.aspx 源文件中静态声明的所有控件都已实例化并采用各自的默认值。控件可以截取 Init 事件以初始化在传入的 Web 请求的生命周期内所需的所有设置。例如,这时控件可以加载外部模板文件或设置事件的处理程序。请注意,这时视图状态信息尚不可用。
初始化之后,页面框架将加载页面的视图状态。视图状态是名称/值对的集合,在此集合中,控件和页面本身存储了对所有 Web 请求都必须始终有效的全部信息。视图状态代表了页面的调用上下文。通常,它包含上次在服务器上处理页面时控件的状态。首次在会话中请求页面时,视图状态为空。默认情况下,视图状态存储在静默添加到页面的隐藏字段中,该字段的名称是 __VIEWSTATE。通过覆盖 LoadViewState 方法(Control 类的受保护、可覆盖方法),组件开发人员可以控制视图状态的存储方式以及视图状态的内容映射到内部状态的方式。
有些方法(如 LoadPageStateFromPersistenceMedium 以及其对应的 SavePageStateToPersistenceMedium),可以用来将视图状态加载并保存到其他存储介质(例如会话、数据库或服务器端文件)中。与 LoadViewState 不同,上述方法只能在从 Page 导出的类中使用。
存储视图状态之后,页面树中控件的状态与页面最后一次显示在浏览器中的状态相同。下一步是更新它们的状态以加入客户端的更改。处理回发数据阶段使控件有机会更新其状态,从而准确反映客户端相应的 HTML 元素的状态。例如,服务器的 TextBox 控件对应的 HTML 元素是 <input type=text>。在回发数据阶段,TextBox 控件将检索 <input> 标记的当前值,并使用该值来刷新自己内部的状态。每个控件都要从回发的数据中提取值并更新自己的部分属性。TextBox 控件将更新它的 Text 属性,而 CheckBox 控件将刷新它的 Checked 属性。服务器控件和 HTML 元素的对应关系可以通过二者的 ID 找到。
在处理回发数据阶段的最后,页面中的所有控件的状态都将使用客户端输入的更改来更新前一状态。这时,将对页面触发 Load 事件。
页面中可能会有一些控件,当其某个敏感属性在两个不同的请求中被修改时,需要完成特定的任务。例如,如果 TextBox 控件的文本在客户端被修改,则此控件将触发 TextChanged 事件。每个控件在其一个或多个属性被修改为客户端输入的值时都可以决定触发相应的事件。对于这些更改对其非常关键的控件,控件实现 IPostBackDataHandler 接口,此接口的 LoadPostData 方法是在 Load 事件后立即调用的。通过对 LoadPostData 方法进行编码,控件将验证自上次请求后是否发生了关键更改,并触发自己的更改事件。
页面生命周期中的关键事件是被调用以执行服务器端代码的事件,此代码与客户端触发的事件相关联。当用户单击按钮时,将回发页面。回发值的集合中包括启动整个操作的按钮的 ID。如果控件实现 IPostBackEventHandler 接口(如按钮和链接按钮),页面框架将调用 RaisePostBackEvent 方法。此方法的行为取决于控件的类型。就按钮和链接按钮而言,此方法将查找 Click 事件处理程序并运行相关的委托。
处理完回发事件之后,页面就可以显示了。这个阶段的标志是 PreRender 事件。控件可以利用这段时间来执行那些需要在保存视图状态和显示输出的前一刻执行的更新操作。下一个状态是 SaveViewState,在此状态中,所有控件和页面本身都将更新自己 ViewState 集合的内容。然后,将得到序列化、散列、Base64 编码的视图状态,而且此视图状态与隐藏字段 __VIEWSTATE 相关联。
通过覆盖 Render 方法可以改变各个控件的显示机制。此方法接受 HTML 书写器对象,并使用此对象来积累所有要为控件生成的 HTML 文本。Page 类的 Render 方法的默认实现包括对所有成员控件的递归调用。对于每个控件,页面都将调用 Render 方法,并缓存 HTML 输出。
页面生命中的最后一个标志是 Unload 事件,在页面对象消除之前发生。在此事件中,您应该释放所有可能占用的关键资源(例如文件、图形对象、数据库连接等)。
在此事件之后,也就是最后,浏览器接收 HTTP 响应数据包并显示页面。
小结
ASP.NET 页面对象模型因其事件机制而显得格外新颖独特。Web 页面由控件组成,这些控件既可以产生丰富的基于 HTML 的用户界面,又可以通过事件与用户交互。以前,在 Web 应用程序的上下文中设置事件模型是件有挑战性的工作。可我们惊奇的看到,客户端生成的事件可以由服务器端的代码来解决,而且只进行一些相应的修改后,此过程仍可以输出相同的 HTML 页面。
掌握这个模型对于了解页面生命周期的各个阶段,以及页面对象如何被 HTTP 运行时实例化并使用是非常重要的。
关于作者
Dino Esposito 是一位来自意大利罗马的培训教师和顾问。作为 Wintellect 团队的成员,Dino 专门研究 ASP.NET 和 ADO.NET,主要在欧洲和美国从事教学和咨询工作。此外,Dino 还负责管理 Wintellect 的 ADO.NET 课件,并为 MSDN 期刊的“Cutting Edge”专栏撰写文章。要与他联系,请向 dinoe@wintellect.com 发送电子邮件。 |
|
ASP.NET 中如何防范SQL注入式攻击
|
一、什么是SQL注入式攻击? 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。常见的SQL注入式攻击过程类如: ⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码。 ⑵ 登录页面中输入的内容将直接用来构造动态的SQL命令,或者直接用作存储过程的参数。下面是ASP.NET应用构造查询的一个例子: System.Text.StringBuilder query = new System.Text.StringBuilder("SELECT * from Users WHERE login = '")。Append(txtLogin.Text)。Append("' AND password='")。Append(txtPassword.Text)。Append("'"); ⑶ 攻击者在用户名字和密码输入框中输入"'或'1'='1"之类的内容。 ⑷ 用户输入的内容提交给服务器之后,服务器运行上面的ASP.NET代码构造出查询用户的SQL命令,但由于攻击者输入的内容非常特殊,所以最后得到的SQL命令变成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'. ⑸ 服务器执行查询或存储过程,将用户输入的身份信息和服务器中保存的身份信息进行对比。 ⑹ 由于SQL命令实际上已被注入式攻击修改,已经不能真正验证用户身份,所以系统会错误地授权给攻击者。 如果攻击者知道应用会将表单中输入的内容直接用于验证身份的查询,他就会尝试输入某些特殊的SQL字符串篡改查询改变其原来的功能,欺骗系统授予访问权限。 系统环境不同,攻击者可能造成的损害也不同,这主要由应用访问数据库的安全权限决定。如果用户的帐户具有管理员或其他比较高级的权限,攻击者就可能对数据库的表执行各种他想要做的操作,包括添加、删除或更新数据,甚至可能直接删除表。 二、如何防范? 好在要防止ASP.NET应用被SQL注入式攻击闯入并不是一件特别困难的事情,只要在利用表单输入的内容构造SQL命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。 ⑴ 对于动态构造SQL查询的场合,可以使用下面的技术: 第一:替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改SQL命令的含义。再来看前面的例子,“SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'”显然会得到与“SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'”不同的结果。 第二:删除用户输入内容中的所有连字符,防止攻击者构造出类如“SELECT * from Users WHERE login = 'mas' —— AND password =''”之类的查询,因为这类查询的后半部分已经被注释掉,不再有效,攻击者只要知道一个合法的用户登录名称,根本不需要知道用户的密码就可以顺利获得访问权限。 第三:对于用来执行查询的数据库帐户,限制其权限。用不同的用户帐户执行查询、插入、更新、删除操作。由于隔离了不同帐户可执行的操作,因而也就防止了原本用于执行SELECT命令的地方却被用于执行INSERT、UPDATE或DELETE命令。 ⑵ 用存储过程来执行所有的查询。SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。 ⑶ 限制表单或查询字符串输入的长度。如果用户的登录名字最多只有10个字符,那么不要认可表单中输入的10个以上的字符,这将大大增加攻击者在SQL命令中插入有害代码的难度。 ⑷ 检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端都执行——之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。 在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给服务器。因此,要保证验证操作确实已经执行,唯一的办法就是在服务器端也执行验证。你可以使用许多内建的验证对象,例如RegularExpressionValidator,它们能够自动生成验证用的客户端脚本,当然你也可以插入服务器端的方法调用。如果找不到现成的验证对象,你可以通过CustomValidator自己创建一个。 ⑸ 将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了“消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入SQL命令。System.Web.Security.FormsAuthentication类有一个HashPasswordForStoringInConfigFile,非常适合于对输入数据进行消毒处理。 ⑹ 检查提取数据的查询所返回的记录数量。如果程序只要求返回一个记录,但实际返回的记录却超过一行,那就当作出错处理。 |
|
Asp.net动态生成html页面
|
作者: love610 加入时间: 2004-09-21 文档类型: 来自: 浏览统计: total: 31 year: 31 quarter: 31 month: 31 week: 15 today: 2
最近研究一个新闻系统,找到了关于asp.net生成HTML的资料
思路
1. 利用如Dw-Mx这样的工具生成html格式的模板,在需要添加格式的地方加入特殊标记(如$htmlformat$),动态生成文件时利用代码读取此模板,然后获得前台输入的内容,添加到此模板的标记位置中,生成新文件名后写入磁盘,写入后再向数据库中写入相关数据。
2. 使用后台代码硬编码Html文件,可以使用HtmlTextWriter类来写html文件。
优点
1. 可以建立非常复杂的页面,利用包含js文件的方法,在js文件内加入document.write()方法可以在所有页面内加入如页面头,广告等内容。
2. 静态html文件利用MS Windows2000的Index Server可以建立全文搜索引擎,利用asp.net可以以DataTable的方式得到搜索结果。而Win2000的Index服务无法查找xml文件的内容。如果包括了数据库搜索与Index索引双重查找,那么此搜索功能将非常强大。
3. 节省服务器的负荷,请求一个静态的html文件比一个aspx文件服务器资源节省许多。
缺点
思路二: 如果用硬编码的方式,工作量非常大,需要非常多的html代码。调试困难。而且使用硬编码生成的html样式无法修改,如果网站更换样式,那么必须得重新编码,给后期带来巨大的工作量。
因此这里采用的是第一种思路
示列代码
1.定义(template.htm)html模板页面
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body >
<table $htmlformat[0] height="100%" border="0" width="100%" cellpadding="10" cellspacing="0" bgcolor="#eeeeee" style="border:1px solid #000000">
<tr>
<td width="100%" valign="middle" align="left">
<span style="color: $htmlformat[1];font-size: $htmlformat[2]">$htmlformat[3]</span>
</td>
</tr>
</table>
</body>
</html>
2.asp.net代码:
//---------------------读html模板页面到stringbuilder对象里----
string[] format=new string[4];//定义和htmlyem标记数目一致的数组
StringBuilder htmltext=new StringBuilder();
try
{
using (StreamReader sr = new StreamReader("存放模板页面的路径和页面名"))
{
String line;
while ((line = sr.ReadLine()) != null)
{
htmltext.Append(line);
}
sr.Close();
}
}
catch
{
Response.Write("<Script>alert('读取文件错误')</Script>");
}
//---------------------给标记数组赋值------------
format[0]="background=\"bg.jpg\"";//背景图片
format[1]= "#990099";//字体颜色
format[2]="150px";//字体大小
format[3]= "<marquee>生成的模板html页面</marquee>";//文字说明
//----------替换htm里的标记为你想加的内容
for(int i=0;i<4;i++)
{
htmltext.Replace("$htmlformat["+i+"]",format[i]);
}
//----------生成htm文件------------------――
try
{
using(StreamWriter sw=new StreamWriter("存放路径和页面名",false,System.Text.Encoding.GetEncoding("GB2312")))
{
sw.WriteLine(htmltext);
sw.Flush();
sw.Close();
}
}
catch
{
Response.Write ("The file could not be wirte:");
}
小结
用此方法可以方便的生成html文件。程序使用了是循环替换,因此对需替换大量元素的模板速度非常快。 |
|
在ASP.NET中创建安全的web站点
|
以前用ASP,PHP,JSP编写网站代码的时候,站点安全性总是一件头疼的事情,虽然我们编写了用户登录,注册,验证页面,但是效果总是不理想。有时候我们不得不用大量的session变量来存放相关信息,处处设防。而在.NET环境下,这个问题处理起来就非常容易了。关键是要充分理解web.config文件。首先,介绍一下web.config文件。 <?xml version="1.0" encoding="utf-8" ?> <configuration>
<system.web>
<!-- 动态调试编译 设置 compilation debug="true" 以将调试符号(.pdb 信息) 插入到编译页中。因为这将创建执行起来 较慢的大文件,所以应该只在调试时将该值设置为 true,而所有其他时候都设置为 false。有关更多信息,请参考有关 调试 ASP.NET 文件的文档。 --> <compilation defaultLanguage="vb" debug="true" />
<!-- 自定义错误信息 设置 customErrors mode="On" 或 "RemoteOnly" 以启用自定义错误信息,或设置为 "Off" 以禁用自定义错误信息。 为每个要处理的错误添加 <error> 标记。 --> <customErrors mode="RemoteOnly" />
<!-- 身份验证 此节设置应用程序的身份验证策略。可能的模式是 “Windows”、 “Forms”、“Passport”和 “None” --> <authentication mode="Windows" />
<!-- 授权 此节设置应用程序的授权策略。可以允许或拒绝用户或角色访问 应用程序资源。通配符:"*" 表示任何人,"?" 表示匿名 (未授权的)用户。 --> <authorization> <allow users="*" /> <!-- 允许所有用户 -->
<!-- <allow users="[逗号分隔的用户列表]" roles="[逗号分隔的角色列表]"/> <deny users="[逗号分隔的用户列表]" roles="[逗号分隔的角色列表]"/> --> </authorization>
<!-- 应用程序级别跟踪记录 应用程序级别跟踪在应用程序内为每一页启用跟踪日志输出。 设置 trace enabled="true" 以启用应用程序跟踪记录。如果 pageOutput="true",则 跟踪信息将显示在每一页的底部。否则,可以通过从 Web 应用程序 根浏览 "trace.axd" 页来查看 应用程序跟踪日志。 --> <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
<!-- 会话状态设置 默认情况下,ASP.NET 使用 cookie 标识哪些请求属于特定的会话。 如果 cookie 不可用,则可以通过将会话标识符添加到 URL 来跟踪会话。 若要禁用 cookie,请设置 sessionState cookieless="true"。 --> <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;user id=sa;password=" cookieless="false" timeout="20" />
<!-- 全球化 此节设置应用程序的全球化设置。 --> <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
</system.web>
</configuration>
好了,相信看过上面的介绍以后,对web.config文件一定非常了解了吧。下面我们就切入主题。为了防止用户没有经过验证就访问站点,我们的处理方法是当用户没有通过验证的时候点击任何页面将会直接跳到Login.aspx页面,具体代码如下:
<authentication mode="Forms"> <forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" /> </authentication> <authorization> <deny users="?" /> </authorization> 但是这样会产生一个问题,那就是如果我的站点有一些信息是可以让任意用户随意访问的,比如站点简介,使用说明等。如果按照上面的处理方法岂不让用户觉得很麻烦,呵呵,不急,在ASP.NET中自然有相应的解决办法。下面的代码可以实现匿名用户访问Test.aspx页面:
<location path="test.aspx"> <system.web> <authorization> <allow users="?" /> </authorization> </system.web> </location>
解决了上面两个问题,相信大家心里一定有底了吧。下面就开始实现login.aspx页面。利用C#和SQL Server2000,创建一个webform页面,加入相应的控件。具体代码如下: 代码运行框: <%@ Page language="c#" Codebehind="login.aspx.cs"
AutoEventWireup="false" Inherits="secure.login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>Secure Site</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="login" method="post" runat="server">
<table cellSpacing="0" cellPadding="0" border="0">
<tr>
<td vAlign="top" align="left">
<asp:label id="Message" Runat="server" ForeColor="#ff0000">
</asp:label>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<b>E-mail:</b>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:textbox id="username" Runat="server" Width="120">
</asp:textbox>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<b>Password:</b>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:textbox id="password" Runat="server"
Width="120" TextMode="Password">
</asp:textbox>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:checkbox id="saveLogin" Runat="server"
Text="<b>Save my login</b>">
</asp:checkbox>
</td>
</tr>
<tr>
<td vAlign="top" align="right">
<asp:imagebutton id="btnLogin" Runat="server"
ImageUrl="/images/w2k/login/btnLogin.gif">
</asp:imagebutton>
</td>
</tr>
</table>
</form>
</body>
</HTML>
[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
界面做好之后,就开始编写提交按钮事件,首先需要注册该事件,代码如下: private void InitializeComponent() { this.btnLogin.Click += new System.Web.UI.ImageClickEventHandler(this.btnLogin_Click); . . . } 事件注册好之后,自然就是编写事件处理函数了:
private void btnLogin_Click(object sender, System.Web.UI.ImageClickEventArgs e) { CCommonDB sql = new CCommonDB(); string redirect = "";
if((redirect = sql.AuthenticateUser(this.Session, this.Response, username.Text, password.Text, saveLogin.Checked)) != string.Empty) { // Redirect the user Response.Redirect(redirect); } else { Message.Text = "Login Failed!"; } } 读者看完上面的代码之后一定想问CCommonDB是哪里来的东东,这是我编写的一个类,用来处理用户登录信息的,如果成功则把相关信息写入session、Cookie和SQL数据库,同时跳到default.aspx页面。具体如下:
CCommonDB.cs
namespace secure.Components
{
public class CCommonDB : CSql
{
public CCommonDB() : base() { }
public string AuthenticateUser(
System.Web.SessionState.HttpSessionState objSession, // Session Variable
System.Web.HttpResponse objResponse, // Response Variable
string email, // Login
string password, // Password
bool bPersist // Persist login
)
{
int nLoginID = 0;
int nLoginType = 0;
// Log the user in
Login(email, password, ref nLoginID, ref nLoginType);
if(nLoginID != 0) // Success
{
// Log the user in
System.Web.Security.FormsAuthentication.SetAuthCookie(nLoginID.ToString(), bPersist);
// Set the session varaibles
objSession["loginID"] = nLoginID.ToString();
objSession["loginType"] = nLoginType.ToString();
// Set cookie information incase they made it persistant
System.Web.HttpCookie wrapperCookie = new System.Web.HttpCookie("wrapper");
wrapperCookie.Value = objSession["wrapper"].ToString();
wrapperCookie.Expires = DateTime.Now.AddDays(30);
System.Web.HttpCookie lgnTypeCookie = new System.Web.HttpCookie("loginType");
lgnTypeCookie.Value = objSession["loginType"].ToString();
lgnTypeCookie.Expires = DateTime.Now.AddDays(30);
// Add the cookie to the response
objResponse.Cookies.Add(wrapperCookie);
objResponse.Cookies.Add(lgnTypeCookie);
return "/candidate/default.aspx";
}
case 1: // Admin Login
{
return "/admin/default.aspx";
}
case 2: // Reporting Login
{
return "/reports/default.aspx";
}
default:
{
return string.Empty;
}
}
}
else
{
return string.Empty;
}
}
/// <summary>
/// Verifies the login and password that were given
/// </summary>
/// <param name="email">the login</param>
/// <param name="password">the password</param>
/// <param name="nLoginID">returns the login id</param>
/// <param name="nLoginType">returns the login type</param>
public void Login(string email, string password, ref int nLoginID, ref int nLoginType)
{
ResetSql();
DataSet ds = new DataSet();
// Set our parameters
SqlParameter paramLogin = new SqlParameter("@username", SqlDbType.VarChar, 100);
paramLogin.Value = email;
SqlParameter paramPassword = new SqlParameter("@password", SqlDbType.VarChar, 20);
paramPassword.Value = password;
Command.CommandType = CommandType.StoredProcedure;
Command.CommandText = "glbl_Login";
Command.Parameters.Add(paramLogin);
Command.Parameters.Add(paramPassword);
Adapter.TableMappings.Add("Table", "Login");
Adapter.SelectCommand = Command;
Adapter.Fill(ds);
if(ds.Tables.Count != 0)
{
DataRow row = ds.Tables[0].Rows[0];
// Get the login id and the login type
nLoginID = Convert.ToInt32(row["Login_ID"].ToString());
nLoginType = Convert.ToInt32(row["Login_Type"].ToString());
}
else
{
nLoginID = 0;
nLoginType = 0;
}
}
}
abstract public class CSql
{
private SqlConnection sqlConnection; // Connection string
private SqlCommand sqlCommand; // Command
private SqlDataAdapter sqlDataAdapter; // Data Adapter
private DataSet sqlDataSet; // Data Set
public CSql()
{
sqlConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
sqlCommand = new SqlCommand();
sqlDataAdapter = new SqlDataAdapter();
sqlDataSet = new DataSet();
sqlCommand.Connection = sqlConnection;
}
/// <summary>
/// Access to our sql command
/// </summary>
protected SqlCommand Command
{
get { return sqlCommand; }
}
/// <summary>
/// Access to our data adapter
/// </summary>
protected SqlDataAdapter Adapter
{
get { return sqlDataAdapter; }
}
/// <summary>
/// Makes sure that everything is clear and ready for a new query
/// </summary>
protected void ResetSql()
{
if(sqlCommand != null)
{
sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
}
if(sqlDataAdapter != null)
sqlDataAdapter = new SqlDataAdapter();
if(sqlDataSet != null)
sqlDataSet = new DataSet();
}
/// <summary>
/// Runs our command and returns the dataset
/// </summary>
/// <returns>the data set</returns>
protected DataSet RunQuery()
{
sqlDataAdapter.SelectCommand = Command;
sqlConnection.Open();
sqlConnection.Close();
sqlDataAdapter.Fill(sqlDataSet);
return sqlDataSet;
}
}
}
|
|
从零开始学ASP.NET(基础篇)
|
作者: 蓝鲸 加入时间: 2004-11-01 文档类型: 来自: 5D多媒体 浏览统计: total: 59 year: 59 quarter: 59 month: 59 week: 21 today: 2
前言
来这儿学习ASP或ASPNET的朋友越来越多了,并且初学的要占了很多,或许是6x%,或许是7x%。当斑竹的主倒楣,本来一个人学得很轻松的,想写就写一点,没事了来凑凑热闹。可现在,发觉一些朋友学ASPNET的路还没找熟,包括自己。 学ASPNET与ASP有区别,这种区别不是语言上的,而是思路上的区别。ASP是纯面向过程的,而ASPNET是完全面向对向的。这种区别使我们在编程的结构设计上要与ASP有很大的不同。 废话少说了,现在我也和各位一起从零开始。我用C#,其实用VB.NET的朋友也应该可以看懂,我会在不同之处说明一些区别的。
第一天
学习目的:
掌握最基本的Label、TextBox、Button控件用法
掌握用StringBuider类连接字符串
理解服务器的环境变量
StringBuilder类: 命名空间是:System.Text。
StringBuilder类是个高效的类,StringBuilder.Append连接字符串的方法是非常快的。用于连接大量的字符串,其速度的优越性就会体现出来。
先举几个例子: 在cs或vb文件的头部加上 [C#]using System.Text; [VB]Imports System.Text
[C#]StringBuilder sbFirst = new StringBuilder(); sbFirst.Append(“这是第一个学ASPNET的例子</br>”); sbFirst.Append( “这个例子太简单</br>”); sbFirst.Append( “连三岁小陔都会做,我早知道了,嘿嘿。”); Response.Write(sbFirst.ToString());
[VB]Dim sbFirst As StringBuilder = New StringBuilder() sbFirst.Append(“这是第一个学ASPNET的例子</br>”) sbFirst.Append( “这个例子太简单</br>”) sbFirst.Append( “连三岁小陔都会做,我早知道了,嘿嘿。”) Response.Write(sbFirst.ToString)
下面就可以做正题了: 先建立一个C#的WEB应用程序工程,这废话我就少说了吧。 放一个Button控件:ID为btnShowVariable 放一个Label控件:ID为labServerVariable
添加Button的单击事件,如下代码 private void btnShowVariable_Click(object sender, System.EventArgs e) { labServerVariables.Text = "";
StringBuilder info = new StringBuilder();
foreach (object objVar in Request.ServerVariables) { info.Append("<span style='font-size:9pt'>"); info.Append(objVar.ToString()); info.Append(" = <font color=blue>"); info.Append(Request.ServerVariables[objVar.ToString()]); info.Append("</font></span><br>"); }
labServerVariables.Text = info.ToString(); }
这样我们就可以这样用 Response.Write(Request.ServerVariables["REMOTE_ADDR"]); // IP地址 Response.Write("<BR>"); Response.Write(Request.ServerVariables["URL"]); // 网页的URL
第二天
学习目的:
掌握文本框的用法
初次接触try…catch…语法
今天内容很轻松,用一个例子,输入年月日,判断输入是否正确
图片如下:
用个文本框,ID分别为txtYear,txtMonth,txtDate; 检验按钮的代码为: private void btnCheck_Click(object sender, System.EventArgs e) { int year, month, date;
// 先把输入的字符转成int类型,如果非数字型, // 会触发错误 try { year = Convert.ToInt32(txtYear.Text); month = Convert.ToInt32(txtMonth.Text); date = Convert.ToInt32(txtDate.Text); } catch { labCheckInfo.Text = "输入的是非数字字符。"; return; }
// 如果第一步检验合格,就把输入的数字转化为日期格式 // 如果不符合日期格式即引发错误 try { DateTime dt = new DateTime(year, month, date); } catch { labCheckInfo.Text = "输入的数字不符合日期格式"; return; }
labCheckInfo.Text = "输入正确"; }
第三天
学习目的:
掌握下拉列表框的用法,并理解AutoPostBack属性;
理解IsPoskBack及用法;
初识DataTable的增加列、行,与下拉列表框绑定的方法。
今天的内容稍多些,而且涉及一些比较常用的,如IsPostBack及DataTable的基本用法。
知识点: IsPostBack:在页面onLoad之间是false值,而当从服务器回传后,该值变为true。当页面中的Button或ImageButton等触发事件,都会把表单回传到服务器,而返回时又会引发onLoad事件。为了节省服务器资源,有些加载中需进行一次,而不需要在回传后多次发生,可以用!IsPoskBack来作为条件,那么页面第一次加载后,以后就不会发生。该属性可以帮助你提高程序的性能。 DataTable:即数据表,.Net 程序中最常用的类,特别是数据库开发中,没有该类的程序是不可想象的。
先做个小程序来练练手,很简单,就一个下拉菜单,取名dlstWeb。在属性的Itmes选项中打开以下对话框,添加各项:
图片如下:
ASPX中的代码为: <asp:DropDownList id="dlstWeb" style="Z-INDEX: 101; LEFT: 32px; POSITION: absolute; TOP: 32px" runat="server" Width="88px" AutoPostBack="True"> <asp:ListItem value="http://www.sina.com.cn">新浪 </asp:ListItem> <asp:ListItem value="http://www.sohu.com">搜狐</asp:ListItem> <asp:ListItem value="http://www.163.com">网易</asp:ListItem> </asp:DropDownList>
在下拉框的SelectedIndexChanged事件中的加入代码: private void dlstWeb_SelectedIndexChanged(object sender, System.EventArgs e) { Response.Write("<script language=javascript>window.open('" +dlstWeb.Selectedvalue + "');</script>"); }
按F5运行,可是我们发现这下拉框选择时什么事也没发生。原来原因是出在下拉框的AutoPostBack属性上,把它设为true后再试试,一切OK了。 下面我们增加些难度,下拉框中的内容很多情况下不是事先固定的,而是要动态添加。这里设计是用一数据表DataTable与之联系起来。
另建一文件,按上添加一下拉框,取名dlstWeb,先设AutoPostPack为false,否则在刚启动而面就触发SelectedIndexChanged事件,弹出窗口就乱飞了。 在onLoad事件中添加代码,注意DataTable用法及IsPoskBack DataTable属于System.Data命名空间,所以如果页面没预添加,可以自行增加这一行。
private void Page_Load(object sender, System.EventArgs e) { // 用IsPostBack判断,只在没有回传时才初始化 // 这样可以防止每次刷新或回传时,都执行一次以下代码 // 可以节省服务器的资源了。 if (!IsPostBack) { DataTable dt = new DataTable(); DataRow dr;
// 在表中增加字段 dt.Columns.Add("WebName", typeof(string)); dt.Columns.Add("WebUrl", typeof(string));
// 表中增加行 dr = dt.NewRow(); dr["WebName"] = "新浪"; dr["WebUrl"] = "http://www.sina.com.cn"; dt.Rows.Add(dr);
dr = dt.NewRow(); dr["WebName"] = "网易"; dr["WebUrl"] = "http://www.163.com"; dt.Rows.Add(dr);
dr = dt.NewRow(); dr["WebName"] = "搜狐"; dr["WebUrl"] = "http://www.sohu.com"; dt.Rows.Add(dr);
// 把表与下拉菜单绑定数据 dlstWeb.DataSource = dt; dlstWeb.DataTextField = "WebName"; dlstWeb.DatavalueField = "WebUrl"; dlstWeb.DataBind();
// 开始时就把下拉菜单的AutoPostBack设为false, // 防止一开始就乱跳出网页来 dlstWeb.AutoPostBack = true; } }
下面的事件与前面一模一样了 private void dlstWeb_SelectedIndexChanged(object sender, System.EventArgs e) { Response.Write("<script language=javascript>window.open('" +dlstWeb.Selectedvalue + "');</script>"); }
小结:今天的一些知识非常重要,为了理解,程序的难度并不高。但这是以后程序设计的基础,所以这些你一定要掌握。
注:VB.NET增加字段代码稍有不同,如下:
// 在表中增加字段 dt.Columns.Add("WebName", GetType(String)) dt.Columns.Add("WebUrl", GetType(String))
其它都差不多了。 学习目的:
学习ADO.NET用法,并如何用DataRearder读取数据
今天练习数据库的最基本用法,如何打开数据库。首先在网站设置文件web.config文件的<configuration>下方加入以下节点:
<configuration>
<appSettings> <add key="数据库1" value="ex01.mdb" /> </appSettings>
……
该节点设置了数据库的路径,这样就可以很方便的调用数据库文件了,调用方法为: Server.MapPath(ConfigurationSettings.AppSettings["数据库1"]) 这是ASP.NET程序的通用方法,以后介绍的SQL SERVER数据库也是在此设置的。 好开始做程序,首先在CS文件的头部加入: using System.Configuration; using System.Data.OleDb; using System.Text; 以下在Page的Load事件中,读取ACCESS数据库,并用表格显示出来: private void Page_Load(object sender, System.EventArgs e) { StringBuilder sbTable = new StringBuilder(); // 用于输出表格的语句
string strConnection = "Provider=Microsoft.Jet.Oledb.4.0;Data Source=" + Server.MapPath(ConfigurationSettings.AppSettings["数据库1"]);
// 连接数据库的语句 OleDbConnection conn = new OleDbConnection(strConnection); // 建立DbCommand对象 OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = "SELECT * FROM Book";
// 打开数据库 conn.Open();
// 用DataReader读取数据 OleDbDataReader dr = cmd.ExecuteReader();
sbTable.Append("<table cellSpacing='0' cellPadding='0' border='1'><tr>"); sbTable.Append("<td>书名</td><td>作者</td><td>单价<td></tr>"); while (dr.Read()) { sbTable.Append("<tr><td>"); sbTable.Append(dr["BookTitle"].ToString()); sbTable.Append("</td><td>"); sbTable.Append(dr["Author"].ToString()); sbTable.Append("</td><td>"); sbTable.Append(dr["UnitPrice"].ToString()); sbTable.Append("</td><tr>"); } sbTable.Append("</tr></table>");
// 记住dr用毕必须关闭,否则会阻塞服务器 dr.Close();
// DbConnection是受托管的,可以不关闭 // 但为良好的编程习惯,应该关闭 conn.Close();
Response.Write(sbTable.ToString());
} 显示结果
学习目的:
掌握ADO.NET打开SQL SERVER数据库的方法。
今天做个非常普通的例子,做一个用户登录框。主要是通过这个练习认识一下SQL SERVER数据库的连接方法。和昨天的例子方法基本相同,很容易掌握的。 先建立SQL SERVER数据库,库名为AspNetABC,并建立一Member新表,建表SQL如下:
CREATE TABLE [dbo].[Member] ( [MemberID] [int] IDENTITY (1, 1) NOT NULL , [MemberName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL , [Password] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL , [Gender] [bit] NOT NULL , [Birthday] [datetime] NULL , [Email] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ) ON [PRIMARY]
与上一例子差不多,在web.config文件中再增加一行: <appSettings> <add key="数据库1" value="ex01.mdb" /> <add key="SqlDatabase1" value="data source=localhost;user id=sa;password=sa;initial catalog=AspNetABC;Connect Timeout=30" /> </appSettings>
在面中添加二个文本框,txtMemberName、txtPassword,并设置txtPassword的TextMode为Password。设置按钮btnLogin。btnLogin的事件代码如下:
private void btnLogin_Click(object sender, System.EventArgs e) { // 先检验输入正确性 if (txtMemberName.Text == String.Empty || txtMemberName.Text.Trim() == "") { Response.Write("<script language=javascript>alert('帐号不能为空')</script>"); return; } if (txtPassword.Text == String.Empty || txtPassword.Text.Trim() == "") { Response.Write("<script language=javascript>alert('没有输入密码')</script>"); return; }
string strConnection = ConfigurationSettings.AppSettings["SqlDatabase1"]; string sqlMember = "SELECT MemberName ,[Password] FROM Member " + " WHERE MemberName = '" + txtMemberName.Text.Trim() + "'" + " AND [Password] = '" + txtPassword.Text.Trim() + "'";
// 连接SqlServer数据库 SqlConnection conn = new SqlConnection(strConnection); // 建立SqlCommand SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = sqlMember; conn.Open(); // 建立DataReader SqlDataReader dr = cmd.ExecuteReader();
// 判断DataReader是否为空记录 if (dr.HasRows) { Response.Write("<script language=javascript>alert('" + txtMemberName.Text + "欢迎你!')</script>"); } else { Response.Write("<script language=javascript>alert('找不到该会员,或密码错误。')</script>"); }
// 千万不要忘记关闭DataReader dr.Close();
conn.Close(); }
好了,一个非常简单的登录框做好了。当然在实际程序中还应加入跳转等,这个就留给你做了。 |
|
什么是web.config
|
从文件名就可以看出是做配置用的,比如配置自定义错误页面,debug,等等 存放连接字符串是最基本的用法, 高级一点可以配置httpmodule,httphandler... 再高级一点可以写一个继承自IConfigurationSectionHandler,添加自定义的配置节... 功能是很强大的 ASP.NET提供了一个丰富而可行的配置系统,以帮助管理人员轻松快速的建立自己的WEB应用环境。ASP.NET提供的是一个层次配置架构,可以帮助WEB应用、站点、机器分别配置自己的扩展配置数据。ASP.NET的配置系统具有以下优点: ●ASP.NET允许配置内容可以和静态内容、动态页面和商业对象放置在同一应用的目录结构下。当管理人员需要安装新的ASP.NET应用时,只需要将应用目录拷贝到新的机器上即可。 ●ASP.NET的配置内容以纯文本方式保存,可以以任意标准的文本编辑器、XML解析器和脚本语言解释、修改配置内容。 ●ASP.NET 提供了扩展配置内容的架构,以支持第三方开发者配置自己的内容。 ●ASP.NET配置文件的更修被系统自动监控,无须管理人员手工干预。
4.2.2配置文件的规则 ASP.NET的配置文件是基于XML格式的纯文本文件,存在于应用的各个目录下,统一命名为“config.web”。它决定了所在目录及其子目录的配置信息,并且子目录下的配置信息覆盖其父目录的配置。 WINNT\Microsoft.NET\Framework\版本号\下的config.web为整个机器的根配置文件,它定义了整个环境下的缺省配置。 缺省情况下,浏览器是不能够直接访问目录下的config.web文件。 在运行状态下,ASP.NET会根据远程URL请求,把访问路径下的各个config.web配置文件叠加,产生一个唯一的配置集合。举例来说,一个对URL: http://localhost/webapp/owndir/test.aspx的访问,ASP.NET会根据以下顺序来决定最终的配置情况: 1..\Microsoft.NET\Framework\v.1.00\config.web (缺省配置文件) 2..\webapp\config.web (应用的配置) 3..\webapp\owndir\config.web (自己的配置) 4.2.3配置文件的语法规则 1)标识 配置内容被置于config.web文件中的标记<configuration>和</configuration>之间。 格式: <configuration> 配置内容 … </configuration>
2)配置段句柄说明 ASP.NET的配置文件架构并未指定任何文件格式或者是支持的配置属性。相反的,它提出了“配置段句柄申明”的概念来支持任意的用户定义配置段。 格式: <configsections> <add name=欲定义配置段名 type=处理的句柄函数 /> </configsections>
3)配置段 具体定义配置的内容,供应用使用。
以下例子定义了一个“httpmodules”配置段,设置了系统http相关的处理模块
<configuration>
<configsections> <add name="httpmodules" type="System.Web.Configuration.HttpModules ConfigurationHandler" /> </configsections>
<httpmodules> <add type="System.Web.SessionState.CookielessSessionModule" /> <add type="System.Web.Caching.OutputCacheModule" /> <add type="System.Web.SessionState.SessionStateModule" /> <add type="System.Web.Security.WindowsAuthenticationModule" /> <add type="System.Web.Security.CookieAuthenticationModule" /> <add type="System.Web.Security.PassportAuthenticationModule" /> <add type="System.Web.Security.CustomAuthenticationModule" /> <add type="System.Web.Security.UrlAuthorizationModule" /> <add type="System.Web.Security.FileAuthorizationModule" /> </httpmodules>
</configuration>
4.2. 4ASP.NET定义的标准配置段 1)httpmodule 段: 定义了应用的http请求的处理模块以及诸如安全、日志之类的应用方式 2)httphandlers 段: 负责映射URLs到IhttpHandler类 3)sessionstat 段: 负责配置http模块的会话状态 4)globalization 段: 配置应用的公用设置 5)compilation 段: 配置ASP.NET的编译环境 6)trace 段: 配置ASP.NET的跟踪服务 7)security 段: ASP.NET的安全配置 8)iisprocessmodel 段: 在IIS上配置ASP.NET的处理模式 9)browercaps 段: 配置浏览器的兼容部件 4.2. 5一个配置读出的例子 1)config.web配置文件
<!--config.web 请放入FormCfg.aspx所在目录--> <configuration> <!--申明一个test配置段--> <configsections> <add name="test" type="System.Web.Configuration.DictionarySectionHandler" /> </configsections>
<test> <!--配置一个键key,其内容为just a configure test-->
<add key="key" value="just a configure test" /> </test>
</configuration>
2)读出其内容
<!--文件名:Application/FormCfg.aspx--> <html> <head> <script language="VB" runat=server> sub page_load(s as object ,e as eventargs) '取出test配置段的key键的值 Dim CfgSection As Hashtable = Context.GetConfig("test") Dim Msg As String = CStr(CfgSection("key"))
lblMsg.text=Msg end sub </script> <title> 配置信息的读取 </title> </head>
<body> <center> config.web中"test"配置段中key的内容为: <asp:label id=lblmsg runat=server /> </center> </body>
</html>
3)运行结果
4.2. 6Config.web配置实例 <configuration> <!--定义用户应用的公用设置,如SQL的sql连接串等等--> <appsettings> </appsettings>
<!--设置浏览器的兼容性部件--> <browsercaps> </browsercaps>
<!--编译环境设置,非调试模式--> <compilation debugmode="false"> <!--缺省编译语言为vb,以后可以不再在Page中定义脚本语言--> <compilers defaultlanguage="vb"> <!--以MSVSA.dll编译.vb为后缀的VB文件--> <compiler language="VB" extension=".vb" type="MSVSA.dll#Microsoft.VB.Compiler"/> </compilers>
<assemblies> <!--加入对System.Data的引用--> <add assembly="System.Data" /> <!--去掉对System.Data的引用--> <remove assembly="System.IO" /> <!--去掉config.web中包含或继承来的引用--> <clear /> </assemblies>
</compilation>
<!--设置应用全局环境--> <!--文件、请求、返回以gb2312编码,以保证浏览器正确显示中文--> <globalization fileencoding="gb2312" requestencoding="gb2312" responseencoding="gb2312"/>
<!--定义用户出错的处理--> <!--出错缺省显示defaultredirect指定的页面,mode为on时,遵循customerrors配置段--> <!--mode为off时,忽略用户出错,mode为remoteonly时,本地才显示真正的出错原因--> <customerrors defaultredirect="AnErrorHasOccured.aspx?ErrNum=-1" mode="remote"> <!--当出错码为500时,显示redirect指定的页面--> <error statuscode="500" redirect="AnErrorHasOccured.aspx?ErrNum=500"/> </customerrors>
<!--指定目录webapp的访问权限--> <location path="webapp” > <!--非授权用户不能进入webapp目录--> <security> <authorization> <deny users="?" /> </authorization> </security> </location>
<!--定义安全属性--> <security> <authorization> <!--角色为Adminstrators和所有的用户访问其指定的资源--> <allow roles="Adminstrators"/> <allow users="*" /> </authorization> </security>
</configuration> |
|
|