|
|
February 25
|
单击开始,指向管理工具,然后单击Internet 信息服务 (IIS)。 展开“* 服务器名称”(其中服务器名称 为该服务器的名称),右键单击Web 站点,然后单击属性。 在Web 站点属性 对话框中,单击目录安全性 选项卡。 在“身份验证和访问控制”下,单击编辑。 单击“启用匿名访问”复选框,将其选中。
备注:“用户名”框中的用户帐户只用于通过 Windows guest 帐户进行匿名访问。
默认情况下,服务器会创建并使用帐户 IUSR_computername。匿名用户帐户密码仅在Windows 中使用;匿名用户不使用用户名和密码登录。 在“已验证身份的访问”下,单击“集成的 Windows 身份验证”复选框,将其选中。 单击确定 两次。 | December 08
Chuandi(传递)是名字空间
WebForm1: <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" Inherits="chuandi.WebForm1" %> <HTML> <HEAD> <title>WebForm1</title> </HEAD> <body> <form id="Form1" method="post" runat="server"> <asp:TextBox id="TextBox1" runat="server"></asp:TextBox> <asp:Button id="Button1" runat="server" Text="传"></asp:Button> </form> </body> </HTML> using System; namespace chuandi { public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.TextBox TextBox1; protected System.Web.UI.WebControls.Button Button1; public string Text1 { get { return this.TextBox1.Text; } } private void Page_Load(object sender, System.EventArgs e) {} override protected void OnInit(EventArgs e) { InitializeComponent(); base.OnInit(e); } private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } private void Button1_Click(object sender, System.EventArgs e) { Server.Transfer("WebForm2.aspx"); } } }
WebForm2: <%@ Page language="c#" Codebehind="WebForm2.aspx.cs" Inherits="chuandi.WebForm2" %> <%@ Reference Page="WebForm1.aspx" %> <HTML> <HEAD> <title>WebForm2</title> </HEAD> <body> <form id="Form1" method="post" runat="server"> <asp:Label id="Label1" runat="server">Label</asp:Label> <asp:Button id="Button1" runat="server" Text="返回"></asp:Button> </form> </body> </HTML> using System; namespace chuandi { public class WebForm2 : System.Web.UI.Page { protected System.Web.UI.WebControls.Button Button1; protected System.Web.UI.WebControls.Label Label1; public chuandi.WebForm1 wf1; private void Page_Load(object sender, System.EventArgs e) { if(!IsPostBack) { wf1=(chuandi.WebForm1)Context.Handler; Label1.Text="上页传来的是:"+wf1.Text1; } } override protected void OnInit(EventArgs e) { InitializeComponent(); base.OnInit(e); } private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } private void Button1_Click(object sender, System.EventArgs e) { Server.Transfer("WebForm1.aspx"); } }
方法一 :
<head> <SCRIPT language="JavaScript"> <!--// function sub() { if(event.keyCode == 13) { LoginForm.BtnLogin.focus(); //LoginForm是form的id,BtnLogin是登录按钮的id LoginForm.BtnLogin.click(); } } //--> </SCRIPT> </HEAD>
如果想在任何时候按回车都提交就在body里加<body onkeydown="sub();">
如果只想在密码框内,就在后台cs里加txtPassword.Attributes.Add("onkeydown","sub();">);就可以了
方法二:
直接在
<asp:textbox ................. onkeypress="javascript:....">
这样加就可以了... 虽然写的时候,出现下划线,看起来有语法错,,但实际用的却是一样的.....
能不在.CS里面写的,就尽量不要在里面写了..修改起来不便,,,,而且性能上也..#%#@%!@#^!#@^....
我平时就是
onkeypress="if(window.event.keycode==13)document.xform.submit();"
September 24
using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging;
namespace using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging;
namespace PickHead { /**//// <summary> /// 一个控制摄像头的类 /// </summary> public class Pick { private const int WM_USER = 0x400; private const int WS_CHILD = 0x40000000; private const int WS_VISIBLE = 0x10000000; private const int WM_CAP_START = WM_USER; private const int WM_CAP_STOP = WM_CAP_START + 68; private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10; private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11; private const int WM_CAP_SAVEDIB = WM_CAP_START + 25; private const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60; private const int WM_CAP_SEQUENCE = WM_CAP_START + 62; private const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20; private const int WM_CAP_SEQUENCE_NOFILE =WM_CAP_START+ 63; private const int WM_CAP_SET_OVERLAY =WM_CAP_START+ 51; private const int WM_CAP_SET_PREVIEW =WM_CAP_START+ 50; private const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START +6; private const int WM_CAP_SET_CALLBACK_ERROR=WM_CAP_START +2; private const int WM_CAP_SET_CALLBACK_STATUSA= WM_CAP_START +3; private const int WM_CAP_SET_CALLBACK_FRAME= WM_CAP_START +5; private const int WM_CAP_SET_SCALE=WM_CAP_START+ 53; private const int WM_CAP_SET_PREVIEWRATE=WM_CAP_START+ 52; private IntPtr hWndC; private bool bStat = false; private IntPtr mControlPtr; private int mWidth; private int mHeight; private int mLeft; private int mTop; /**//// <summary> /// 初始化摄像头 /// </summary> /// <param name="handle">控件的句柄</param> /// <param name="left">开始显示的左边距</param> /// <param name="top">开始显示的上边距</param> /// <param name="width">要显示的宽度</param> /// <param name="height">要显示的长度</param> public Pick(IntPtr handle, int left, int top, int width,int height) { mControlPtr = handle; mWidth = width; mHeight = height; mLeft = left; mTop = top; }
[DllImport("avicap32.dll")] private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID); [DllImport("avicap32.dll")] private static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize ); [DllImport("User32.dll")] private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, long lParam);
/**//// <summary> /// 开始显示图像 /// </summary> public void Start() { if (bStat) return; bStat = true; byte[] lpszName = new byte[100]; hWndC = capCreateCaptureWindowA(lpszName,WS_CHILD|WS_VISIBLE ,mLeft,mTop,mWidth,mHeight,mControlPtr,0);
if (hWndC.ToInt32() != 0) { SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0); SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0); SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0); SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0); SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0); SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0); SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0); }
return;
}
/**//// <summary> /// 停止显示 /**//// </summary> public void Stop() { SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0); bStat = false; }
/**//// <summary> /// 抓图 /// </summary> /// <param name="path">要保存bmp文件的路径</param> public void GrabImage(string path) { IntPtr hBmp = Marshal.StringToHGlobalAnsi(path); SendMessage(hWndC,WM_CAP_SAVEDIB,0,hBmp.ToInt64());
}
/**//// <summary> /// 录像 /// </summary> /// <param name="path">要保存avi文件的路径</param> public void Kinescope(string path) { IntPtr hBmp = Marshal.StringToHGlobalAnsi(path); SendMessage(hWndC,WM_CAP_FILE_SET_CAPTURE_FILEA,0,hBmp.ToInt64()); SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0); }
/**//// <summary> /// 停止录像 /// </summary> public void StopKinescope() { SendMessage(hWndC, WM_CAP_STOP, 0, 0); }
} }
September 19 这是系统要求:要安装Asp.net运行环境,请按顺序安装以下软件: IE6.0 sp1 中文版下载地址: http://download.microsoft.com/download/ie6sp1/finrel/6_sp1/W98NT42KMeXP/CN/ie6setup.exe MDAC2.8 中文版下载地址: http://download.microsoft.com/download/8/b/6/8b6198c0-fe96-4811-9d81-d5c76dd5fea8/MDAC_TYP.EXE .Net Framework 1.1 可再发行组件包下载地址: http://download.microsoft.com/download/7/b/9/7b90644d-1af0-42b9-b76d-a2770319a568/dotnetfx.exe .Net SDK 1.1 中文正式版下载地址: http://download.microsoft.com/download/0/f/e/0fecf85c-fb50-4ca9-adf2-c4be7ec9b454/setup.exe .Net Framework 1.1 sp1 for win2000 http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=A8F5654F-088E-40B2-BBDB-A83353618B38 .Net Framework 1.1 sp1 for win2003 http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=AE7EDEF7-2CB7-4864-8623-A1038563DF23 September 07 .NET的应用程序配置文件,使用的是XML格式。相对INI文件来说,它的功能要强上不少,而且具有很强的可扩展性。它的缺点是不能直接进行写操作,也就是说,不能直接在程序中修改配置文件的数据(当然不是指不能,不过不是本文讨论的范围)。本文主要目的是探讨如何扩展配置文件,并在其加入各种自定义配置信息。
3. 自定义配置结构 (使用IConfigurationSectionHandler) 假设有以下的配置信息,其在MyInfo可以重复许多次,那么应如何读取配置呢?这时就要使用自定义的配置程序了。
<myConfigs>
<myInfo Area="Fuzhou" Device="Printer" Customer="Muf" />
<myInfo Area="Shanghai" Device="Mobile" Customer="Liny" />
</myConfig>

访问代码如下:
Hashtable cfgTable = (Hashtable)ConfigurationSettings.GetConfig( "myConfigs" );

Debug.Assert( cfgTable.Count == 2);
Hashtable cfgFuzhou = (Hashtable)cfgTable["Fuzhou"];
Hashtable cfgShanghai = (Hashtable)cfgTable["Shanghai"];
Debug.Assert( cfgFuzhou["Device"] == "Printer" );
Debug.Assert( cfgShanghai["Device"] == "Mobile" );
Debug.Assert( cfgFuzhou["Customer"] == "Muf" );
Debug.Assert( cfgShanghai["Customer"] == "Liny" );

foreach(Hashtable cfg in cfgTable.Values)
  {
Console.WriteLine("Area={0} Device={1} Customer={2}", cfg["Area"], cfg["Device"], cfg["Customer"]);
}


为了能使用上面的访问代码来访问配置结构,我们需要生成一个特定的配置读取类(ConfigurationSectionHandler),例子很简单,就不多做说明了:
public class MyInfoSectionHandler: IConfigurationSectionHandler
  {
public object Create(object parent, object configContext, System.Xml.XmlNode section)
 {
Hashtable config = new Hashtable();
foreach(XmlNode node in section.ChildNodes)
 {
if(node.Name != "myInfo")
throw new System.Configuration.ConfigurationException("不可识别的配置项", node);

Hashtable item = new Hashtable();
foreach(XmlAttribute attr in node.Attributes)
 {
switch(attr.Name)
 {
case "Area":
case "Device":
case "Customer":
item.Add(attr.Name, attr.Value);
break;
default:
throw new System.Configuration.ConfigurationException("不可识别的配置属性", attr);
}
}
config.Add(item["Area"], item);
}
return config;
}
}


然后,我们再定义配置说明。其中,myNamespace.MyInfoSectionHandler 是MyInfoSectionHandler类的带名字空间的完整名称;myApp 则是定义MyInfoSectionHandler类的程序集不带扩展名的名字(如myApp.dll或myApp.exe):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 以下是自定义配置的声明 -->
<configSections>
<section name="myConfig" type="myNamespace.MyInfoSectionHandler, myApp" />
</configSections>
<myConfigs>
<myInfo Area="Fuzhou" Device="Printer" Customer="Muf" />
<myInfo Area="Shanghai" Device="Mobile" Customer="Liny" />
</myConfig>
</configuration>

根据上面的例子,我们可以使用IConfigurationSectionHandler来实现任意的配置文件结构。
.NET的应用程序配置文件,使用的是XML格式。相对INI文件来说,它的功能要强上不少,而且具有很强的可扩展性。它的缺点是不能直接进行写操作,也就是说,不能直接在程序中修改配置文件的数据(当然不是指不能,不过不是本文讨论的范围)。本文主要目的是探讨如何扩展配置文件,并在其加入各种自定义配置信息。 1. 使用<appSettings> 简单的配置信息,可以直接放入<appSettings>标记中。如:
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="LogFile" value="d:\log\debug.log"/>
</appSettings>
</configuration>

相应访问代码如下:
string fileName = System.Configuration.ConfigurationSettings.AppSettings.Get("LogFile");

2. 自定义配置节(section)名称 比如,我们要使用下面的配置结构,将配置信息归类分组:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 需要在此处加入自定义配置声明 -->
<!-- 以下是自定义配置的内容 -->
<myConfig>
<myDictionary>
<add key="Area" value="Fuzhou"/>
<add key="Device" value="Printer"/>
<add key="Customer" value="Muf"/>
</myDictionary>
<myNameValue>
<add key="Area" value="Fuzhou"/>
<add key="Device" value="Printer"/>
<add key="Customer" value="Muf"/>
</myNameValue>
<myInfo
Area="Fuzhou" Device="Printer" Customer="Muf"
/>
</myConfig>
</configuration>

但是光这样子说明是不行的。没有声明,是不能使用自定义的配置段。我们必须要在配置文件前面加入声明:
<!-- 以下是自定义配置的声明 -->
<configSections>
<sectionGroup name="myConfig">
<section name="myDictionary"
type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="myNameValue"
type="System.Configuration.DictionarySectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="myInfo"
type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</sectionGroup>
</configSections>

声明和配置的关系,示意图如下: 由图上可以看出,NameValueSectionHandler和DictionarySectionHandler在定义配置文件的内容形式上是一样的,都是用<add>来设置内容的。只是返回到C#中的类不太一样,可以参考下面的代码示例。 另外,如果不关心Handler类的版本等信息,可以直接省略。如NameValueSectionHandler可以直接如下声明:
<section name="myDictionary" type="System.Configuration.NameValueSectionHandler, System" />

把上面的<configSections>声明段放入配置文件中,我们的配置结构就可以正常使用了。声明中,<sectionGroup>用来定义不含配置数据的节的名称。<section>用来定义含有自定义配置数据的节的名称。<section type>用来指定定义配置数据的类型。.NET已经定义了3种配置类型: a. NameValueSectionHandler 相应访问代码如下:
NameValueCollection myNameValue= (NameValueCollection)System.Configuration.ConfigurationSettings.AppSettings.Get(@"myConfig\myNameValue");
string Area = myNameValue["Area"];
string Device= myNameValue["Device"];
string Customer = myNameValue["Customer "];

b. DictionarySectionHandler 相应访问代码如下:
Hashtable myNameValue= (Hashtable)System.Configuration.ConfigurationSettings.AppSettings.Get(@"myConfig\myDictionary");
string Area = myNameValue["Area"];
string Device= myNameValue["Device"];
string Customer = myNameValue["Customer "];

c. SingleTagSectionHandler 相应访问代码如下:
Hashtable myNameValue= (Hashtable)System.Configuration.ConfigurationSettings.AppSettings.Get(@"myConfig\myInfo");
string Area = myNameValue["Area"];
string Device= myNameValue["Device"];
string Customer = myNameValue["Customer "];

这三种类型的详细信息,可以参考 MSDN 文档。同时.NET 还定义了IgnoreSectionHandler类型,为 System.Configuration 之外的系统所读取和处理的配置节提供节处理程序定义。 除此之外,.NET提供了IConfigurationSectionHandler接口,这样我们还可以自行进行扩展,以设计出我们自已的配置形式。
(待续) September 02
一、性能参数: 1、 吞吐量 2、 响应时间 3、 执行时间 4、 可伸缩性 二、性能因素: 1、ASPX执行环境 2、编写代码逻辑
三、提高性能的方法: 1、 避免不必要的操作.例如:在Page_Load中使用IsPostBack; 2、 尽量减少使用服务器端控件 3、 关闭不必要的页面Session和控件的ViewState <%@Page EnableSessionState =”false”%> 4、 禁用VB和JSP动态类型 <%@Page Language=”VB” Strict=”true”%> 5、 使用存储过程 6、 使用DateReader代替DataSet 7、 关闭ASP.Net的Debug模式 8、 使用ASP.Net的Output Cache缓冲 <%@ OutputCache Duration=60 VaryByParam=”None” %> <%@ OutputCache Duration=60 VaryByParam=”TextBox1,TextBox2” %> 说明: Duration是设置Cache的过期时间; VarByParam是设置是否根据参数而变化,None时所有参数使用同一Cache,设置TextBox1时则根据TextBox1的不同值分别缓存;当有多个参数时则要组合缓存; 9、 不要使用Exception控制程序流程 try
{ result=100/num; } catch(Exception e)
{ result=0; } if(num!=0) result = 100/num; else result=0; 四、缓冲分类: 1页面缓冲:根据VarByParam来进行不同的缓冲处理。 2片段缓冲:在页面控件中使用页面缓冲,当一个页面里多次使用同一个页面控件时,需要根据VarByControl来进行不同的缓冲处理。 3数据缓冲:Cache(范围是和Application一样,所有用户) Cache.Insert(“MyData”,Source,null,new CacheDependency(Server.MapPath(“authors.xml”))); Cache.Insert(“MyData”,Source,null,DateTime.Now.AddHours(1),TimeSpan.Zero); Cache.Insert(“MyData”,Source,null,DateTime.MaxValue,TimeSpan.FromMinutes(20)); 环境:Microsoft .NET Framework SDK v1.1 OS:Windows Server 2003 中文版 ASP.Net生成静态HTML页 在Asp中实现的生成静态页用到的FileSystemObject对象! 在.Net中涉及此类操作的是System.IO 以下是程序代码 注:此代码非原创!参考别人代码 Code:
//生成HTML页 public static bool WriteFile(string strText,string strContent,string strAuthor) { string path = HttpContext.Current.Server.MapPath("/news/"); Encoding code = Encoding.GetEncoding("gb2312"); // 读取模板文件 string temp = HttpContext.Current.Server.MapPath("/news/text.html"); StreamReader sr=null; StreamWriter sw=null; string str=""; try { sr = new StreamReader(temp, code); str = sr.ReadToEnd(); // 读取文件 } catch(Exception exp) { HttpContext.Current.Response.Write(exp.Message); HttpContext.Current.Response.End(); sr.Close(); }
string htmlfilename=DateTime.Now.ToString("yyyyMMddHHmmss")+".html"; // 替换内容 // 这时,模板文件已经读入到名称为str的变量中了 str =str.Replace("ShowArticle",strText); //模板页中的ShowArticle str = str.Replace("biaoti",strText); str = str.Replace("content",strContent); str = str.Replace("author",strAuthor); // 写文件 try { sw = new StreamWriter(path + htmlfilename , false, code); sw.Write(str); sw.Flush(); } catch(Exception ex) { HttpContext.Current.Response.Write(ex.Message); HttpContext.Current.Response.End(); } finally { sw.Close(); } return true; | 此函数放在Conn.CS基类中了 在添加新闻的代码中引用 注:工程名为Hover
if(Hover.Conn.WriteFilethis.Title.Text.ToString),this.Content.Text.ToString),this.Author.Text.ToString))) { Response.Write("添加成功"); } else { Response.Write("生成HTML出错!"); } | 模板页Text.html代码 Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>ShowArticle</title> <body> biaoti <br> content<br> author </body> </HTML> biaoti <br> content<br> author </body> </HTML> | August 23 /// <summary> /// 生成水印,可按左上、左下、右上、右下、居中、透明度生成文件,只对jpeg或jpg格式有效! /// </summary> /// <param name="sourceFile">底图</param> /// <param name="waterMarkFile">水印图</param> /// <param name="saveFile">要保存的文件</param> /// <param name="local">位置:左上(1)、左下(2)、右上(3)、右下(4)、居中(5)</param> /// <param name="alpha">透明度(1-100)</param> /// <returns>bool,是否成功</returns> public static bool MakeWaterImage(string sourceFile,string waterMarkFile,string saveFile,int local,int alpha) { bool result; if( !File.Exists(sourceFile) || !File.Exists(waterMarkFile)) //如果源图或水印图不存在 return false; FileInfo fi = new FileInfo(sourceFile); //判断文件类型是否合法 if(fi.Extension.ToLower()!=".jpg" & fi.Extension.ToLower()!=".jpeg") return false; try { //原图 Bitmap sImage = new Bitmap(sourceFile); int sWidth = sImage.Width; int sHeight = sImage.Height; //水印图 Bitmap wImage = new Bitmap(waterMarkFile); int wWidth = wImage.Width; int wHeight = wImage.Height;
//make Graphics. Graphics g = Graphics.FromImage(sImage); int x; //临时变量 int y; //监时变量 int x1 = 0; //原图和水印图的宽度差,即开始绘图的X位置 int y1 = 0; //原图和水印图的高度差,即开始绘图的Y位置 int w = 0; //生成的水印图的宽度,即结束绘图的X位置 int h = 0; //生成的水印图的高度,即结束绘图的Y位置 int al; //alpha int rl; //Red int gl; //Green int bl; //Blue
//校验透明度 if(alpha < 1 || alpha > 100) al = 80; else al = alpha; if(sWidth > wWidth & sHeight > wHeight) //如果源图比水印图大 { switch(local) { case 1: //左上 x1 = 0; y1 = 0; July 02 CallByName:函数在运行时用来获取属性,设置属性或调用方法。 例子: Imports Microsoft.VisualBasic.CallType'该方法所在的运行库 Sub TestCallByName1() ' 设置对象的属性值 CallByName(TextBox1, "Text", CallType.Set, "New Text" )' 获取对象的属性值 MsgBox( CallByName(TextBox1, "Text", CallType.Get )) ' 调用对象的方法 CallByName(TextBox1, "Hide", CallType.Method )End Sub DirectCast:关键字引入类型转换操作。其使用方法和Ctype一样 例子: Dim Q As Object = 2.37 Dim I As Integer = CType(Q, Integer) ' 成功,原因:只要定义了表达式与类型之间的有效转换,Ctype就会成功。 Dim J As Integer = DirectCast(Q, Integer ) '失败,原因: DirectCast 则要求对象变量的运行时类型与指定的类型相同。如果参数类型不匹配, DirectCast 会引发 InvalidCastException 错误 如果类型匹配,DirectCast比Ctype在运行时的性能更好。 HashTable:表示键/值对的集合,这些键/值对根据键的哈希代码进行组织,该类对内存的消耗较大。 HybridDictionary:在集合较小时,使用ListDictionary 来实现 IDictionary,然后当集合变大时,切换到HashTable。
要求业务验证的情况大致可以分为3类
1、某一个值本身需要验证
2、仅当另外一个值出现时,某一个值需要验证
3、仅当另外一个数据集里面包含的某一个数据满足某个条件时,某一个值需要验证
业务逻辑的验证要求验证方法集中处理,尽量避免在整个系统中对同一个值存在多个业务验证。
验证:返回true或false的方法,该方法必须包含两个参数,1、验证数据本身;2、验证数据的处理方法
验证中必须理解的技术:
delegate:表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。要求被引用方法的参数和返回值和delegate声明的方法一致的类。该类的方法就可以被delegate类型调用。
一下为两个例子:
例子一:
Public Class SamplesDelegate
' 为一个方法申明委托 Delegate Function myMethodDelegate(myInt As Integer) As [String]
' 申明委托能够指向的方法 Public Class mySampleClass
' 定义需要实例化的方法. Public Function myStringMethod(myInt As Integer) As [String] If myInt > 0 Then Return "positive" End If If myInt < 0 Then Return "negative" End If Return "zero" End Function 'myStringMethod
' 定义静态方法 Public Shared Function mySignMethod(myInt As Integer) As [String] If myInt > 0 Then Return "+" End If If myInt < 0 Then Return "-" End If Return "" End Function 'mySignMethod End Class 'mySampleClass
Public Shared Sub Main()
' 为每个方法申明一个委托myD1,myD2. Dim mySC As New mySampleClass() Dim myD1 As New myMethodDelegate(AddressOf mySC.myStringMethod)'引用实例方法 Dim myD2 As New myMethodDelegate(AddressOf mySampleClass.mySignMethod)'引用静态方法
' 通过委托调用. Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 5, myD1(5), myD2(5)) Console.WriteLine("{0} is {1}; use the sign ""{2}"".", - 3, myD1(- 3), myD2(- 3)) Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 0, myD1(0), myD2(0))
End Sub 'Main
End Class 'SamplesDelegate
例子二: Public Class SortClass '声明委托
Delegate Function Compare(ByVal x As Integer, _
ByVal y As Integer) As Boolean
'申明委托指向的实例方法 Function CompareValues(ByVal X As Integer, _
ByVal Y As Integer) As Boolean
If X > Y Then
CompareValues = True
Else
CompareValues = False
End If
End Function
'声明使用委托的方法 Sub SelectionSort(ByVal IsGreaterThan As Compare, _
ByVal IntArray() As Integer)
Dim MaxVal As Integer
Dim MaxIndex As Integer
Dim i, j As Integer
' Step through the elements in the array starting with the
' last element in the array.
For i = UBound(IntArray) To 1 Step -1
MaxVal = IntArray(i)
MaxIndex = i
For j = 1 To i
' 使用委托.
If IsGreaterThan.Invoke(IntArray(j), MaxVal) Then
MaxVal = IntArray(j)
MaxIndex = j
End If
Next j
' 使用委托.
If IsGreaterThan.Invoke(i, MaxIndex) Then
IntArray(MaxIndex) = IntArray(i)
IntArray(i) = MaxVal
End If
Next i
End Sub
End Class
Class Class1
Sub SortArray() '声明被委托指向的实例化对象
Dim Sort As New SortClass()
Dim arr1() As Integer = {1, 5, 3, 2, 7, 22, 5, 54, 12}
Sort.SelectionSort(AddressOf Sort.CompareValues, arr1)
MsgBox("Array sorted.")
End Sub
End Class
'测试 Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim c As New Class1()
c.SortArray()
End Sub
问题
在写Internet应用程序的时候,常常需要处理用户登录的情况。一般来说,对于这种情况,我们是使用程序来模拟用户在Web页面上填写用户名、密码并提交的过程。当用户在Web页面上输入了用户名、密码并提交之后,实际上是触发了一个POST请求,在这个请求中包含有用户名、密码等信息。因此,我们只要在程序中将相关信息封装成一条POST请求,并将它发送给Web Server,基本上就能实现登录了。以MFC为例,下面的这段代码模拟了一个登录过程:
CString strHeaders = _T("Content-Type: application/x-www-form-urlencoded");
// name = "sam", password = "123", action = "submit"
CString strFormData = _T("name=sam&password=123&action=submit");
CInternetSession session;
CHttpConnection* pConnection =
session.GetHttpConnection(_T("ServerNameHere"));
CHttpFile* pFile =
pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,
_T("FormActionHere"));
BOOL result = pFile->SendRequest(strHeaders,
(LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());
这个方法对于Asp页面很有效,但对于Asp.Net页面,有时却不起作用,这是为什么呢?
研究
为了搞清出Asp.Net页面在处理登录时与Asp页面有何区别,我们需要使用Sniffer工具来跟踪Web服务器与浏览器之间的通讯。经过跟踪会发现,Asp.Net页面在用户提交登录信息之后,仍然是使用POST请求将相关信息发送给服务器。所不同的是,处理用户名、密码等信息之外还多了一个__VIEWSTATE。如果在上面代码中的strFormData中加上一个通过Sniffer得到的__VIEWSTATE的话,就能够成功模拟出整个登录过程了。接下来的问题就是,我们应该如何获得这个__VIEWSTATE呢?
我们知道,Asp.Net页面有一个ViewState属性,Asp.Net用它来保存页面的状态信息,以便在页面提交失败时,能够恢复页面的状态。它是通过页面中的一个隐藏的域来定义的,如果通过浏览器来View Source的话,可以看到它是如下的一行代码:
<input type="hidden" name="__VIEWSTATE" value="dDwtMTI4ODQyNDA1Ozs+lhWR3hjHp3u/496m+cT53Ofw4P4=" />
它的value值正是我们所需要的,我们只要从登录页面中解析出这个__VIEWSTATE的value,我们的问题就能够得到解决了。
解决
仔细看一下,ViewState的值是经过编码的,先不管它,直接将它从页面中取出,和登录信息一起组成POST请求,发送给Server,结果如何呢?失败了L。对比一下Sniffer的结果和页面中ViewState的value,我们会发现,它们之间还是有些许不同的。原来,页面源码中的ViewState值是经过Base64编码的,而当它被发送给Web Server时,为了保证传输的正确,浏览器会将它转换成URL编码,当Web Server接收到ViewState之后,当然会先将它从URL编码解码为Base64编码再交给Asp.Net处理。看来我们需要将ViewState的值在进行一边URL编码处理,这样就能够成功模拟整个登录过程了J。
参考
1. HOWTO: Simulate a Form POST Request Using WinInet,微软的KB文章,描述了模拟POST请求的实现。
2. ASP .NET Maintaining the ViewState,ViewState的入门知识。
3. ViewState: All You Wanted to Know,关于ViewState的深入讨论。
4. ViewState Parser,想看看解码后的ViewState是什么样子吗?试试这个Parser。
在.NET的所有技术中,最具争议的恐怕是垃圾收集(Garbage Collection,GC)了。作为.NET框架中一个重要的部分,托管堆和垃圾收集机制对我们中的大部分人来说是陌生的概念。在这篇文章中将要讨论托管堆,和你将从中得到怎样的好处。
为什么要托管堆?
.NET框架包含一个托管堆,所有的.NET语言在分配引用类型对象时都要使用它。像值类型这样的轻量级对象始终分配在栈中,但是所有的类实例和数组都被生成在一个内存池中,这个内存池就是托管堆。
垃圾收集器的基本算法很简单:
● 将所有的托管内存标记为垃圾
● 寻找正被使用的内存块,并将他们标记为有效
● 释放所有没有被使用的内存块
● 整理堆以减少碎片
托管堆优化
看上去似乎很简单,但是垃圾收集器实际采用的步骤和堆管理系统的其他部分并非微不足道,其中常常涉及为提高性能而作的优化设计。举例来说,垃圾收集遍历整个内存池具有很高的开销。然而,研究表明大部分在托管堆上分配的对象只有很短的生存期,因此堆被分成三个段,称作generations。新分配的对象被放在generation 0中。这个generation是最先被回收的——在这个generation中最有可能找到不再使用的内存,由于它的尺寸很小(小到足以放进处理器的L2 cache中),因此在它里面的回收将是最快和最高效的。
托管堆的另外一种优化操作与locality of reference规则有关。该规则表明,一起分配的对象经常被一起使用。如果对象们在堆中位置很紧凑的话,高速缓存的性能将会得到提高。由于托管堆的天性,对象们总是被分配在连续的地址上,托管堆总是保持紧凑,结果使得对象们始终彼此靠近,永远不会分得很远。这一点与标准堆提供的非托管代码形成了鲜明的对比,在标准堆中,堆很容易变成碎片,而且一起分配的对象经常分得很远。
还有一种优化是与大对象有关的。通常,大对象具有很长的生存期。当一个大对象在.NET托管堆中产生时,它被分配在堆的一个特殊部分中,这部分堆永远不会被整理。因为移动大对象所带来的开销超过了整理这部分堆所能提高的性能。
关于外部资源(External Resources)的问题
垃圾收集器能够有效地管理从托管堆中释放的资源,但是资源回收操作只有在内存紧张而触发一个回收动作时才执行。那么,类是怎样来管理像数据库连接或者窗口句柄这样有限的资源的呢?等待,直到垃圾回收被触发之后再清理数据库连接或者文件句柄并不是一个好方法,这会严重降低系统的性能。
所有拥有外部资源的类,在这些资源已经不再用到的时候,都应当执行Close或者Dispose方法。从Beta2(译注:本文中所有的Beta2均是指.NET Framework Beta2,不再特别注明)开始,Dispose模式通过IDisposable接口来实现。这将在本文的后续部分讨论。
需要清理外部资源的类还应当实现一个终止操作(finalizer)。在C#中,创建终止操作的首选方式是在析构函数中实现,而在Framework层,终止操作的实现则是通过重载System.Object.Finalize 方法。以下两种实现终止操作的方法是等效的:
~OverdueBookLocator()
{
Dispose(false);
}
和:
public void Finalize()
{
base.Finalize();
Dispose(false);
}
在C#中,同时在Finalize方法和析构函数实现终止操作将会导致错误的产生。
除非你有足够的理由,否则你不应该创建析构函数或者Finalize方法。终止操作会降低系统的性能,并且增加执行期的内存开销。同时,由于终止操作被执行的方式,你并不能保证何时一个终止操作会被执行。
内存分配和垃圾回收的细节
对GC有了一个总体印象之后,让我们来讨论关于托管堆中的分配与回收工作的细节。托管堆看起来与我们已经熟悉的C++编程中的传统的堆一点都不像。在传统的堆中,数据结构习惯于使用大块的空闲内存。在其中查找特定大小的内存块是一件很耗时的工作,尤其是当内存中充满碎片的时候。与此不同,在托管堆中,内存被组制成连续的数组,指针总是巡着已经被使用的内存和未被使用的内存之间的边界移动。当内存被分配的时候,指针只是简单地递增——由此而来的一个好处是,分配操作的效率得到了很大的提升。
当对象被分配的时候,它们一开始被放在generation 0中。当generation 0的大小快要达到它的上限的时候,一个只在generation 0中执行的回收操作被触发。由于generation 0的大小很小,因此这将是一个非常快的GC过程。这个GC过程的结果是将generation 0彻底的刷新了一遍。不再使用的对象被释放,确实正被使用的对象被整理并移入generation 1中。
当generation 1的大小随着从generation 0中移入的对象数量的增加而接近它的上限的时候,一个回收动作被触发来在generation 0和generation 1中执行GC过程。如同在generation 0中一样,不再使用的对象被释放,正在被使用的对象被整理并移入下一个generation中。大部分GC过程的主要目标是generation 0,因为在generation 0中最有可能存在大量的已不再使用的临时对象。对generation 2的回收过程具有很高的开销,并且此过程只有在generation 0和generation 1的GC过程不能释放足够的内存时才会被触发。如果对generation 2的GC过程仍然不能释放足够的内存,那么系统就会抛出OutOfMemoryException异常
带有终止操作的对象的垃圾收集过程要稍微复杂一些。当一个带有终止操作的对象被标记为垃圾时,它并不会被立即释放。相反,它会被放置在一个终止队列(finalization queue)中,此队列为这个对象建立一个引用,来避免这个对象被回收。后台线程为队列中的每个对象执行它们各自的终止操作,并且将已经执行过终止操作的对象从终止队列中删除。只有那些已经执行过终止操作的对象才会在下一次垃圾回收过程中被从内存中删除。这样做的一个后果是,等待被终止的对象有可能在它被清除之前,被移入更高一级的generation中,从而增加它被清除的延迟时间。
需要执行终止操作的对象应当实现IDisposable接口,以便客户程序通过此接口快速执行终止动作。IDisposable接口包含一个方法——Dispose。这个被Beta2引入的接口,采用一种在Beta2之前就已经被广泛使用的模式实现。从本质上讲,一个需要终止操作的对象暴露出Dispose方法。这个方法被用来释放外部资源并抑制终止操作,就象下面这个程序片断所演示的那样:
public class OverdueBookLocator: IDisposable
{
~OverdueBookLocator()
{
InternalDispose(false);
}
public void Dispose()
{
InternalDispose(true);
}
protected void InternalDispose(bool disposing)
{
if(disposing)
{
GC.SuppressFinalize(this);
// Dispose of managed objects if disposing.
}
// free external resources here
} } June 10 主 题: 在页面中嵌入播放器,点击DataList的播放按钮后,在页面中的播放器播放,怎样做? 作 者: zsanhong (老狼) 等 级: 信 誉 值: 100 所属社区: .NET技术 ASP.NET 问题点数: 50 回复次数: 13 发表时间: 2004-10-25 10:54:50 在页面中嵌入播放器,数据是指向的文件路径,是动态从数据库中取出的, 点击DataList的播放按钮后,在页面中的播放器播放,怎样做?没有一点头绪, 请提供类似的代码或实际的网页做参考.谢谢 回复人: zsanhong(老狼) ( ) 信誉:100 2004-10-25 10:57:29 得分: 0 up Top 回复人: xiaohutushen(xiaohutushen) ( ) 信誉:100 2004-10-25 10:58:35 得分: 1 up Top 回复人: snowpine999([彼岸烟花]) ( ) 信誉:98 2004-10-25 11:01:08 得分: 1 up Top 回复人: yichuan1982(往者不可谏,来者犹可追) ( ) 信誉:100 2004-10-25 11:05:21 得分: 1 关注中,我后面可能要用到 兄弟,解决了能否把大体的解决方案发送到我邮箱,万分感谢: yichuan1982@etang.com Top 回复人: zsanhong(老狼) ( ) 信誉:100 2004-10-25 11:14:00 得分: 0 怎么这个问题大家都没做过吗? Top 回复人: zsanhong(老狼) ( ) 信誉:100 2004-10-25 11:27:41 得分: 0 在asp中有类似的网页可参考吗? Top 回复人: joseph0311(EohoSoft) ( ) 信誉:100 2004-10-25 12:07:25 得分: 25 在web窗体中舔加一个windows media player控件和一个LinkButton控件: HTML编码中这样写: <OBJECT style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px" classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" VIEWASTEXT> <PARAM NAME="URL" VALUE="<%# FileName%>"> <PARAM NAME="rate" VALUE="1"> <PARAM NAME="balance" VALUE="0"> <PARAM NAME="currentPosition" VALUE="0"> <PARAM NAME="defaultFrame" VALUE=""> <PARAM NAME="playCount" VALUE="1"> <PARAM NAME="autoStart" VALUE="-1"> <PARAM NAME="currentMarker" VALUE="0"> <PARAM NAME="invokeURLs" VALUE="-1"> <PARAM NAME="baseURL" VALUE=""> <PARAM NAME="volume" VALUE="50"> <PARAM NAME="mute" VALUE="0"> <PARAM NAME="uiMode" VALUE="full"> <PARAM NAME="stretchToFit" VALUE="0"> <PARAM NAME="windowlessVideo" VALUE="0"> <PARAM NAME="enabled" VALUE="-1"> <PARAM NAME="enableContextMenu" VALUE="-1"> <PARAM NAME="fullScreen" VALUE="0"> <PARAM NAME="SAMIStyle" VALUE=""> <PARAM NAME="SAMILang" VALUE=""> <PARAM NAME="SAMIFilename" VALUE=""> <PARAM NAME="captioningID" VALUE=""> <PARAM NAME="enableErrorDialogs" VALUE="0"> <PARAM NAME="_cx" VALUE="6482"> <PARAM NAME="_cy" VALUE="6350"> </OBJECT> <asp:LinkButton id="LinkButton1" style="Z-INDEX: 102; LEFT: 288px; POSITION: absolute; TOP: 40px" runat="server">新文件</asp:LinkButton> -------------------------------------------------------------------------- 后台编码文件中这样写: public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.LinkButton LinkButton1; private string _FileName; public string FileName { get { return _FileName; } } private void Page_Load(object sender, System.EventArgs e) { _FileName = @"G:\Joseph Movie\123.wmv"; //起始播放地址 DataBind(); } private void LinkButton1_Click(object sender, System.EventArgs e) { _FileName = @"G:\Joseph Movie\246.wmv"; //换新地址 } } Top 回复人: joseph0311(EohoSoft) ( ) 信誉:100 2004-10-25 12:33:04 得分: 2 补充: private void LinkButton1_Click(object sender, System.EventArgs e) { _FileName = @"G:\Joseph Movie\246.wmv"; //换新地址 } 改为: private void LinkButton1_Click(object sender, System.EventArgs e) { _FileName = @"G:\Joseph Movie\246.wmv"; //换新地址 DataBind(); } Top 回复人: zsanhong(老狼) ( ) 信誉:100 2004-10-25 12:36:04 得分: 0 请问windows media player控件在微软的开发工具2003.net中有吗?还是要自己加入? 我把你的代码copy了一份,不能播放.能不能把你页面的代码贴全一点.谢谢! Top 回复人: lingwu05() ( ) 信誉:100 2004-10-25 14:02:08 得分: 0 up Top 回复人: cocoguo(周周) ( ) 信誉:100 2004-10-25 16:14:30 得分: 20 工具--添加/移除工具箱选com组件找到windows media play加入就可以加到工具箱里了, 从工具箱上把这个控件拖到页面后进入.aspx文件修改为<PARAM NAME="URL" VALUE='<%=Session["fileName"]%>'> 在命令中修改Session["fileName"]="k:\\abc.mpg"; 就可以了 Top 回复人: zsanhong(老狼) ( ) 信誉:100 2004-10-25 16:33:43 得分: 0 谢谢各位,问题解决! Top 回复人: joseph0311(EohoSoft) ( ) 信誉:100 2004-10-25 19:24:43 得分: 0 感谢楼主加分,感谢cocoguo(周周)的Session["fileName"]
主 题: 在网页中嵌入了一个播放器,怎么才能在asp.net响应该播放器的open事件? 作 者: netbit (netbit) 等 级: 信 誉 值: 100 所属社区: .NET技术 ASP.NET 问题点数: 100 回复次数: 14 发表时间: 2004-12-3 8:27:34 用javascript可以这么捕获: <SCRIPT FOR="MediaPlayer" EVENT="OpenStateChange(NewState)" LANGUAGE="JScript"> if(NewState=13) { } </SCRIPT> 可是怎么用asp.net捕获呢?或者怎么在用javascript捕获事件后调用一个asp。net的函数? 多谢! 回复人: jsljy(小卢) ( ) 信誉:97 2004-12-3 8:33:40 得分: 0 没有用过,帮你顶一下 Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 8:36:55 得分: 0 以前有一个家伙问过! 好像可以用WebServer解决了! Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 8:38:44 得分: 40 http://msdn.microsoft.com/library/default.asp?url=/workshop/author/webservice/webservice.asp Top 回复人: netbit(netbit) ( ) 信誉:100 2004-12-3 8:39:36 得分: 0 如何在用某事件发生使用javascript调用一个asp。net的函数,这个问题我碰上很多回了,由于javascript是运行在客户端的,而asp.net函数是运行在服务器端的,所以我感觉不能直接调用,那么,有什么折中的办法么? 那位大虾指点一下啊 Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 8:39:52 得分: 0 好像只能调用webservice 不然一刷新什么都没有了! Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 8:44:19 得分: 15 http://msdn.microsoft.com/library/default.asp?url=/workshop/author/webservice/webservice.asp 这个就是一个用JS调用服务端的方法的例子呀! Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 8:48:20 得分: 15 有一个更详细一点的 http://www.cnblogs.com/evernory/archive/2004/07/13/23907.aspx Top 回复人: killerliu(Lain) ( ) 信誉:88 2004-12-3 8:51:39 得分: 30 客户端要调用服务器函数其实很简单。。但是你首先必须借助一个中间桥梁 大家都知道asp.net程序(包含有提交事件)编译以后生成的html代码中都会包含一个函数就是__dopostback() <script language="javascript"> <!-- function __doPostBack(eventTarget, eventArgument) { var theform; if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) { theform = document.forms["Form1"]; } else { theform = document.Form1; } theform.__EVENTTARGET.value = eventTarget.split("$").join(":"); theform.__EVENTARGUMENT.value = eventArgument; theform.submit(); } // --> </script> 所以我们可以模拟这个事件做一些事情,我的做法是放一个textbox在页面,宽度设为0px(不能隐藏,否则无法触发),设置autopostback属性为true,然后在后台为其绑定事件 Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged ‘这里写你要调用的函数 ’函数的参数可以赋值给textbox1 End Sub 上述事情做完以后,我们就可以直接写脚本了 <script language=javascript> a(strs){ Form1.TextBox1.value=strs; __doPostBack('TextBox1',''); } </script> 放心,只要你能模拟到这个提交事件,什么事情都能做到。 Top 回复人: taizans(书生) ( ) 信誉:100 2004-12-3 8:58:35 得分: 0 原来这样。尝试过,但失败了。学习学习…… Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 9:00:57 得分: 0 killerliu(Lain) 你这个不行的,楼主要的是无刷新! 你这样一提交! 页面刷新 页面就被重置! Top 回复人: feidaoxiaoli(★★★★★) ( ) 信誉:98 2004-12-3 9:01:31 得分: 0 好题!共同学习,帮你顶!!! Top 回复人: killerliu(Lain) ( ) 信誉:88 2004-12-3 9:11:18 得分: 0 倒。。。。楼主不是要用javascript来调用服务器端的函数吗?我写的方法可能有些地方么写正确,但是我已经成功处理过这样的事情,而且模拟“提交”事件去调用服务器端函数绝对是一个很好玩的事情。 还有无刷新的确不行! Top 回复人: listhome(不想睡) ( ) 信誉:100 2004-12-3 9:26:05 得分: 0 webservice.htc 绝对是正解了! Top 回复人: netbit(netbit) ( ) 信誉:100 2004-12-3 9:33:12 得分: 0 感觉用webservice的方法和killerliu(Lain)的中间桥梁都是不错的办法,现在问题已经解决。 多谢各位了
May 27  有的时候我们需要 (1)在编辑的时候用下拉框选择,并且默认为数据库的内容 (2)使用下拉框过滤数据 (3)使用css统一定制DataGrid 下面给出代码: 数据结构: 表dep:depid(标识主键),depname(学院名字) 表stu:stuid(标识主键),stuname(学生名字),studepid(学院id=表dep.depid)
前台: <%@ Page language="c#" Codebehind="WebForm28.aspx.cs" AutoEventWireup="false" Inherits="csdn.WebForm28" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm28</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <link href="css.css" rel="stylesheet" type="text/css"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body> <form id="Form1" method="post" runat="server"> <asp:DropDownList id="DropDownList1" runat="server" AutoPostBack="True"></asp:DropDownList> <asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns="False" CellSpacing="1" BorderWidth="0px" CellPadding="5" CssClass="border" OnEditCommand="edit" OnCancelCommand="cancel" OnUpdateCommand="update" DataKeyField="stuid"> <ItemStyle CssClass="item"></ItemStyle> <HeaderStyle CssClass="header"></HeaderStyle> <Columns> <asp:TemplateColumn HeaderText="姓名"> <ItemTemplate> <%# DataBinder.Eval(Container.DataItem,"stuname") %> </ItemTemplate> <EditItemTemplate> <asp:TextBox id="name" Runat="server" Text='<%# DataBinder.Eval(Container.DataItem,"stuname") %>' Width="88px"> </asp:TextBox> </EditItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="学院"> <ItemTemplate> <%# DataBinder.Eval(Container.DataItem,"depname") %> </ItemTemplate> <EditItemTemplate> <asp:DropDownList ID="dep" Runat="server"></asp:DropDownList> </EditItemTemplate> </asp:TemplateColumn> <asp:EditCommandColumn ButtonType="PushButton" UpdateText="更新" CancelText="取消" EditText="编辑"></asp:EditCommandColumn> </Columns> </asp:DataGrid> </form> </body> </HTML> 后台: using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace csdn { /// <summary> /// WebForm28 的摘要说明。 /// </summary> public class WebForm28 : System.Web.UI.Page { protected System.Web.UI.WebControls.DropDownList DropDownList1; protected System.Web.UI.WebControls.DataGrid DataGrid1; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 if(!IsPostBack) { SetBind(); SetBind2(); } } protected void SetBind() { SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); SqlDataAdapter da=new SqlDataAdapter("select * from stu,dep where stu.studepid=dep.depid",conn); DataSet ds=new DataSet(); da.Fill(ds,"table1"); this.DataGrid1.DataSource=ds.Tables["table1"]; this.DataGrid1.DataBind(); } protected void SetBind2() { SqlConnection conn2=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); SqlDataAdapter da2=new SqlDataAdapter("select * from dep",conn2); DataSet ds2=new DataSet(); da2.Fill(ds2,"table1"); this.DropDownList1.DataSource=ds2.Tables["table1"]; this.DropDownList1.DataTextField="depname"; this.DropDownList1.DataValueField="depid"; this.DropDownList1.DataBind(); this.DropDownList1.Items.Insert(0,new ListItem("请选择","")); } protected void SetBind3() { string s=this.DropDownList1.SelectedValue; SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); SqlCommand comm=new SqlCommand(); comm.Connection=conn; if(s!="") { comm.CommandText="select * from stu,dep where stu.studepid=dep.depid and depid=@depid"; SqlParameter parm1=new SqlParameter("@depid",SqlDbType.Int); parm1.Value=s; comm.Parameters.Add(parm1); } else comm.CommandText="select * from stu,dep where stu.studepid=dep.depid"; SqlDataAdapter da=new SqlDataAdapter(); da.SelectCommand=comm; DataSet ds=new DataSet(); da.Fill(ds,"table1"); this.DataGrid1.DataSource=ds.Tables["table1"]; this.DataGrid1.DataBind(); } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.DataGrid1.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemDataBound); this.DropDownList1.SelectedIndexChanged += new System.EventHandler(this.DropDownList1_SelectedIndexChanged); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) { SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); SqlDataAdapter da=new SqlDataAdapter("select * from dep",conn); DataSet ds=new DataSet(); da.Fill(ds,"table1"); if(e.Item.ItemType==ListItemType.EditItem) { DropDownList ddl=(DropDownList)e.Item.FindControl("dep"); ddl.DataSource=ds.Tables["table1"]; ddl.DataTextField="depname"; ddl.DataValueField="depid"; ddl.DataBind(); ddl.Items.FindByValue(Convert.ToString(DataBinder.Eval(e.Item.DataItem,"depid"))).Selected=true;//选择数据库内的作为默认 } } protected void edit(object sender,DataGridCommandEventArgs e) { this.DataGrid1.EditItemIndex=e.Item.ItemIndex; if(this.DropDownList1.SelectedValue=="") SetBind(); else SetBind3(); } protected void cancel(object sender,DataGridCommandEventArgs e) { this.DataGrid1.EditItemIndex=-1; if(this.DropDownList1.SelectedValue=="") SetBind(); else SetBind3(); } protected void update(object sender,DataGridCommandEventArgs e) { if(e.Item.ItemType==ListItemType.EditItem)//只有在编辑按下以后才能提交 { SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]); SqlCommand comm=new SqlCommand("update stu set stuname=@name,studepid=@depid where stuid=@id",conn); SqlParameter parm1=new SqlParameter("@name",SqlDbType.NVarChar,50); parm1.Value=((TextBox)e.Item.FindControl("name")).Text; SqlParameter parm2=new SqlParameter("@depid",SqlDbType.Int); parm2.Value=((DropDownList)e.Item.FindControl("dep")).SelectedValue; SqlParameter parm3=new SqlParameter("@id",SqlDbType.Int); parm3.Value=this.DataGrid1.DataKeys[e.Item.ItemIndex]; comm.Parameters.Add(parm1); comm.Parameters.Add(parm2); comm.Parameters.Add(parm3); conn.Open(); comm.ExecuteNonQuery(); conn.Close(); this.DataGrid1.EditItemIndex=-1; if(this.DropDownList1.SelectedValue=="") SetBind(); else SetBind3();//如果选择过滤则使用SetBind3() } } private void DropDownList1_SelectedIndexChanged(object sender, System.EventArgs e) { SetBind3(); } } } css: .border { background-color: #00496C; } .header { font-family: "宋体", sans-serif; font-size: 10pt; font-weight: bold; color: #FFFFFF; background-color: #0080C0; text-align: center; } .item { font-family: "宋体", sans-serif; font-size: 9pt; font-weight: normal; color: #0080C0; background-color: #FFFFFF; text-align: center; } 代码比较简单,下面简单说明一下: (1)SetBind()是基本的绑定;SetBind2()是绑定外面的那个DropDownList;SetBind3()是在下拉框选择了以后过滤后的DataGrid的绑定 (2)这里使用Css来实现表格边框是利用CellSpacing,所以这个数值就是边框的宽度,在表格边框的css中使用background-color来描述边框的颜色。 May 25 1、ASP.NET能在那些系统中运行? 目前,ASP.NET还只能奔跑在微软的Windows 2000、Windows XP和Windows 2003的系统中,并且需要微软Internet Information Server(IIS)的支持,微软原计划要让Windows NT4.0也支持ASP.NET,但可能微软是有些技术问题或市场考虑,还没有实现NT下的ASP.NET的支持。 2、在一个ASPX文件中是否可以使用一种以上的语言? 答案让你有点失望,虽然微软的提供了公共语言运行环境(CLR,Common Laguage Runtime),实现了多种编程语言间的紧密集成,可以允许你从一个VB对象中导出C#所需的对象来,但一个ASPX文件中只能用一种语言,正如你不能在VB.NET中使用C#的语法一样。 3、ASPX文件的服务器端脚本支持那些语言? 目前,ASPX文件只支持C#、Visual Basic.NET、Jscript.NET和J#,但是你使用code—behind(代码分离)的方法创建一个独立代码文件,你就可以使用任何.NET编译器支持的语言来实现功能了。 4、在Global.asax文件中能使用code—behind(代码分离)技术吗? 当然可以了,例如: Global.asax: <script language=VB" runat="server"> Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) Application("online_session") = 0 End Sub Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) Application.Lock() Application("online_session") = CInt(Application("online_session")) + 1 Application.UnLock() End Sub Sub Session_End(ByVal sender As Object, ByVal e As EventArgs) Application.Lock() Application("online_session") = CInt(Application("online_session")) - 1 Application.UnLock() End Sub </script> 和使用code—behind(代码分离)技术 Global.asax: <%@ Application Inherits="MyApp" %> MyApp.vb: Imports System.Web Imports System.Web.SessionState Public Class MyApp Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) Application("online_session") = 0 End Sub Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) Application.Lock() Application("online_session") = CInt(Application("online_session")) + 1 Application.UnLock() End Sub Sub Session_End(ByVal sender As Object, ByVal e As EventArgs) Application.Lock() Application("online_session") = CInt(Application("online_session")) - 1 Application.UnLock() End Sub End Class 5、我能否看到ASPX文件在ASP.NET中生成的代码吗? 可以看到的,当你的ASPX文件中包含<%@ Page Debug="true" %>命令或Web.config中声明了<compilation debug="true">时,你就可以在系统目录下的Microsoft.NET\Framework\v1.0.nnnn\Temporary ASP.NET Files中找到ASPX文件在ASP.NET下生成的文件。 6、在ASPX文件中如何注释呢? 同ASP文件中的方法一样。 <%-- response.write "测试!" --%> 7、ASPX文件中是否可以存在一个以上服务器端 Form 标记? 不可以 8、我可以在Web窗体中使用自定义数据类型吗 可以,你可以把包含自定义数据类型的DLL文件放在程序根目录下的BIN目录中,ASP.NET会在数据类型引用时,装载DLL文件的。 9、我能在Global.asax文件中触发那些事件? Application对象创建和结束时所触发的事件有 Application_Start Application_End Session对象创建和结束时所触发的事件有 • Session_Start • Session_End 对程序有请求发生时触发的事件有 (按发生顺序排列) • Application_BeginRequest • Application_AuthenticateRequest • Application_AuthorizeRequest • Application_ResolveRequestCache • Application_AcquireRequestState • Application_PreRequestHandlerExecute • Application_PostRequestHandlerExecute • Application_ReleaseRequestState • Application_UpdateRequestCache • Application_EndRequest 当有程序有错误发生时触发的事件有 • Application_Error • Application_Disposed 10、Web控件是否支持样式表(CSS)呢? Yes. All Web controls inherit a property named CssClass from the base class System.Web.UI.WebControls.WebControl. The following example defines a CSS class named Input and uses it to modify a TextBox control to display text in red 10-point Verdana type: 支持,所有的Web控件都从基类System.Web.UI.WebControls.WebControl中继承了一个叫做CssClass的属性。 例如: <html> <head> <style> .Input { font: 10pt verdana; color: red; } </style> </head> <body> <form runat="server"> <asp:TextBox CssClass="Input" RunAt="server" /> </form> </body> </html> 11、在ASPX文件中默认导入那些名称空间? ASPX默认导入的名称空间可以直接引用了,使用其它的名称空间就的自行导入了。 默认名称空间 System System.Collections System.Collections.Specialized System.Configuration System.Text System.Text.RegularExpressions System.Web System.Web.Caching System.Web.Security System.Web.SessionState System.Web.UI System.Web.UI.HtmlControls System.Web.UI.WebControls 12、我是否可以自己创建服务器控件呢? 可以,创作您自己的 ASP.NET 服务器控件很容易。创建简单的自定义控件时,您所要做的只是定义从 System.Web.UI.Control 派生的类并重写它的 Render 方法。Render 方法采用 System.Web.UI.HtmlTextWriter 类型的参数。控件要发送到客户端的 HTML 作为字符串参数传递到 HtmlTextWriter 的 Write 方法。 例如: 服务器控件代码(简单显示字符串):Simple.vb: Imports System Imports System.Web Imports System.Web.UI Namespace SimpleControlSamples Public Class SimpleVB : Inherits Control Protected Overrides Sub Render(Output As HtmlTextWriter) Output.Write("<H2>欢迎使用控件开发!</H2>") End Sub End Class End Namespace 引用文件Simple.aspx: <%@ Register TagPrefix="SimpleControlSamples" Namespace="SimpleControlSamples" Assembly="SimpleControlSamplesVB" %> <html> <body> <form method="POST" action="Simple.aspx" runat=server> <SimpleControlSamples:SimpleVB id="MyControl" runat=server/> </form> </body> </html> 13、如何在ASP.NET程序中发送邮件呢? 在ASP.NET程序中发送邮件不再象ASP中那样需要组件的支持了,在.NET的框架基类的System.Web.Mail名称空间内包含的MailMessage和SmtpMail类可以实现这个功能。 例如: Dim message As new Mail.MailMessage message.From = "web3@163.com" message.To = "web3@163.com" message.Subject = "测试" message.Body = "内容" Mail.SmtpMail.SmtpServer = "localhost" Mail.SmtpMail.Send(message) 14、我将如何通过ADO.NET读取数据库中的图片并显示它呢? 下面举一个从Microsoft SQL Server的PUB数据库读取图片并显示它的例子: <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Drawing" %> <%@ Import Namespace="System.Drawing.Imaging" %> <%@ Import Namespace="System.IO" %> <script language="VB" runat="server"> Sub Page_load(Sender as Object, E as EventArgs) dim stream as new MemoryStream dim connection as SqlConnection connection=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=") try connection.Open() dim command as SqlCommand command = new SqlCommand ("select logo from pub_info where pub_id=''0736''", connection) dim image as byte() image = command.ExecuteScalar () stream.Write (image, 0, image.Length) dim imgbitmap as bitmap imgbitmap = new Bitmap (stream) Response.ContentType = "image/gif" imgbitmap.Save (Response.OutputStream, ImageFormat.Gif) Finally connection.Close() stream.Close() End Try End Sub </script> May 13 (1)访问Duwamish,执行Global.asax的Application_OnStart()  void Application_OnStart()   {  ApplicationConfiguration.OnApplicationStart(Context.Server.MapPath( Context.Request.ApplicationPath ));  string configPath = Path.Combine(Context.Server.MapPath( Context.Request.ApplicationPath ),"remotingclient.cfg");  if(File.Exists(configPath))  RemotingConfiguration.Configure(configPath);  } (2)调用ApplicationConfiguration.OnApplicationStart(Context.Server.MapPath( Context.Request.ApplicationPath ));
 public static void OnApplicationStart(String myAppPath)   {  appRoot = myAppPath;  System.Configuration.ConfigurationSettings.GetConfig("ApplicationConfiguration");  System.Configuration.ConfigurationSettings.GetConfig("DuwamishConfiguration");  System.Configuration.ConfigurationSettings.GetConfig("SourceViewer");  } (3)System.Configuration.ConfigurationSettings.GetConfig("DuwamishConfiguration");并没有返回什么,目的是调用: Common.DuwamishConfiguration.Create()方法,填充静态字段: private static String dbConnectionString;等. (4)可以直接使用DuwamishConfiguration.ConnectionString进行读取.
May 12 DataAdapter 在其 TableMappings 属性中包含零个或更多个 DataTableMapping 对象的集合。DataTableMapping 提供对数据源的查询所返回的数据与 DataTable 之间的主映射。DataTableMapping 名称可以代替 DataTable 名称传递到 DataAdapter 的 Fill 方法。以下示例为 MyAuthors 表创建名为 AuthorsMapping 的 DataTableMapping。 [Visual Basic] workAdapter.TableMappings.Add("AuthorsMapping", "MyAuthors") [C#] workAdapter.TableMappings.Add("AuthorsMapping", "MyAuthors"); DataTableMapping 使您能够使用 DataTable 中与数据库中的列名不同的列名。当该表被更新时,DataAdapter 将使用此映射来匹配列。 如果在调用 DataAdapter 的 Fill 或 Update 方法时未指定 TableName 或 DataTableMapping 名称,DataAdapter 将查找名为“Table”的 DataTableMapping。如果 DataTableMapping 不存在,DataTable 的 TableName 将为“Table”。可以通过创建名为“Table”的 DataTableMapping 来指定默认的 DataTableMapping。 以下代码示例创建一个 DataTableMapping(从 System.Data.Common 命名空间)并通过将其命名为“Table”来使其成为指定 DataAdapter 的默认映射。然后,该示例将查询结果中第一个表(Northwind 数据库的 Customers 表)中的列映射到 DataSet 的 Northwind Customers 表中的一组更为用户友好的名称。对于未映射的列,将使用数据源中的列名称。 [Visual Basic] Dim custMap As DataTableMapping = custDA.TableMappings.Add("Table", "NorthwindCustomers") custMap.ColumnMappings.Add( "CompanyName", "Company") custMap.ColumnMappings.Add( "ContactName", "Contact") custMap.ColumnMappings.Add( "PostalCode", "ZIPCode") custDA.Fill(custDS) [C#] DataTableMapping custMap = custDA.TableMappings.Add("Table", "NorthwindCustomers"); custMap.ColumnMappings.Add( "CompanyName", "Company"); custMap.ColumnMappings.Add( "ContactName", "Contact"); custMap.ColumnMappings.Add( "PostalCode", "ZIPCode"); custDA.Fill(custDS); 在更为复杂的情况下,您可能会决定需要使用相同的 DataAdapter 来支持为不同的表加载不同的映射。若要完成此任务,只需添加附加的 DataTableMapping 对象。 当 Fill 方法以 DataSet 实例和 DataTableMapping 名称的形式进行传递时,如果存在具有该名称的映射,则使用该映射;否则将使用具有该名称的 DataTable。 以下示例创建一个名称为 Customers 而 DataTable 名称为 BizTalkSchema 的 DataTableMapping。然后,该示例将 SELECT 语句所返回的行映射到 BizTalkSchema DataTable。 [Visual Basic] Dim bizMap As ITableMapping = custDA.TableMappings.Add("Customers", "BizTalkSchema") bizMap.ColumnMappings.Add( "CustomerID", "ClientID") bizMap.ColumnMappings.Add( "CompanyName", "ClientName") bizMap.ColumnMappings.Add( "ContactName", "Contact") bizMap.ColumnMappings.Add( "PostalCode", "ZIP") custDA.Fill(custDS, "Customers") [C#] ITableMapping bizMap = custDA.TableMappings.Add("Customers", "BizTalkSchema"); bizMap.ColumnMappings.Add( "CustomerID", "ClientID"); bizMap.ColumnMappings.Add( "CompanyName", "ClientName"); bizMap.ColumnMappings.Add( "ContactName", "Contact"); bizMap.ColumnMappings.Add( "PostalCode", "ZIP"); custDA.Fill(custDS, "Customers"); 注意 如果没有为列映射提供源列名称或者没有为表映射提供源表名称,则将自动生成默认名称。如果没有为列映射提供源列,则将给列映射提供递增的默认名称 SourceColumnN,这些名称从“SourceColumn1”开始。如果没有为表映射提供源表名称,则将给该表映射提供递增的默认名称 SourceTableN,这些名称从“SourceTable1”开始。 建议在为列映射提供源列名称时避免使用“SourceColumnN”命名约定,在为表映射提供源表名称时避免使用“SourceTableN”命名约定,因为所提供的名称可能会与 ColumnMappingCollection 中现有的默认列映射名称或 DataTableMappingCollection 中的表映射名称发生冲突。如果提供的名称已经存在,将引发异常。 多个结果集 如果 SelectCommand 返回多个表,Fill 将自动使用递增值为 DataSet 中的表生成表名称,这些表名称从指定表名称开始,并以 TableNameN 格式(从“TableName1”开始)继续。可以使用表映射将自动生成的表名称映射到要为 DataSet 中的表指定的名称。例如,对于返回两个表(Customers 和 Orders)的 SelectCommand,可对 Fill 发出以下调用。 custDA.Fill(custDS, "Customers") 在 DataSet 中创建了两个表:Customers 和 Customers1。可以使用表映射来确保第二个表名为 Orders 而不是 Customers1。若要完成此任务,请将 Customers1 的源表映射到 DataSet 表 Orders,如以下示例所示。 custDA.TableMappings.Add("Customers1", "Orders") custDA.Fill(custDS, "Customers")
|