[置顶] C# 编程感悟

第一篇:编程感悟6

程序员应具备的素质:
1.与时俱进,不断进步。
2.
认真负责,少犯错误。
3.
勤奋听话,踏实工作。
4.
注意备份,防患于未然。
5.
掌握多种语言,放宽思维。
程序员的必备技能
1.自上而下和面向对象的思维方法
2.
数据库技术
3.
富客户端应用技术
4.WEB
页面开发
5.
操作系统
程序员的生涯规划
对照自己制定的职业规划看看目标达成了多少,这两年是否达到了自己的预期目标,
如果没有达成目标,分析一下究竟是环境的原因,,还是自己个人的原因,如果是环境的原因,
可以考虑是否需要换个环境,如果是自己的原因,可以调整自己或者把目标设的更现实一些。
让职业规划的目标给予自己动力,让自己朝着正确的方向发展。
编程学习经验谈
1.
勤上机,多动手。
2.
尝试自己解决问题
3.
多读优秀程序的源代码
4.
善于利用googlebaidu和编程论坛
5.
养成代码规范的编程习惯
6.
屏蔽复制,粘贴大法
7.
关于英语。
数据库设计经验谈
1.
开始设计数据库前分析现有系统的表结构
2.
尽早创建系统的ER
3.
标准化和数据驱动
4.
不要讲身份证号码选作表的主键
5.
保证数据的完整性
6.
为文本字段留足字段余量
7.
使用系统生成的主键
8.
反复测试设计的数据库
项目实战经验谈
1.
在项目开始前进行技术储备
2.
分析项目的业务流程
3.
多和团队成员交流
4.
能在数据库干的事绝不放在程序中解决
5.
一定要为代码加上注释
6.
边写代码边测试
7.
正确使用版本控制工具

 

第二篇 不可忽视的30个技术陷阱

陷阱01 版本不一致产生的陷阱
解决方法:为网站重新添加一遍对项目的引用。
陷阱02 结构初始化产生的陷阱
C#
编译器不会为结构生成无参数的构造器,而属性必须在构造器中被初始化,这是出错的原因
虽然结构中不允许创建无参的构造器,但开发者可以使用new运算符显示创建结构的实例。
陷阱03 传递派生类产生的陷阱
在参数传递中,派生类对象可以用其基类类型的参数接受。而SystemObject类是所有类型(包括string类型)的基类,但一个object类型的参数,如果提供的参数值不是一个对象,那么编译器就会发出错误消息。
解决方法:首先将string类型的变量装箱,转为object类型,再将object类型的变量转入方法。
陷阱04 DataReader读取数据时产生的陷阱
在读取第一行记录前也必须调用Read方法,DataReader刚创建时,行游标在第一行之前。
在使用DataReader每次读取记录之前必须判断Reader()方法的返回值,只有返回值为true时才能读取记录。
陷阱05 类型转换时产生的陷阱
通过ado.net读取的数据都是object类型的,而实体对象中的属性类型通常与物理数据表中的字段类型一一对应,即没有object类型的,可能是日期型,浮点型,如果将日期类型的字段值通过ado.net读取赋值给本地对象时,需呀用convert类的todatatime()将ado.net中读取的值转换为datatime类型。再赋值给实体对象。
判断从ado.net中读取的值是否为空有一技巧:
if (reader["OperateDate"].ToString()!="")
陷阱06 DataReader作为返回类型的陷阱
DataReader在读取数据的过程中要求数据库保持连接状态,读完数据后才能断开连接。
ado.net中,打开数据连接,执行完数据操作后,要尽快关闭数据连接。
解决方法:使用DataSet读取数据的方式,并返回DataSet类型。
陷阱 07 GridView 绑定DataReader 产生的陷阱
DataReader
的读取速度比DataSet快,占用的资源比DataSet少,所以在加载列表控件数据时一般使用DataReader的读取方式。
GridView
如果使用分页功能,跟DataReader有冲突
解决方法:1.DataSet换掉DataReader 2.可以使用自定义实现分页功能
陷阱 08 sqlDateTime溢出陷阱
解决方法:userOperateDate=DateTimeNow
陷阱 09 写网站中XML文件产生的陷阱
权限访问问题:设置下权限
陷阱10 访问下拉列表控件的SelectedValue属性产生的陷阱
绑定方法:
ddlDepartment.DataTextField="DepartmentName"
ddlDepartment.DataValueField="DepartmentID"
ddlDepartment.DataSource=reader
ddlDepartment.DataBind()
陷阱 11 动态记载用户控件的陷阱
动态加载:
UC_Search search = (UC_Search )Page.LoadControl("~/UC_Search .ascx")
PlaceHolder.Controls.Add(search)
Page.IsPostBack
属性表示是否首次记载和访问页面,属性值为false表示首次加载页面,否则表示从客户端再次返回该页面。
陷阱 12 javascript 设置服务器控件值
asp.net为页上的每个服务器控件自动生成一个唯一的ClientID值。ClientID值是通过连接控件的ID值和她的父控件的UniqueID值生成的。
解决方法:可以通过Control类的ClientID属性读取asp.net生成的控件ID
<a href="#"onclick="document.getElementByIdx_x('<%=hidCatalog.ClientID%>').value='1';">Java</a>
陷阱 13 放置隐藏字段的陷阱
为了回传的过程中保存控件的值,aspnet提供了很多解决方案,使用隐藏字段hidden存值是一种最古老最有效的方法。HiddenField控件没有Enable属性,也没有ReadOnly属性,
声明隐藏字段时一定要加上属性runat="server"并且将隐藏字段放在<form></form>标记中,至于这样隐藏字段才能被代码访问到。
陷阱 14 动态加载设置输出缓存的用户控件
<%@OutPutCache Duration="30"VaryByParam="none"%>
加载用户控件:
PartialCachingControl head=(PartialCachingControl)Page.LoadControl("~/UC_Header.ascx")
用户控件启用输出缓存后,LoadControl不再返回对控件实例的引用,相反,它返回对PartialCachingControl实例的引用
陷阱 15 为删除按钮添加删除确认对话框
protected void RowDataBound(object sender,GridViewRowEventArgse)
{
  
if(e.Row.RowType==DataControlRowType.DataRow)//如果是数据行
   
{
         GridView grid = sender as GridView //取当前操作的GridView
         
((LinkButton)(e.Row.Cells[grid.Columns.Count-1].Controls[0])).Attributes.Add("onclick","returnconfirm('确认删除?')")
}
}
protected void RowCommnd(object sender,GridViewCommandEventArgs 
e)
{
    if(!string.IsNullOrEmptype(e.CommandName))
{
       //其他代码
     
elseif(e.CommndName=="Del")
{
          intindex=Convert.ToInt32(e.CommandArgument)//GridView行索引
         
GridView grid = GridViewe.CommandSource //取当前操作的GridView
        
intid = Convert.ToInt32(grid.DataKey[index].Value)//gridView主键值
       
UserInforService.Instance.DeleteUserInfo(id)//调用删除用户信息的方法
      
LoadData()
}
}
陷阱 16 页面在客户端转向的陷阱
使用javascript设置windowlocation 实现页面跳转
<asp:Button ID="btnAdd" runat="server" text="
添加"OnClientClick="location.href='UserInput.aspx'return false;"/>
陷阱 17 Web Service 方法重载产生的陷阱
Web服务,就是系统提供一组接口,并通过接口使用系统提供的功能。(将一组相近的功能封装成一个Web服务,供所有的用户远程使用)
Web Service
工作原理:客户端调用一个WebService方法,首先需要将方法名和需要传递的参数包装成XML(也就是SOAP包),通常是通过HTTP传递到服务器端,然后服务器端解析这段XML,得到被调用方法名称和传递来的参数,进而调用WebService实例的相应方法。方法执行完成后,将返回的结果再包装成XML(
soap
响应)发送到客户端,客户端解析这段XML,进而得到返回结果。
Web Service
中不支持方法的重载,所以只能将两方法改成不同名
陷阱18 编写javascript代码时的空格陷阱
protected void RowCommnd(object sender,GridViewCommandEventArgs e)
{
    if(!string.IsNullOrEmptype(e.CommandName))
{
       //其他代码
     
elseif(e.CommndName=="Edi")
{
          intindex=Convert.ToInt32(e.CommandArgument)//GridView行索引
         
GridView grid = GridViewe.CommandSource //取当前操作的GridView
        
intid = Convert.ToInt32(grid.DataKey[index].Value)//gridView主键值
       
Response.Redirect(@"~/System/UserInput.aspx?ID="+id.ToString())
}
}
proected void Page_Load(object sender,EventArgs e)
{
  if(!this.IsPostBack)
{
   id=Request.QueryString["ID"].ToString()
}
}
注意:?和ID之间有没有空格
陷阱19 使用可空符号??运算
??可以解决数据库中的数字可以为空,而C#中的数字不能为空的问题
??运算符:如果??运算符的左操作数非null,该运算符将返回左操作数,否则返回右操作数
注意:运算符的优先顺序。
double ? Amount=(Quantity??0)*(Prive??0)
陷阱20 获取错误信息并到指定页面
asp.net中,通过设置web.config配置文件可以在应用程序范围内实现自定义错误处理页面,错误配置信息位于web.config文件的<customErrors>节。
<customErrors mode ="on"defaultRedirect="Error.aspx"></customErrors >
mode="on"
表示为整个应用程序自定义错误。
通过全局配置文件(Gobal.asax)中的Application_Error 事件,可以截取所有未处理的异常。在该事件中首先调用Server.GetLastError()方法获得最后一个异常,如果该异常是未处理的一般异常则打开错误处理页
void Application_Error(object sender,EventArgs e)
{
   
Exceptionexcept=Server.GetLastError()//获得最后一个异常
   
if(except is HttpUnhandledException)//如果是一个未处理过的异常

     
Response.Redirect("~/Error.aspx")//Redirect会导致回传,所以不用
  
改成:Server.Transfer("~/Error.aspx")
}
}
Server.Transfer
方法直接在服务器端打开Erroraspx 页,这样就可以在错误处理页面得到出错信息并进行相应的处理。
陷阱22 文件格式与文件读取的陷阱
protected void btnWrite_Click(object sender,EventArgs e)
{
  
stringfilename=Server.MapPath("App_Data/txtFile.txt")//文件路径
  
if(File.Exists(filename))
{
   File.Delete(filename)
}
using (StreamWriter sw= newStreamWriter(filename,false,System.Text.Encoding.GetEncoding("gb2312")))
{
   sw.Write("你的姓名")
   
sw.WriteLine("lyf")
}
}
protected void btnRead_Click(object sender,EventArgs e)
{
  stringfilename=Server.MapPath("App_Data/txtFile.txt")//文件路径
  
using (StreamReader sr=newStreamReader(filenamefalse,System.Text.Encoding.GetEncoding("gb2312")))
{
  string line;
  while((line=sr.ReadLine())!=null)
{
  Response.Write(line+"<br/>")
}
}
}
注意:以什么样的编码格式写入,就以什么样的编码格式读出
陷阱23 读写二进制文件的陷阱
protected void btnWrite_Click(object sender,EventArgs e)
{
  
stringfilename=Server.MapPath("App_Data/txtFile.txt")//文件路径
  
if(File.Exists(filename))
{
   File.Delete(filename)
}
FileStream fs = new FileStream(filename,FileMode.CreateNew);//创建文件流
BinaryWriter bw = new BinaryWrite(fs);
for(int i=0;i<5;i++)
{
  
bw.Write(i);
}
for(int i=5;i<10;i++)
{
  bw.Write(i.ToString());
}

}
protected void btnRead_Click(object sender,EventArgs e)
{
  
stringfilename=Server.MapPath("App_Data/txtFile.txt")//文件路径
FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read);//
创建文件流

 BinaryWriter bw = newBinaryWrite(fs);
for(int i=0;i<5;i++)
{
  
Response.Write(br.ReadInt32());
}
for(int i=0;i<5;i++)
{
 Response.Write(br.ReadString
());
}
}
注意:以什么方式写入什么类型的数据,就得以什么方式读取
陷阱 24 母板页中使用img标签
解决方法:img标签改成asp.net服务器端控件Image,并使用绝对路径
陷阱25 页面缓存产生的陷阱
解决方法:
1.asp.net
根据Url缓存模态窗口的,即如果每次传入的URL都不同,模态窗口就不会从缓存中取了。再打开模态窗口URL后面添加如下代码可以使每次传入的url都不同。
Response.Redirect("@~/System/UsertInput.aspx?ID="+id.ToString());
后面加上+"&rand"+newRandom().Next().ToString()
2.
在模态窗口的Load事件中加入一些代码可以使缓存失败
 protected void Load(object sender , EventArgs e)
{
  
if(!IsPostBack)
{
   Response.Buffer=true//清除缓存
    
Response.ExpiresAbsolute=DataTime.Now.AddSeconds(-1);
    Response.Expries=0;
    Response.CacheControl="no-cache";
}
}
陷阱26 使用查询字符串在页面间传递参数
解决方法:在查询字符串时,不管查询字符串的值是何种类型,都不要加入任何类型修饰符。
正确的写法:Response.Redirect("@~/System/UsertInput.aspx?UserCode="+UserCode);
陷阱27通用数据类型运算产生的陷阱
object obj = DBHeper.GetData();
该方法有时会返回一个DataSet,有时会返回一个实体对象,有时则返回一个表示数据表中某行某列的值。
如果返回某行某列的值,我们通过object类型接收之后需要将其转换为对应的类型。
string str= obj.ToString()
有时则需要调用object对象的GetType()方法,通过反射动态取GetData方法返回对象中的成员值。
Type ty= obj.GetType()
解决方法:首先是判断object类型的变量是否为null,其次再判断该变量值与对变量的操作是否匹配。
陷阱28 在模态窗口中下载文件
解决方法:在Gridview中定义一个模板字段,在模板中定义一个<a>,用于指定另一个实现文件下载功能的页面。
<ItemTemplate>
<ahref="DownloadFiles.aspx?AttachFileID=<%#eval_r("AttachFileID")%>"target="_blank">
下载</a>
</ItemTemplate>
protected void Page_Load(object sender , EventArgs e)
{
  
if(!this.IsPostBack)
{
   if(Request.QueryString["AttachFileID"]!=null)
{
   string fileFullName;
   stringattachFileID=Request.QueryString["AttachFileID"].ToString();
   stringconStr=ConfigurationManager.ConnectionString["ExpatiateAspNetConnectionString"].ToString();
   using(SqlConnectioncon = new SqlConnection(conStr))
{
   con.Open();
   SqlCommand cmd = newSqlCommand ("select fileFullName from ....where....");
   fileFullName=cmd.ExecuteScalar().ToString();//取出文件下载路径
   
fileFullName=Server.MapPath(fileFullName);//将虚拟路径转成物理路径
}
  
DownloadFilefileFullName);
}
}
}
privat void DownloadFile
stringfileName)
{
  
System.IO.Stream iStream=null;
  byte[]  buffer =new Byte[10000];
  int length;
  long dataToRead;
  string filepath =fileName;
  stringfileName=System.IO.Path.GetFileName(fileName);//读出文件名
  
try
{
  //创建文件流
 iStream =newSystem.IO.FileStrem(filepath,System.IO.FileMode.Open,System.IO.FileAccess.Reoad,System.IO.FileShape.Read);
dataToRead =iStream.Length;
Response.CotentType ="application/octet-stream";
Response.AddHeader("Content-Disposition","attachment:filename="+filename);
while(dataToRead>0)
{
  
if(Response.IsClientConnected)
{
  length=iStream.Read(buffer,0,10000);//读取指定字节的文件流
  
Response.OutputStream.Write(buffer,0,length);//将读取的内容写入HTTP输出流
  
Response.Flush();//强制HTTP输出流全部输出
 buffer=new Byte[10000];
 dataToRead=dataToRead-length;
}
else
{
  
dataToRead=-1;
}
}
}
catch(Exception ex)
{
  Response.Write("Error:"+ex.Message);
}
finally
{
 if(iStream!=null)
{
 iStream.Close();
}
}
}
陷阱29 构造方法中调用虚方法的陷阱
解决方法:永远不要在父类的构造函数中调用虚函数。
陷阱30 使用值类型进行线性同步
解决方法:使用引用类型进行线性同步

 

第三篇 开发人员意识中的20个常见谬论

谬论01 所有的异常都要使用try...catch语句捕获
InvalidOperationException:
无效操作异常
InvalidCastException:
无效类型转换异常
类型转换异常处理方式可使用is或者as语句替换。
object obj;
DateTime dt;
obj=new objcect();
if(obj is DateTime)
{
  
dt=(DateTime)obj;
}
其他方式的类型转换失败时引发一个InvalidCastException异常,但使用as语句转换失败时只返回null
谬论02 web控件的Enable功能等价于html控件的disabled属性
Web
控件的Enable属性等于false,会影响该Web控件的服务器端行以及客户端呈现,并且会将该控件中的所有子控件的Enable属性设为false。而Html控件的disabled属性等于disabled通常仅影响客户端呈现,并不会影响到它的子控件
谬论03 Session设置为空就是删除该会话状态
解决方法:Session.Remove("ID");
谬论04 RegisterStartupScript方法不能向页面输出文本
使用RegisterStartupScript()或RegisterClientScriptBlock()方法同样可以向页面输出文本或弹出对话框
Page.ClientScript.RegisterStartupScript(Page.GetType(),"","
这是使用RgisterStartupScript输出文本");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(),"","<script>alert('
这是使用。。。')</script>");
谬论05 数据绑定表达式会自动计算它的值
一般情况下,数据绑定表达式不会自动计算它的值,除非它所在的页或控件显示的调用DataBind()方法。该方法能够将数据源绑定到被调用的服务器控件及所有子控件,同时分析并计算数据绑定表达式的值。

谬论 06 事件和委托的差别很大

谬论12 方法中只有引用类型的参数才能实现引用传递

解决方法:为值类型的参数加ref参数修饰符,也可以实现该参数以引用的方式进行传递
谬论14 数据绑定表达式中的Eval功能等价于Bind()
eval_r()方法只能够显示数据,使用RepeaterDataList控件呈现数据时经常在其数据绑定表达式中使用该方法。
Bind()
方法不但可以显示数据,而且还能修改数据。所以Bind()通常被GridviewDetailsView. FormView 控件中使用Bind()方法。
谬论17 Object类型比较方法上的一些误解
静态方法ReferenceEquals:该方法实现了引用比较。
静态方法Equals()首先比较两个对象是否恒等,如果不恒等调用实例Equals()方法,实例Equals()方法是一个虚方法,默认实现是引用比较,可以重写该方法构建自定义的比较。
谬论19 TextBox 控件依靠ViewState保持状态数据
asp.net控件依靠ViewState在页面回传时保存数据,但TextBox例外
谬论20 必须在页面添加<link>元素才能使用CSS文件中的样式。
可以将。css文件放入主题文件夹,asp.net会在这个文件夹里搜索所有的。css文件并把它们动态绑定到所有使用这个主题的页面上。

 

第四篇 必知必会的40个C#语言方面的技术细节

 细节01C#代码加注释的意义
细节02装箱和拆箱
细节03理解值类型和引用类型
值类型变量不能为null,必须具有一个确定的值。引用类型被赋值前的值都是null
细节04隐式转换和显示转换
细节05前缀方式增1和减1运算符
细节06理解移位运算符
>>运算符将第一个操作数向右移动第二个操作数所指定的位数
<<
运算符将第一个操作数向左移动第二个操作数所指定的位数
注意几点:
1.
如果第一个操作数为intuint,则移位数由第二个操作数的低五位给出
2.
如果第一个操作数为longulong,则移位数由第二个操作数的低六位给出
例如:int i; i=48>>3 i=6
48
对应的二进制为00110000,右移3位后的二进制值为00000110,则十进制为6
细节07理解运算的次序
细节08理解参数的类型
输入参数,输出参数out,引用参数ref,参数数组params
细节09重载方法
细节10虚方法与重写方法
虚方法指允许被其子类重新定义的方法,在声明时需要用virtual修饰符
重写也称为覆盖override,是在派生类使用override修饰符重写基类中带有virtual修饰符的虚方法
注意:override修饰符不能与newstatic,或virtual修饰符同时使用
,另外,重写方法只能用于重写基类中的虚方法,不能用来单独声明方法。
派生类中使用new关键字可以实现向基类成员隐藏继承成员。
public class Child:Parent
{
  public new string m()
{return "
隐藏一般方法"}
}
细节11结构和类的区别
细节12什么是封装
细节13什么是继承
细节14什么是多态
细节15作用域的概念
细节16使用索引器
索引器就是能够让类像一个数组似的被访问。索引器与属性很相似,也有getset访问器。
public string this[int Ind]
{
  get
{}
}
shapeName=s[Count];
细节17basethis关键字
base
关键字用于派生类中访问基类的成员。使用范围如下:
1.
调用基类中已被其他方法重写的方法
2.
指定创建派生类实例时应调用的基类构造函数。
细节18理解静态修饰符
细节19netobject
System.Object
类的核心成员如下:
Equals()
:确定两个object实例是否相等
Finalize():
释放资源并执行其他清理操作。
GetHashCode():
返回一个能够标识内存中指定对象的整数
GetType():
获取当前实例的System.Type()对象
MemberwiseClone():
返回当前对象逐个成员的副本
ToString
()
细节20细说可空类型
在访问数据库数据时可能获得的数据为空值,这时可以考虑使用可空类型来定义字段或方法以更好的使用类来操作数据。
int
i=null;
int?
等价于System.Nullable<int>
细节21分部类
public partial class Person
{}
开发分部类时,要成为同一类型的各个部分的所有分部类类型定义必须都在同一个程序集或者同一模快中。(。exedll)中进行定义,分部类定义不能跨越多个模块。
细节22匿名方法
匿名方法:在事件注册时直接将一个委托与一段代码相关联,这种代码就是匿名方法。
Sendbtn.Click+=delegate{"sda"};
定义委托的后面要加上分号。
delegate void Msg(string str)//
定义委托
public void GetMsg(string str)//
定义与关联委托匹配的方法
{Response.Write("dads");}
Msg d =delegate(string str){Response.Write(str);}//
委托与匿名方法的关联
Msg d= new Msg(GetMsg);//
委托与命名方法关联
Sendbtn.Click+=delegate{Response.Write("safsaf");};//
事件处理程序为匿名方法
细节23net框架提供的属性(attribute
net框架提供了内置属性,这些属性都是从System.Attribute类派生而来的。
Conditional
属性是System.Diagnostics.ConditionalAttribute的别名,该属性仅用于方法声明,即仅在C#编译器定义了作为属性参数出现的符号时,他才指定方法作为类的一部分
[Conditional(“
参数”)]
启用调试状态时才作为类的一部分可以被调用,
Obsolete
属性用于定义正被替换或者不再有效的代码。该属性有两个参数MessageIsErrorMessage用于设置错误信息字符串,IsError默认为false表示在编译代码时发出警告信息,True表示编译器将生成错误信息。
细节24自定义属性类(Attribute
自定义属性类派生于SystemAttribute

自定义属性类的特定:

1.使用AttributeUsage属性可以限制属性的用法。

2.AttributeUsage属性中可以指定是否可以多次使用属性。

3.可以设置属性参数。

    [AttributeUsage(AttributeTargets.Class,AllowMultiple = true)]//AttributeTargets.Class表示限制仅用于类。 AllowMultiple = true表示可以多次使用属性
    public class BookAttribute : Attribute
    {
        private string BookName;
        public BookAttribute(stringbookname)//
设置属性参数
        {
            this.BookName= bookname;
        }
        public string Book
        {
            get
            {
                returnBookName;
            }
        }
    }
    //
多次使用属性类
    [Book("
细说ASP.NET;")]
    [Book("
范例手册")]
    public class BookInfo
    {
        public string binfo = "
图书信息-------";
        public BookInfo() { }
    }

     protected void Page_Load(object sender,EventArgs e)
        {
            BookInfobf = new BookInfo();
            object[]Bookattr;
            System.Reflection .MemberInfo  Typeinfo=typeof (BookInfo );
            //
提取类型是属性类的成员
            Bookattr= Typeinfo.GetCustomAttributes(typeof (BookAttribute ),false );
            if (Bookattr.GetLength(0)!= 0)
            {
                BookAttributeba = (BookAttribute)Bookattr[0];//
获取属性类的第一个成员
                BookAttributeba2=(BookAttribute )Bookattr [1];//
获取属性类的第二个成员
            }

}
细节25泛型
细节26包含/委托
类似适配器模式,把类中定义对象,然后自定义方法,然后在方法体中用到定义的对象中的方法。
细节27实现迭代器
迭代器是可以返回相同类型值的有序序列的一段代码,可用做方法、运算符或get访问器的代码体。可以在类中实现多个迭代器,每个迭代器都必须像类成员一样有唯一的名称。并且可以再foreach语句中被客户端代码调用。迭代器的返回类型必须为IEnumerableIEnumerator中任意一种,也可以是实现这两个接口的类。
IEnumerable
接口:包含了。net框架用于从对象中提取元素的方法。如果类包含一个元素的集合,并希望其他代码段使用foreach循环语句遍历该集合中的每一个元素则应该在类上实现该接口。
IEnumerable
接口值包含一个方法定义GetEnumerator(),用于返回一个循环访问集合的枚举数。
IEnumerator
接口:支持对非泛型集合的简单迭代。该接口定义了一个属性和两个方法
1.Object Current{get}
属性,获取集合中的当前元素
2.bool MoveNext()
方法,访问集合的下一个元素
3.void Reset()
方法,设置枚举数为其初始位置。
使用时必须引用SystemCollection命名空间
public class Car : IEnumerable, IEnumerator
    {
        private short flag = -1;
        public IEnumeratorGetEnumerator()
        {
            return  this;
        }
        public object Curretn
        {
            get
            {
                switch(flag)
                {
                    case0:
                        return"aodi";
                    case1:
                        return"huangguan";
                    default:
                        return"this is Error";
                }
            }
        }
        public bool MoveNext()
        {
            flag++;
            if(flag==2)
            {
                returnfalse;
            }
            returntrue;
        }
        public void ReSet()
        {
            flag =-1;
        }
    }
 static void Main(string[] args)
        {
            Car car= new Car();
            foreach(string s in car)
            {
                Response.Write(s+"</br>");
            }
        }
使用C#中的yield return命令也可以实现迭代器
细节28压缩和解压缩流的方法
在。net中,systtem.Io.Strem 类是所有流类型的虚基类。操作文件的FileStrem,操作内存的MemoryStrem操作网络的NetworkStrem
Stream
类的Read()方法用于从当前流中读取字节序列。
public abstract int Read
()
{
  byte[] buffer,//
字节数组
  int offset,//
表示从开始读取的位置
  int count//
读取的最大字节数
}
Stream
类的Write()方法用于从当前流中写入字节序列。并返回写入的字节数
public abstract int Write
()
{
  byte[] buffer,//
字节数组
  int offset,//
表示从开始写入的位置
  int count//
写入的字节数
}
一般情况下,对文件或数据可以进行压缩或解压缩操作。实质上就是对流的操作。在。net框架的System.IO.Compression命令空间下提供了GZipStream类,可以实现对流的压缩和解压缩。
public GZipStream
(
  Stream stream;//
要压缩或解压缩的流
  CompressionMode mode;//
要采取的操作(Compress压缩流或Decompress解压缩流)
  bool leaveOpen
true表示将流保留为打开状态,false表示流为关闭状态)
)
 //
定义一个用于读取指定数据流中的数据的方法
        private const intbufferlength=1024;
        public static Byte[]ReadBytes(Stream stream, int bufferlength)
        {
           Byte[]buffer=newByte  [bufferlength ];
           List<Byte>data = new List<Byte>();
           int real;
           while ((real= stream.Read(buffer, 0, bufferlength)) > 0)
           {
               if(real < bufferlength)
               {
                   Byte[]temp = new Byte[real];
                   Array.Copy(buffer,temp, real);
                   data.AddRange(temp);
               }
               else
               {
                   data.AddRange(buffer);
               }
           }
           returndata.ToArray();
        }
         //
定义一个向当前流中写入字节数组数据
        public static voidWriteBytes(Stream stream, Byte[] data, int bufferlength)
        {
           Byte[]buffer=newByte[bufferlength ];
           for (long g =0; g < data.LongLength; g += bufferlength)
           {
               intle = bufferlength;
               if(g + bufferlength > data.LongLength)
               {
                   le=(int)(data.LongLength-g);
               }
               Array.Copy(data,g,buffer,0,le);
               stream.Write(buffer,0,le);
           }
        }
        //
自定义方法压缩流,并调用前面定义的方法
        //
压缩字节数据
        public Byte[]CompressByte(Byte[] data)
        {
            using(MemoryStream ms = new MemoryStream())
            {
                //
提供压缩内存流的方法
                using(System.IO.Compression.GZipStream gs = new System.IO.Compression.GZipStream(ms,CompressionMode.Compress, true))
                {
                    WriteBytes(gs,data,bufferlength);//
将数据写入压缩流
                }
                returnms.ToArray();//
返回压缩后的数据
            }
        }
        //
自定义方法解压缩流
        public static Byte[]DeCompressByte(Byte[] data)
        {
            using(MemoryStream ms = new MemoryStream(data ))//
数据存于内存流
            {
                //
提供解压缩的方法
                using(System.IO.Compression.GZipStream gs = new System.IO.Compression.GZipStream(ms,CompressionMode.Decompress, true))
                {
                    returnReadBytes(gs, bufferlength);//
读取解压缩流中的数据
                }
               
            }
        }
细节29C#中的深复制和浅复制
浅复制是指复制一个对象的时候,复制原始对象中所有的非静态值类型成员和所有的对应类型成员的引用
深复制是指不仅仅复制所有的非静态值类型成员,而且还复制所有引用类型成员的实际对象。
细节30全角字符转换为半角
全角字符是指一个字符占用两个标准字符位置。
半角字符是指一个字符占用一个标准字符的位置。
 //
判断字符是否英文半角字符或标点
        public static boolIsHalflChar(char c)
        {
            int i =(int)c;
            returni >= 32 && i <= 126;

        }
        //
判断字符是否全角或标点
        public static boolIsAllChar(char c)
        {
            if(c=='\u3000')returntrue ;
            int i=(int )c-65248;
            if (i< 32) return false;
            returnIsHalflChar((char)i);

        }
        //
将字符串中的全角字符转换和为半角
        public static stringaToh(string s)
        {
            if(s==null||s.Trim ()==string.Empty )return s;
            StringBuildersb = new StringBuilder(s.Length );
            for(int i = 0; i < s.Length; i++)
            {
                if(s[i] == '\u3000') { sb.Append('\u0020'); }
                elseif (IsAllChar(s[i])) { sb.Append((char)((int)s[i] - 65248)); }
                else
                    sb.Append(s[i]);
            }
            returnsb.ToString();
        }
细节31分析路径字符串函数总结
相对路径:指相对对于网站地址的文件路径。
绝对路径:指磁盘上的一个指定位置。
C#
中通过Path类的相关方法可以分析路径字符串。
GetDirectoryName
:返回指定路径字符串的目录信息
GetExtension
:返回指定的路径字符串的扩展名
GetFullPath:
返回指定路径字符串的绝对路径
GetPathRoot:
获取指定路径的根目录信息
HasExtension
:确定路径是否包含文件扩展名
IsPathRooted:
获取一个值,该值指示指定的路径字符串是包含绝对路径信息true还是包含相对路径信息false
 //
分析路径字符串
        protected void FenSi()
        {
            stringstr = string.Empty;
            stringpath1 = "c:\\temp\\blog.txt";
            stringpath2 = @"c:\\temp\\blog";
            stringpath3 = @"Record";
            if(Path.HasExtension(path1))
            {
                str= string.Format("
路径{0});下有一扩展名为{1}的文件,属于目录{2}", path1, Path.GetExtension(path1), Path.GetDirectoryName(path1));
            }
            if(Path.IsPathRooted(path2))
            {
                string.Format("
路径{0}的根目录为{1}",path2 ,Path .GetPathRoot (path2));
            }
            str =string.Format("
路径{0}的全路径为{1}",path3,Path .GetFullPath (path3));
        }
细节32重载一元。二元运算符
细节33对象也能排序
System.Array
类提供的Sort()静态方法可以根据数字、字母顺序对数组中的项进行排序。
System.ICompareTo()
接口指定了一种允许一个对象可基于某些特定键值进行排序的方法。该接口提供一个CompareTo()方法用于比较当前实例与同一类型的另一个对象。
返回值小于0表示当前实例小于另一个对象。
 public class Student : IComparable
    {
        private int sid;
        public string name;
        public Student(int sid, stringname)
        {
            this.sid= sid;
            this.name= name;
        }
        public int ID
        {
            get{returnsid;}
            set {sid = value; }
        }
        intIComparable.CompareTo(object obj)
        {
            Students = (Student)obj;
            if(this.sid > s.sid)
            {
                return1;
            }
            if (this.sid< s.sid)
            {
                return-1;
            }
            else
                return0;
        }
    }
string str = string.Empty;
            Student[]arr=new Student [4];
            arr[0]= new Student(65,"
张三");
            arr[1]= new Student(62, "
张三");
            arr[2]= new Student(63, "
张三");
            arr[3]= new Student(63, "
张三");
            Array.Sort(arr);//
对象排序
            foreach(var item in arr)
            {
 
            }
细节34实现IDisposable接口清除对象
利用。net框架提供的方法处理非内存资源,也就是通过实现IDisposable接口来释放非托管的资源。
IDisposable
接口:它的Dispose()方法用于执行与释放或重置非托管资源相关应用程序定义的任务。
using语句提供的对象必须实现IDisposable接口,此接口提供了Dispose()方法,该方法释放资源。
public class Test : IDisposable
    {
        public Test()
        {Console.WriteLine("a"); }
        ~Test()
        {Console.WriteLine("b"); }
        public void Dispose()
        {
            Console.WriteLine("c");
        }
    }
 static void Main(string[] args)
        {
            try
            {
                using(Test te = new Test())
                {
                    thrownew Exception("safaf");
                }
            }
            catch {}
        }
运行结果:
a
c
b
细节35将字符串转成字符数组
net框架在System.IO命名空间下的StringRead类可以实现把字符串转换为字符数组
StringRead
类的Read()方法用于读取输入字符串中的字符快
public override int Read
()
{
  char[] buffer,//
读取到的字符数组
  int index,//
表示从开始读取的位置
  int count//
要读取的字符数
}
  //
将字符串转换为字符数组
        protected void ZhuanHuan()
        {
            stringstr = "are you Read";
            char[]c=newchar[200];
            StringReadersr = new StringReader(str);
            sr.Read(c,0,19);
        }
细节36将字符数组写入到字符串
StringBuider
类和StringWriter类可以实现
public override int Read
()
{
  char[] buffer,//
读取到的字符数组
  int index,//
表示从开始读取的位置
  int count//
要读取的字符数
}
 //
将字符数组写入字符串
        protected void Zhuan()
        {
            StringBuildersb = new StringBuilder("One World");
            char[]c = { '.','0','n','e','c','d',};
            StringWritersw = new StringWriter(sb);
            sw.Write(c,0,4);
        }
细节37使用var创建隐型局部变量
var
关键字指示编译器能根据变量的初始化表达式推断出变量的类型。
细节38Lambda表达式
构成:一个参数列表,Lambda操作符(=>,表达式()或语句块{}
Lambda
表达式有两种。Lambda操作符右边是表达式的叫做表达式Lambda,如果是一个大括号括起来的任意多条语句,那就是语句Lambda
Lambda
表达式赋值给委托类型必须满足一下条件:
1.Lambda
表达式与委托类型的参数个数相同
2.Lambda
表达式的每个参数都能被隐式的转化为委托类型的参数类型
3.Lambda
表达式的返回值能够被隐式转化为委托类型的返回值类型。
 delegate int AddOne(int i);
        delegate int ToAdd(int i,intj);
        delegate void Method();
        delegate int Method1();
        protected void Lambda()
        {
            AddOneaddone;
            addone= x => x + 1; //
隐式类型,表达式方式体
            addone= x => { return x + 1; };//
隐式类型,语句方法体
            addone= (int x) => x + 1;//
显示类型,表达式方式体
            addone= (int x) => { return x + 1; };//
显示语句方法体类型,
            ToAddmyto = (x, y) => x + y;//
多个参数
            Methodmethod1 = () => { };//
无参数,表达式方式体
            Method1  method2= () => 1;//
无参数,语句方法体

        }
细节39生成缩略图的方法
Web
应用中传输较大图片时除了采用压缩格式传输外,还可以使用缩略图的方式加快浏览速度。
生成图片缩略图主要应用了Image类的GetThumbnailImage()方法
该方法返回当前Image实例的缩略图
public Image GetThumbnaiImage(
  int thumbWidth,//
请求的缩略图的宽度
  int thumbHeight,//
请求的缩略图的高度
  Image.GetThuumbnailImageAbort callback,//
创建一个委托并在该参数中传递对此委托的引用。
  IntPtr callbackData//
必须为Zero
)
 //
生成缩略图
        /// <summary>
        ///
        /// </summary>
        /// <paramname="imgPath">
原图片路径</param>
        /// <paramname="thumbPath">
缩略图存储路径</param>
        /// <paramname="width">
原图片的宽度</param>
        /// <paramname="height">
高度</param>
        private void Thumb(stringimgPath, string thumbPath, double width, double height)
        {
            //
生成缩略图
            System.Drawing.Imageimage = System.Drawing.Image.FromFile(imgPath  );
            System.Drawing.Image.GetThumbnailImageAbortcallb = null;
            int w,h;
            //
根据实际的宽度和高度确定缩略图的宽高
            if(width > height)
            {
                w= 100;
                h= Convert.ToInt32(Convert.ToSingle(height) / Convert.ToSingle(width)) * 80;

            }
            else
            {
                h= 100;
                w= Convert.ToInt32(Convert.ToSingle(width ) / Convert.ToSingle(height )) * 80;
            }
            System.Drawing.Imagenewimage = image.GetThumbnailImage(w,h,callb,new System .IntPtr ());
            //
上传缩略图
            newimage.Save(thumbPath);
            newimage.Dispose();
            image.Dispose();

        }
细节40使用缓冲流
net框架提供的在System.Io命令空间下的BufferedStream类可以实现缓冲数据,减少对操作系统的调用次数。
BufferedStream
类提供从基础数据源或存储库读取字节以及将字节写入基础数据源或存储库的实现,在不需要缓冲区时可以防止缓冲区降低输入和输出速度。
BufferedStream
类的Read()方法用于从当前缓冲流复制到字节数组
public overrider int Read
()
{
  byte[] array,//
复制到的字节数组
  int offset,//
表示从开始读取的位置
  int count//
要读取的字节数
}
BufferedStream
类的Write()方法将字节复制到缓冲流
public override int Write
()
{
  byte[] array,//
从字节数组中复制数据
  int offset,//
表示从开始写入的位置
  int count//
写入的字节数
}
    //
将一个文件的内容复制到另一个文件
        /// <summary>
        ///
        /// </summary>
        /// <paramname="oPath">
源文件路径</param>
        /// <paramname="copyPath">
目标文件路径</param>
        private void Buf(string oPath,string copyPath)
        {
            Streams1, s2;
            BufferedStreambs1, bs2;
            byte[]b=newbyte[1024];
            int i;
            //
分别以读写方式打开文件
            s1 =File.OpenRead(oPath );
            s2 =File.OpenWrite(copyPath );
            //
使用缓冲流
            bs1 =new BufferedStream(s1 );
            bs2 =new BufferedStream(s2);
            i =bs1.Read(b,0,1024);
            //
从文件1中读取写入到文件2
            while(i > 0)
            {
                bs2.Write(b,0,i);
                i= bs1.Read(b,0,1024);
            }
            bs2.Flush();
            s1.Close ();
            bs2.Close ();

        }

第五篇 必知必会的28ADO.NET.XML.LINQ方面的技术细节

ADO.NET

细节01 ADO.NET调用存储过程插入数据

            SqlConnectioncon = null;
            stringstr="
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                SqlCommandcmd = new SqlCommand("
存储过程名称",con );
                cmd.CommandType= CommandType.StoredProcedure;
                cmd.Parameters.Add("@UserName",SqlDbType.VarChar,50).Value="pyj";
                cmd.Parameters.Add("@UserPwd",SqlDbType.VarChar,50).Value="sa";
                cmd.ExecuteNonQuery();
            }
           //createprocedure User
           // (@UserNamevarchar(50),
           //  @UserPwdvarchar(50)
           // )
           // as
           // insertinto UserInfo(UserName,UserPwd)values(@UserName,@UserPwd)
细节02 ADO.NET调用存储过程查询数据
CommandBehavior
枚举用于提供对查询结果和查询对数据库影响的说明,.CloseConnection表示在执行该命令时如果关闭关联的DataReader对象,则关联的Connection对象也将关闭
 SqlConnection con = null;
            stringstr="
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                SqlCommandcmd = new SqlCommand("
存储过程名称",con );
                cmd.CommandType= CommandType.StoredProcedure;
                cmd.Parameters.Add("@UserName",SqlDbType.VarChar,50).Value="pyj";
                cmd.Parameters.Add("@UserPwd",SqlDbType.VarChar,50).Value="sa";
                SqlDataReaderdr = cmd.ExecuteReader(CommandBehavior .CloseConnection );
                if(dr.Read())
                {
                    Console.Write("
登陆成功");
                }
            }
           //createprocedure User
           // (@UserNamevarchar(50),
           //  @UserPwdvarchar(50)
           // )
           // as
            //select id from UserInfo where UserName=@UserNameand UserPwd=@UserPwd
细节03 ADO.NET仅影响一行的数据操作
在数据库中插入一条数据,更新一条数据,删除一条数据,这些都可以称为仅影响一行的数据操作。
 //
使用DataAdapter对象如何插入删除更新数据。
           
            SqlConnectioncon = null;
            stringstr = "
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                //
插入数据
                stringsqlstr = "select * from UserInfo";
                SqlDataAdapterda1 = new SqlDataAdapter();
                SqlCommandinsertcmd = new SqlCommand(sqlstr, con);
                SqlCommandBuildercb = new SqlCommandBuilder(da1);//
自动生成插入数据的SQL语句
                da1.SelectCommand= insertcmd;//
必须设置此项
                DataSetds = new DataSet();
                intcount = da1.Fill(ds, "UserInfo");
                if(count > 0)
                {
                    DataRowdr = ds.Tables["UserInfo"].NewRow();
                    dr["UserName"]= "
小王";
                    dr["UserPwd"]= "111";
                    ds.Tables["UserInfo"].Rows.Add(dr);
                    da1.Update(ds,"UserInfo");

                }
                //
更新数据

                sqlstr= "select * from UserInfo where UserName=@UserName";
                SqlDataAdapterda2 = new SqlDataAdapter();
                SqlCommandupdatecmd = new SqlCommand(sqlstr ,con);
                updatecmd.Parameters.Add("@UserName",SqlDbType.VarChar,50).Value ="xiaowang";
                SqlCommandBuildercb2 = new SqlCommandBuilder(da2);//
自动生成更新插入数据的SQL语句
                da1.SelectCommand= updatecmd;
                DataSetds2 = new DataSet();
                intcount2 = da2.Fill(ds2, "UserInfo");
                if(count2 > 0)
                {

                    ds2.Tables["UserInfo"].Rows[0]["Pwd"]= "000";
                    da2.Update(ds2,"UserInfo");

                }
                ds2.Clear();
                //
删除数据
                sqlstr= "select * from UserInfo";
                SqlDataAdapterda3 = new SqlDataAdapter();
                SqlCommanddeletecmd = new SqlCommand(sqlstr, con);
               
                SqlCommandBuildercb3 = new SqlCommandBuilder(da3);//
自动生成更新插入数据的SQL语句
                da1.SelectCommand= deletecmd;
                DataSetds3 = new DataSet();
                intcount3 = da3.Fill(ds3, "UserInfo");
                if(count3 > 0)
                {

                    ds3.Tables["UserInfo"].Rows[0].Delete();
                    da3.Update(ds3,"UserInfo");

                }
                ds3.Clear();

            }
细节04 ADO.NET返回多行数据操作
 SqlConnection con = null;
            stringstr = "
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                stringsqlstr = "select * from UserInfo";
                SqlCommandcmd = new SqlCommand(sqlstr, con);
                cmd.CommandType= CommandType.Text;
                SqlDataReaderdr = cmd.ExecuteReader(CommandBehavior .CloseConnection );
                while(dr.Read())
                {
                    Console.WriteLine(dr["UserName"]);
                }
细节05 ADO.NET影响多行的数据操
 SqlConnection con = null;
            stringstr = "
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                //
插入数据
                stringsqlstr = "select * from UserInfo";
                SqlDataAdapterda1 = new SqlDataAdapter();
                SqlCommandinsertcmd = new SqlCommand(sqlstr, con);
                SqlCommandBuildercb = new SqlCommandBuilder(da1);//
自动生成插入数据的SQL语句
                da1.SelectCommand= insertcmd;//
必须设置此项
                DataSetds = new DataSet();
                intcount = da1.Fill(ds, "UserInfo");
                if(count > 0)
                {
                    //
第一行
                    DataRowdr = ds.Tables["UserInfo"].NewRow();
                    dr["UserName"]= "
小王";
                    dr["UserPwd"]= "111";
                    ds.Tables["UserInfo"].Rows.Add(dr);
                    //
第二行
                     dr= ds.Tables["UserInfo"].NewRow();
                    dr["UserName"]= "
小王";
                    dr["UserPwd"]= "111";
                    ds.Tables["UserInfo"].Rows.Add(dr);
                    da1.Update(ds,"UserInfo");

                }
                //
更新数据

                sqlstr= "select * from UserInfo";
                SqlDataAdapterda2 = new SqlDataAdapter();
                SqlCommandupdatecmd = new SqlCommand(sqlstr ,con);
                SqlCommandBuildercb2 = new SqlCommandBuilder(da2);//
自动生成更新插入数据的SQL语句
                da1.SelectCommand= updatecmd;
                DataSetds2 = new DataSet();
                intcount2 = da2.Fill(ds2, "UserInfo");
                if(count2 > 0)
                {
                    for(inti=2;i<count2;i++)
                    {

                    ds2.Tables["UserInfo"].Rows[i]["Pwd"]= "000";
                    da2.Update(ds2,"UserInfo");

                }
                ds2.Clear();
                //
删除数据
                sqlstr= "select * from UserInfo ";
                SqlDataAdapterda3 = new SqlDataAdapter();
                SqlCommanddeletecmd = new SqlCommand(sqlstr, con);
                SqlCommandBuildercb3 = new SqlCommandBuilder(da3);//
自动生成更新插入数据的SQL语句
                da1.SelectCommand= deletecmd;
                DataSetds3 = new DataSet();
                intcount3 = da3.Fill(ds3, "UserInfo");
                if(count3 > 0)
                {
                    for(int i = 2; i < count3;i++ )
                    {
                        ds3.Tables["UserInfo"].Rows[i].Delete();
                    da3.Update(ds3,"UserInfo");

                }
                ds3.Clear();
细节06 ADO.NET得到多组数据
应用DataReader对象的NextResult()方法在读取批处理SQL语句结果时,使数据读取器前进到下一个结果集。
 SqlConnection con = null;
            stringstr = "
联接字符串";
            using(con = new SqlConnection(str))
            {
                con.Open();
                stringsqlstr = "select * from UserInfo;select * from UserOrder";//
多个查询语句
                SqlCommandcmd = new SqlCommand(sqlstr, con);
                cmd.CommandType= CommandType.Text;
                SqlDataReaderdr = cmd.ExecuteReader(CommandBehavior .CloseConnection );
                intnum = 1;
                for(; ; )
                {
                    Console.WriteLine("*******
{0}中的内容*****", num.ToString());


                    while(dr.Read())
                    {
                        stringstrr = string.Empty;
                        for(int i = 0; i < dr.FieldCount; i++)
                        {
                            str= strr + dr[i] + ".";

                        }
                        Console.WriteLine(dr["UserName"]);
                    }
                    if(!dr.NextResult())
                    {
                        break;
                    }
                    else
                    {
                        num++;
                    }
                }
            }

 

XML

细节07DataSet操作XML文件
DataSet
对象的ReadXML方法读取XML数据:将XML架构和数据读入到DataSet
public XmlReadMode ReadXML(string fileName)
DataSet
对象的WriteXml方法写入XML数据:
public void WriteXml(string fileName)
//
读取和写入XML
public void Read()
{
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("Employee.xml"));//
读取XML文件
gvEmployee.DataSource = ds;
gvEmployee.DataBind();
}
public void Write()
{
DataTable dt = new DataTable("Employee");
DataColumn dcId = new DataColumn("ID",typeof(string));
DataColumn dcName = new DataColumn("NAME",typeof(string));
DataColumn dcAGE = new DataColumn("AGE",typeof(string));
dt.Columns.AddRange(new DataColumn []{dcId,dcName,dcAGE});
DataRow dr = new DataRow();
dr["ID"]="Mr008";
dr["NAME"] = "xiaow";
dr["AGE"] = "87";
dt.Rows.Add(dr);
DataSet ds2 = new DataSet();
ds2.Tables.Add(dt);
//
读取原有的XML数据
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("Employee.xml"));
//
合并两个DataSet
ds.Merge(ds2);
ds.WriteXml((Server.MapPath("Employee.xml"));
Page.ClientScript.RegisterStartupScript(GetType (),"","aler('
写入成功');",true );
}
细节08 XML节点操作
1.插入节点
XmlDocument
类的ImportNode()方法和XmlElement类的AppendChild()方法可以实现向XML文件中插入新的节点。
XmlDocument
类的ImportNode()方法:用于将构造的XML节点添加到当前文档结构中。
public virturl XmlNode ImportNode(
XmlNode node,//
表示插入的节点
bool deep//
如果执行深层复制返回值为true)

XmlElement类的AppendChild()方法:将指定的节点添加到当前节点子节点列表的末尾
public virturl AppendChild(
XmlNode newChild//
添加的节点)
//
插入XML节点(一条记录)
public void Inert()
{
//
加入命名空间system.xml
//
构造一个XML节点
StringBuilder sb = new StringBuilder();
sb.Append("<Books>");
sb.Append("<Book>");
sb.Append("<Name>
数据库开发与应用</Name>");
sb.Append("<Author>
张三</Author>");
sb.Append("<ISBN>999</ISBN>");
sb.Append("</Book>");
sb.Append("</Books>");
//DOM
加载XML数据
//
此处可以扩展,可以加载一个XML文件

XmlDocument doc1 = newXmlDocument();
doc1.LoadXml(sb .ToString ());
//
读取XML文件
XmlDocument doc2 = new XmlDocument();
doc2.Load(Server.MapPath("Book.xml"));
//
XML文件中插入构造的XML节点
XmlNode newnode=doc2.ImportNode(doc1.DocumentElement .LastChild ,true );
//
保存修改
doc2.Save(Server.MapPath("Book.xml"));
Page.ClientScript.RegisterStartupScript(GetType(), "", "aler('
写入成功');", true);

//
插入一个XML叶节点
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("Book.xml"));
XmlNode root = doc.DocumentElement;//
获得根节点
int num = root.ChildNodes.Count;
//
遍历根节点下的子节点book,在该节点下添加子节点date

for (int i = 0; i < num;i++)
{
XmlElement Date = doc.createElement_x_x("Date");
Date.InnerText = "2010-9";
root.ChildNodes[i].AppendChild(Date );
}
doc.Save(Server.MapPath("Book.xml"));

}
2.
检索节点
使用XmlNode类的SelectNodes()方法可以从XML文件中检索指定节点,
public XmlNodeList SelectNodes(
string xpath //
检索匹配表达式

//
检索XML节点

public void Search()
{
XmlDocument doc=new XmlDocument ();
doc.Load (Server.MapPath("Employee.xml"));
XmlNodeList nodes;
XmlElement root=doc.DocumentElement ;
nodes =doc.SelectNodes ("descendant::Book[Nane='
细说asp.net']");
//
遍历符合检索条件的Book节点内容
foreach (XmlNode node in nodes )
{
for(int i=0;i<=nodes.Count ;i++)
{
string str=string.Empty ;
str+=node.ChildNodes [i].InnerText.ToString ();
}
}


}
3.
删除节点
使用XmlElement类的RemoveChild()方法执行删除XML文件中节点的操作
public XmlNode RemoveChild(
XmlNode oldChild //
要删除的XML节点

//
删除XML节点
public void Delete()
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("Employee.xml"));
XmlNodeList nodes;
XmlElement root = doc.DocumentElement;
nodes = doc.SelectNodes("descendant::Book[Nane='
细说asp.net']");
//
遍历符合检索条件的Book节点内容
foreach (XmlNode node in nodes)
{
root.RemoveChild(node );
}
doc.Save(Server.MapPath("Employee.xml"));
}
细节09 XmlReader读取XML
如果XML文件内容较少可以考虑以缓存方式访问(例如DOM技术),如果XML文件内容较大读入内存将占用很大的控件,这时可以考虑以非缓存的流方式访问。总得来说,流式操作最大的特点就是以时间换空间。
通过XmlReader类而已以非缓存的流方式读取XML数据。
XmlReader
类的Create()方法根据指定的XML文件路径创建一个XmlReader实例。
public static XmlReader(
string inputUrl //
表示XML文件路径
)
XmlReader
类的Read()方法用于依次读取XML文件的节点。
public abstract bool Read():
如果成功读取下一个节点,返回true
XmlReader
类的NodeType属性:用于获取当前节点的类型。如XmlNodeTypeElement(元素标记)。XmlNodeType.EndElement(末尾元素标记)。XmlNodeType.Text(节点的文本内容)
//
XmlReader读取info.xml文件的数据
public void ReadXml()
{
using (XmlReader xr=XmlReader.Create (Server.MapPath("Employee.xml"))
{
while (xr.Read ())
{
switch (xr.NodeType )
{
case XmlNodeType.Element :
Console .Write ("<"+xr.Name );
while (xr.MoveToNextAttribute ())//
节点的属性
{
Console.Write (""+xr.Name +"="+xr.Value );
}
Console.Write (">");
break ;
case XmlNodeType .Text :
Console .Write (xr.Value );
break ;
case XmlNodeType .EndElement :
Console .Write ("</"+xr.Name +">");
break ;

}
}
细节10 XmlWrite写入XML
XmlWrite
类提供非缓存。只进的快速方式来生成包含XML数据的流或文件。常用的方法:
Create
:创建一个XmlWrite实例
WriteComment
:写出指定文本的注释
WriteStartElement
:写出指定的开始标记
WriteEndElement
:关闭一个元素(写出结束标记)
WriteElementString
:写出包含字符串的元素
WriteAttributeString
:写出指定值的属性。

//XmlWriteuser.xml文件中写入新的XML数据
public void WriteXml()
{
//
创建XmlWrite实例
using (XmlWriter xw=XmlWriter .Create (Server.MapPath("User.xml"))
{
xw.WriteComment ("
图书信息");//注释信息
//
根节点开始
xw.WriteStartElement ("Info");
//
定义子节点Record
xw.WriteStartElement ("Record");
xw.WriteAttributeString ("ID","001");//
附加属性
xw.WriteElementString ("Name","xiaoyu");
xw.WriteElementString ("Tele","000");
xw.WriteEndElement ();
//
定义子节点Record
xw.WriteStartElement ("Record");
xw.WriteAttributeString ("ID","002");//
附加属性
xw.WriteElementString ("Name","xiaowang");
xw.WriteElementString ("Tele","001");
xw.WriteEndElement ();
//
根节点结束
xw.WriteEndElement ();

}
}
细节11 DataReader对象与DataSet对象的区别
DataReader
:需要缓冲数据。正在处理的结果集太大而不能全部放入内容中。需要快速一次性的访问数据,采用只进的只读方式。

LINQ:

主要由3部分组成:LINQ to ObjectLING to ADO.NETLING to XML。其中LINQ to Object组件可以查询IEnumerableIEnumerable<T>集合,也就是说可以查询任何可枚举的集合。如数据(ArrayArrayList。)泛型列表List<T>。泛型字典Dictionary<T>等。以及用户自定义的集合,而不需要使用LINQ提供程序或API
细节12 对象的筛选操作
使用Where操作符可以筛选集合,Where方法中使用的是Lambda表达式
IEnumerable<string> result1 = color.Where(u =>u.IndexOf("||") > -1);
 protected void Page_Load(object sender, EventArgs e)
        {
            List<string>color = new List<string> { "red", "yellow","green", "black", "bule" };
            //
使用where字句
            varresult = from c in color
                         wherec.Length > 4
                         selectc;
            //
使用where操作符
            varresult2 = color.Where(u=>u.IndexOf ("ll")>-1);
            //
或者
            //IEnumerable<string>result1 = color.Where(u => u.IndexOf("ll") > -1);
            foreach(var item in result)
            {
                Response.Write(item+"</br>");
            }
            Response.Write("
查询包含子串ll的字符串:</br>");
            foreach(var item in result2)
            {
                Response.Write(item+"</br>");
            }
        }
细节13 对象的投影操作
LINQ
提供的Select操作符可以实现对象的投影操作。投影是指把正在查询的数据转换为各种结构的能力。
细节14 对象的排序操作
使用排序操作符可以对输入序列中的元素进行排序。
OrderBy
为升序排序,OrderByDescending为降序排序。OrderByOrderByDescending操作符要求传递类型为IEnumerable<T>的输入序列,返回一个类型为IOrderedEnumerable<T>的序列。
ThenBy
ThenByDescending操作符只能应用于IOrderedEnumerable<T>的序列,而不能应用于IEnumerable<T>的序列。也就是说,只有先使用OrderByDescendingOrderByDescending操作符,才能使用ThenByThenByDescending操作符。
 public class Person
    {
        private string Name;
        private int Age;
        private string Dept;
        public Person(string name, intage, string dept)
        {
            this.Name= name;
            this.Age= age;
            this.Dept= dept;
        }
        public string P_name
        {
            get {return Name; }
        }
        public int P_age
        {
            get {return Age; }
        }
        public string P_dept
        {
            get {return Dept; }
        }
    }
 protected void Page_Load(object sender, EventArgs e)
        {
            Person[]arr = new Person[]{
             newPerson ("
小王",12,"软件开发"),
             newPerson ("
小李",13,"软件开发"),
             newPerson ("
小菜",14,"软件开发"),
             newPerson ("
小张",15,"软件开发"),
             newPerson ("
小于",16,"软件开发"),
            };
            //
投影操作,插入额索引值
            varresult = arr.Select((p, index) => new { index ,p.P_name ,p.P_age ,p.P_dept});
            foreach(var item in result)
            {
                Response.Write(item+"</br>");
            }
            //orderby
字句排序操作,按年龄降序
            var a =from c in arr
                    wherec.P_dept == "
软件开发"
                    orderbyc.P_age descending
                    selectnew { c.P_name ,c.P_age };
            Response.Write("
使用orderby子句降序排序:</br>");
            foreach(var item in a)
            {
                Response.Write(item+"</br>");
            }
            //orderby
操作符
            var a1= arr.Where(p => p.P_dept == "
软件开发").OrderBy(p => p.P_age).Select(p => new { p.P_name, p.P_age});
            Response.Write("
使用orderby升序排序:</br>");
            foreach(var item in a)
            {
                Response.Write(item+ "</br>");
            }
            //orderbydescending
操作符
            var a2= arr.Where(p => p.P_dept == "
软件开发").OrderByDescending (p => p.P_age).Select(p => new { p.P_name,p.P_age });
            Response.Write("
使用OrderByDescending降序排序:</br>");
            foreach(var item in a)
            {
                Response.Write(item+ "</br>");
            }
            //ThenBy
操作符
            var a3= arr.Where(p => p.P_dept == "
软件开发").OrderBy(p => p.P_age).ThenBy(p => p.P_name).Select(p=>new { p.P_name ,p.P_age });
            Response.Write("
使用ThenBy升序排序:</br>");
            foreach(var item in a)
            {
                Response.Write(item+ "</br>");
              
            }
            //Reverse
反转操作符
            var a4= arr.Select(p => new { p.P_name ,p.P_age }).Reverse ();
        }
投影输出:
{ index = 0, P_name =
小王, P_age = 12,P_dept = 软件开发 }
{ index = 1, P_name =
小李, P_age = 13,P_dept = 软件开发 }
{ index = 2, P_name =
小菜, P_age = 14,P_dept = 软件开发 }
{ index = 3, P_name =
小张, P_age = 15,P_dept = 软件开发 }
{ index = 4, P_name =
小于, P_age = 16,P_dept = 软件开发 }
       
细节15 对象的聚合操作
Count
操作符可以返回输入序列中元素的数量
Sum
操作符可以返回输入序列的元素中包含的数字值的总和
Max
操作符可以返回输入序列的最大值
Mix
操作符可以返回输入序列的最小值
细节16 对象的集合操作
Distinct
操作符用来去除输入序列中的重复元素。
Intersect
(交集)操作符将返回两个源序列的交集
Except
(差集)操作符将返回第一个序列中没有出现在第二个序列中的所有元素组成的序列,
细节17 对象的元素操作
First操作符,用于从序列中返回符合条件的第一个元素。
Last
操作符,用于从序列中返回符合条件的最后一个元素。
Single
操作符:用于从序列中返回符合条件一个特定的,唯一的元素。
ElementAt
操作符,用于从序列中返回指定位置的特定元素。
细节18 对象的联接操作
Join
操作符可以对两个序列执行内部联接,该联接基于从序列中的每个元素提取键值。
 public class Order
    {
        private int id;
        private float Money;
        public Order(int id, floatmoney)
        {
            this.id= id;
            this.Money= money;
        }
        public int o_id
        {
            get {return id; }
        }
        public float o_money
        {
            get {return Money; }
        }
    }
public class User
    {
         private string Name;
        private int id;
       
        public User(string name, intid)
        {
            this.Name= name;
            this.id= id;
          
        }
        public string U_name
        {
            get {return Name; }
        }
        public int U_id
        {
            get {return id; }
        }
      
    }
protected void Page_Load(object sender, EventArgs e)
        {
            User[]arr = new User[]{
             newUser ("
小王",12),
             newUser ("
小李",13),
             newUser ("
小菜",14),
           
            };
            Order[]od = new Order[]{
              newOrder(12,130),
              newOrder (13,289),
              newOrder(14,333),
              newOrder (12,44),
              newOrder(13,555)};
            Order[]oo = new Order[]{
              newOrder(12,130),
              newOrder (13,289),
              newOrder(14,333),
              newOrder (12,44),
              newOrder(13,555)};
            //Count
操作符
            intresult = od.Count(u=>u.o_money >300);
            //Sum
操作符
            varuser = from o in od
                       whereo.o_id == 12
                       selectnew { o.o_id ,o.o_money };
            floatresult2 = user.Sum(o=>o.o_money );
            //
连接两个序列的情况下查询每个用户的消费情况
            varu_sum = from u in arr
                        joino in od
                        onu.U_id equals o.o_id
                        intouserorder
                        selectnew { u.U_name, Total = userorder.Sum(o => o.o_money) };
            //max
操作符
            var ma= (from o in od
                      whereo.o_id == 13
                      selectnew { o.o_id, o.o_money }).Max(o=>o.o_money );
            //min
操作符
            var mi= from u in arr
                     joino in od
                     onu.U_id equals o.o_id
                     intouserorder
                     selectnew { u.U_name, Mi = userorder.Min(o => o.o_money) };
            //Average
操作符
            varage=from u in arr
                     joino in od
                     onu.U_id equals o.o_id
                     intouserorder
                     selectnew {u.U_name ,Mi=userorder .Average  (o=>o.o_money )};
            //Distinct
避免重复操作
            vardistinct = (from o in od
                            selectnew { o.o_id, o.o_money }).Distinct();
            //Intersect
交集操作符
            varintersect =od.Intersect (oo );
            //Except
差集操作符,返回第一个序列中没有出现在第二个序列中的所有元素组成的序列
            varexcept=od.Except (oo );
            //
对元素操作
            varfirst=od.First (o=>o.o_money >100);
            varlast=od.Last (o=>o.o_money <300);
            varsingle=od.Single (o=>o.o_id ==1);//
返回产品id1的元素
            varelement=od.ElementAt (3);


                     

        }
细节19 查询DataSet中的单个表
LINQ to DataSet 组件可用于查询DataSet对象中的数据,并对这些数据进行检索、过滤、排序等操作。
LINQ
DataSet的查询,而DataTable类没有实现其中任一接口,必须调用AsEnumerable()方法使DataTable作为LINQ查询From字句的源。
AsEnumerable()
方法:该方法将DataTable对象转换为EnumerableRowCollection<DataRow>对象。
public static EnumerableRowCollection<DataRow> AsEnumerable
(
  this DataTable source
)
Field<T>:
该方法提供对指定行中的每个列值的强类型访问,
public static T Field<T>
{
this DataRow row,
string columnName
}
细节20 查询DataSet中的多个表
LINQ
可以通过join。。。。on 子句访问DataSet中的多个表。
细节21 DataSet进行投影操作
使用select子句可以实现DataSet的投影操作,即指从DataSet中选择内容返回到结果中。
细节22 DataSet进行筛选操作
使用where子句可以实现DataSet的投影操作,where子句指定筛选元素的逻辑条件,一般由逻辑运算符组成。一个查询表达式可以不包含where子句,也可以包含一个或多个where子句。每一个where子句可以包含一个或多个布尔条件表达式。
细节23 DataSet进行排序操作
orderby
子句可以对查询结果进行排序。且排序的主键可以是一个或多个。在orderby子句中升序使用ascending关键字,降序使用descending关键字。
细节24 DataSet进行聚合操作
LINQ提供了一组聚合操作符(MaxSumMin等)对DataSet实现聚合操作。
细节25 DataSet进行元素操作
LINQ提供了一组操作符(First.Last.Single等)对DataSet实现聚合操作。
细节26 DataSet进行联接操作
使用join...on 实现对DataSet中的联接操作。
细节27 DataSet进行数据分区作
Enumerable.Take(int count):
从序列的开头返回指定数量的连续元素。
使用Skip()方法:跳过序列中指定数量的元素,然后返回剩余的元素。
细节28 使用LINQ数据源控件
 protected SqlConnection conn;
        protected static stringConnectionString = "
连接字符串";
        protected void Page_Load(objectsender, EventArgs e)
        {
            using(conn = new SqlConnection(ConnectionString))
            {
                stringsqlstr = "select * from BookInfo";
                SqlDataAdapterda = new SqlDataAdapter(sqlstr,conn);
                conn.Open();
                DataSetds = new DataSet();
                da.Fill(ds,"BookInfo");
                sqlstr="select* form BookOrder";
              
                da.SelectCommand.CommandText =sqlstr ;
                da.Fill(ds ,"BookOrder");
                //
查找3月份出版的图书.包含投影,筛选知识点
                varresult = from b in ds.Tables["BookInfo"].AsEnumerable()
                             where(b.Field<DateTime>("b_pub_date").Month == 3)
                             selectnew {
                                          bookName=b["b_Name"].ToString(),
                                          author=b["b_pub_date"].ToString()};
                foreach(var item in result)
                {
                    Response.Write("
书名"+item.bookName +"出版日期"+item.author +"</br>");
                }
                //
排序
                varresult1= from b in ds.Tables ["BookInfo"].AsEnumerable ()
                             orderbyb.Field <DateTime >("b_pub_date")descending
                             selectnew
                             {
                                 bookName= b["b_Name"].ToString(),
                                 author= b["b_pub_date"].ToString()
                             };
                //
聚合操作

                varresult2 = from b in ds.Tables["BookInfo"].AsEnumerable()
                              selectb;
                decimaltotal = result2.Sum(d=>d.Field <decimal >("
书费"));
                //
元素操作
                varresult3 = from b in ds.Tables["BookInfo"].AsEnumerable()
                              selectb;
                if(result3.Count() > 0)
                {
                    DataRowdr = result3.Last();
                    Response.Write("
书名" + dr.Field <string>("书名"));
                }
                //
联接操作
                varresult4 = from b in ds.Tables["BookInfo"].AsEnumerable()
                              joinu in ds.Tables["BookOrder"].AsEnumerable()
                              onb.Field<string>("b_code").Trim() equals u.Field<string>("
书号").Trim()
                              selectnew
                              {
                                  b_code= b["b_code"].ToString(),
                                  b_order=u["
同类图书排名"].ToString ()
                              };
                //
分区操作
                vara = result4.Take(2);//
返回头两条记录
                varc = result4.Skip(1);//
跳过一条记录,返回剩余记录

第六篇 必知必会的22Web方面的技术细节

细节01 在网页中使用CSS的方式
1.
链接到外部的CSS样式表
<link rel="stylesheet" href="style.css"type="text/css">
2.<style>
标记嵌入CSS样式
<style type="text/css"></style>
3.
内联样式
<span style="color:Blue">
蓝色</span>
细节02 动态调用Javascript
Page.ClientScript.RegisterStarupScript(GetType(),"","alter('
您的输入有误,请重新输入!');history.back();",true);
ClientScriptManager
对象常用方法

细节03 Request对象获得信息
ASP.NET的内置Request对象用于检索从浏览器向服务器所发送的请求中的信息,它提供对当前页请求的访问,包括标题,Cookie,客户端证书,查询字符串等。
Request
对象的Params属性和QuerySting属性获取页面传递的值。Params属性获取的集合包括QueryString属性获取的集合。
Request
对象的Brower属性获取客户端浏览器信息。 HttpBrowserCapabilities bw = Request.Browser;
 protected void Page_Load(object sender, EventArgs e)
        {
            Response.Redirect("Prodece.aspx?param=1&param2=
产品&param3=广东");
            //
接收值
            Response.Write("
产品编号"+Request["param"]+"</br>");
            Response.Write("
产品名称"+Request["param2"]+"</br>");
            Response.Write("
产品产地"+Request["param3"]+"</br>");
        }
细节04 Response对象输出信息
ASP.NET的内置Response对象用于将数据从服务器发送回浏览器。它允许将数据作为请求的结果发送到浏览器中,并提供有关响应的信息。可以用来在页面中输入数据,在页面中跳转,还可以传递各个页面的参数。
Response
对象的Write()WriteFile()方法在页面上输出数据。
Response
对象的BinaryWrite()输出二进制图像。
 protected void Page_Load(object sender, EventArgs e)
        {
            strings = "we are the future";
            char[]carry = { 'a','b','c','d','d'};
            Response.Write(carry,0,carry .Length );//
输出数组
            Response.Write(s);//
输出字符串
            Response.WriteFile(Server.MapPath ("file.txt"));//
输入到文件中

            //输出二进制图片

            FileStreamstream = new FileStream(Server .MapPath ("pic.jpg"),FileMode.Open );
            longfileSize = stream.Length;
            byte[]buffter=new  byte[(int)fileSize ];
            stream.Read(buffter,0,(int )fileSize );
            stream.Close();
            Response.BinaryWrite(buffter);
        }
细节05 URL编码和解码
对字符串进行URL编码,可以确保所有浏览器都能正确的传输URL字符串中的文本。
Server.UrlEncode()
方法对字符串进行URL编码。这可解决ResponseRedirect()方法传递汉字丢失或者出现乱码的问题。
Server.UrlDecode()
方法对所接收的汉字进行URL解码。
 Response.Write(Server.UrlEncode ("http://www.baidu.com"));
            stringstr = Server .UrlEncode ("
解决汉字丢失");
            Response.Redirect("temp.aspx?param="+str);
            //
接收
            stringstr1 = Server.UrlDecode(Request.QueryString ["param"]);
细节06 取站点路径
Server.MapPath()方法可以获取服务器端的物理地址。
Server.MapPath(".")
获取当前目录所在服务器端的物理路径。
细节07 ViewState
视图状态(ViewState)是asp.net网页框架在访问过程中保留网页和控件值的默认方法。在呈现网页HTML标记时,系统会将回传过程中需要保留的网页或值的当前状态序列化为Base64编码字符串,并将字符串放入一个或多个隐藏字段。
 protected void Page_Load(object sender, EventArgs e)
        {
           //
保存字符串
            ViewState["course"]="math";
            //
保存整形数组
            int[]num = { 1,3,4};
            ViewState["num"]= num;
            if(ViewState["course"] != null)
            {
                Response.Write(ViewState["course"]);
            }
            if(ViewState["num"] != null)
            {
                int[]temp = ViewState["num"] as int[];
                foreach(int i in temp)
                {
                    Response.Write(i+"</br>");
                }
            }

        }
细节08 隐藏域
HiddenField
控件的value属性可以设置或获取保存的数据。value属性只能保存一个值且类型为字符串。设置value后,无论页面回传多少次,将一直保存。

细节09 Cookie
Cookie
对象用于保存客户端到浏览器请求服务器页面,也可用它存放非敏感性的用户信息,信息保存的时间可以根据用户的需要进行设置。
1.
存储一个Cookie变量:Response.Cookie[varname].Value=值。
2.
取回Cookie值:变量名=Request.Cookie[varname].value
3.
Cookie中的数据加密:Response.Cookie["data"].Value=Forms.Authentication.HashPasswordForStoringInCofigFile(data,"md5");
4.
创建及存取多个键值的Cookie对象:Response.Cookies["CookieName"]["KeyName"]="";
5.
设定Cookie变量的生命周期:Response.Cookies["CookieName"].Expires=日期
 protected void Page_Load(object sender, EventArgs e)
        {
           //
保存IP地址
            stringUserIP = Request.UserHostAddress.ToString();
            Response.Cookies ["IP"].Value =UserIP ;
            //
IP地址
            UserIP=Request.Cookies ["IP"].Value ;
            //
Cookie数据加密
            stringdata = "
我爱我家";
            Response.Cookies["IP"].Value=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(data,"
这是密码");
            //
存储多值
            Response.Cookies["UserInfo"]["UserName"]= "add";
            Response.Cookies ["UserInfo"]["UserPwd"]="111";
            //
设定Cookie变量的生命周期
            Response.Cookies["User"].Expires= DateTime.MaxValue;//
不过期
            Response.Cookies["User"].Expires= DateTime.Now.AddMonths(1);//
一个月过期
            Response.Cookies["User"].Expires= DateTime.Parse("10/10/2012");//
指定日期
        }
细节10 Application
Application
对象定义的变量为应用程序级变量,即为全局变量。变量可以再Globalasax文件或aspx页面中进行声明。
由于应用程序中的所有页面都可以访问应用程序变量,所以为了确保数据的一致性,必须对Application对象加锁。
 void Application_Start(object sender, EventArgs e)
        {
            //
在应用程序启动时运行的代码
            Application["count"]=0;
        }
 void Session_Start(object sender, EventArgs e)
        {
            //
在新会话启动时运行的代码
            Application.Lock();
            Application["count"]= (int)Application["count"] + 1;
            Application.UnLock();
        }

        void Session_End(objectsender, EventArgs e)
        {
            //
在会话结束时运行的代码。
            //
注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
            //InProc
时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
            //
SQLServer,则不会引发该事件。
            Application.Lock();
            Application["count"]= (int)Application["count"] -1;
            Application.UnLock();

        }
细节11 Session
会话变量(Session)只能用于会话中特定的用户,应用程序的其他用户不能访问或修改这个变量。session通过键值对的方式保存数据。
 Session["UserName"] = "asa";
细节12 定义主题
主题基于控件而不是HTML。主题应用在服务器上。
可以通过配置文件来应用主题。这样不必修改任何一个页面条件下对整个网站应用主题。
如果在一个主题和一个控件里同时指定了一个属性,那么主题里定义的值会覆盖控件的属性。
外观文件分为默认外观已命名外观两种类型。如果控件外观没有包含SkinID属性,那么就是默认外观。
控件外观设置的属性可以是简单属性,也可以是复杂属性(集合属性,模板属性,数据绑定表达式)
如何将主题应用于母版页中
答:不能直接将主题应用于母版页,而是在内容页中应用。
    
通过在Web.Config文件中的pages元素内设置主题定义可以使整个站点都应用主题。
细节13 应用主题
1.
为单个页面指定和禁用主题
<%@ Page Theme="ThemeName"%>
<%@ Page StyleSheetTheme="ThemeName"%>
使用StyleSheetTheme时,控件外观的设置可以被页面中声明的同一类型控件的相同属性所代替。
禁用主题:
<%@Page EnableTheming="false"%>
<asp:Button id="button1"runat="server" EnableTheming="false"/>
2.
为应用程序指定和禁用主题。
<system.web>
 <pages theme ="ThemeName"></pages>
    <pages styleSheetTheme="ThemeName"></pages>
</system.web>
禁用主题只有将Theme属性或StyleSheetTheme属性设置为空(""
细节14 动态加载主题
protected void Page_Load(object sender, EventArgs e)
        {
            stringurl = Request.Path + "?theme=ThemeName";
            Response.Redirect(url);
            //
接收
            if(Request.QueryString["theme"] != null)
            {
                stringa=Request .QueryString ["theme"];
                Page.Theme= a;//
使用PageTheme属性为页面指定主题
            }
        }
细节15 母板页
母版页中有几个ContentPlaceHolder控件,在内容页中就会有几个Content控件生成,Content控件的ContentPlaceHolderID属性值对应着母版页ContentPlaceHolder控件的ID值。
细节16 设置母版页应用范围
1.
页面级
可以再每个内容页中使用page指令将内容页绑定到一个母版页。
<%@ Page MasterPageFile="~/MasterPage.master"%>
2.
应用程序级
在配置文件中进行设置
<system.web>
 <pages masterPageFile ="MasterPage.master"></pages>
</system.web>
3.
文件夹级
只需在该文件夹中的一个web.config文件中进行设置,母版页绑定会应用于该文件夹中的所有页面,而不影响文件夹以外的页面。
细节17 数据格式验证
使用RegulareExpressionValidator控件可以验证用户输入是否与预定义的模式相匹配。
RegularExpressionValidator
控件常用属性
ControlToValidate
:表示要验证的控件ID
ErrorMessage
:验证不正确时,出现的错误信息
IsValid
:指示控件验证的数据是否有效
ValidationExpression
:指定验证的正则表达式。
细节18 ImageMap典型应用
ImageMap
控件允许在图片中定义一些热点(HotSpot)区域,当用户点击这些热点区域时,将会引发超链接或单击事件。当需要对某幅图片的局部实现交互时,使用ImageMap控件。
重要属性:HotSpotMode属性和HotSpots属性。
HotSpotMode
属性用于获取或设置单击热点区域后的默认行为方式。
HotSpots
属性用于获取Hotspots对象的集合。HotSpot类是个抽象类。它包含CircleHotSotRectangleHotSpotPolygonHotSpot

<asp:ImageMap ID="ImageMap1" runat="server"HotSpotMode="PostBack"
ImageUrl="~/QQ
截图20120418224737.png"onclick="ImageMap1_Click">
<asp:RectangleHotSpot AlternateText="
西北" Bottom="100" HotSpotMode="PostBack"
PostBackValue="NW" Right="100" />
<asp:RectangleHotSpot AlternateText="
东北" Bottom="100" HotSpotMode="PostBack"
Left="100" PostBackValue="NE" Right="100" />
<asp:RectangleHotSpot AlternateText="
西南" Bottom="200" HotSpotMode="PostBack"
PostBackValue="SW" Right="100" Top="100" />
<asp:RectangleHotSpot AlternateText="
东南" Bottom="200" HotSpotMode="PostBack"
Left="100" PostBackValue="SE" Right="200"Top="100" />
</asp:ImageMap>
protected void ImageMap1_Click(object sender, ImageMapEventArgs e)
{
string region = "";
switch (e.PostBackValue)
{
case "NW":
region = "
西北";
break;
case "NE":
region = "
东北";
break;
case "SE":
region = "
东南";
break;
case "SW":
region = "
西南";
break;
}
this.Label5.Text = "
您现在所指的方向是:"+region +"方向";
}

细节19 MultiViewView控件
MultiView
控件是一组View控件的容器。它允许定义一组View控件,其中每个View控件都包含子控件。在应用程序中可以根据条件向客户端呈现特定的View控件。还可以使用MultiView控件创建向导。
MultiView
控件重要属性:
ActiveViewIndex
属性:设置该控件的活动View控件的索引
BindingContainer
属性:包含对Control对象的引用,该对象包含当前控件的数据绑定信息。
MultiView
控件方法:
GetActiveView
():返回MultiView控件的当前活动View控件
SetActiveView():
将制定的View控件设置为MultiView控件的活动视图。
MultiView
控件事件:
ActiveViewChange
事件。
View
控件事件:
Activate
()事件:当前View控件成为活动视图时,引发Activate事件。
Deactivate
()事件:当前的活动View控件变成非活动时,引发Deactivate事件。
  protected void BackButton_Click(object sender, EventArgs e)
        {
            try
            {
                if(this.Multiview1.ActiveViewIndex > 0 & this.Multiview1.ActiveViewIndex< 3)
                {
                    this.BackButton.Visible= true;
                    this.Multiview1.ActiveViewIndex-= 1;
                }
                elseif (this.Multiview1.ActiveViewIndex == 3)
                {
                    this.Multiview1.ActiveViewIndex= 0;
                    this.BackButton.Visible= false;
                }
            }
            catch(Exception ee)
            {
                Response.Write("<script>alter('"+ ee.Message + "')</script>");
            }
        }

        protected voidNextButton_Click(object sender, EventArgs e)
        {
            try
            {
                if(this.Multiview1.ActiveViewIndex > -1 & this.Multiview1.ActiveViewIndex< 3)
                {
                    this.BackButton.Visible= true;
                    this.Multiview1.ActiveViewIndex+= 1;
                }
                elseif (this.Multiview1.ActiveViewIndex == 3)
                {
                    this.NextButton.Visible= false;
                    Response.Write("<script>alter('
填写完成')</script>");
                }
            }
            catch(Exception ee)
            {
                Response.Write("<script>alter('"+ee.Message+"')</script>");
            }
           
        }
细节20 Wizard控件典型应用
Wizard
控件提供了一种跨多个步骤收集相关数据的机制,允许轻松的生成步骤,添加新步骤或重新安排步骤。无需编写代码即可生成线性或非线性的导航。
Wizard
控件重要属性:
WizardSteps
属性:用于获取一个包含为该控件定义的所有WizardStepBase对象的集合
StepNextButtonText
属性:用于设置为Star步骤中的下一步按钮显示的文本标题
Wizard
控件的方法
MoveTo
方法:将指定的从WizardStepBase派生的对象设置为Wizard控件的ActivateStep属性的值。
SetRenderMethodDelegate
方法:分配事件处理程序的委托,以将服务器控件以及内容呈现到父控件中。
Wizard
事件:
CancelButtonClick
:当单击Wizard控件的取消按钮会引发该事件。
FinishButtonClick

NextButtonClick

PreviousButtonClick:
细节21 DetailsView典型应用
DetailsView
控件是一个数据源绑定控件,该控件主要功能是将数据表中的数据源以单一数据行的方式呈现给用户,同时控件本身还有SelectInsertUpdateDelete等功能。通常用于更新和插入新数据,并且是在主/详方案中使用。主控件要选取记录,然后在DetailsView控件中显示出该记录。
GridView
控件虽然是asp.net中非常重要的控件,但它本身并不具有添加信息的功能,所以必须通过与DetailView控件的结合才能完成信息添加的功能。
细节22 BulletedList典型应用
BulletedList
控件用于创建一个无序或有序列表,他们呈现为html ulol元素,可以指定项项目符号或编号的外观,
BulletedList
属性:
Items
属性
BulletImageUrl
属性:设置为BulletedList控件中的每个项目符号显示的图像的路径。更改此属性时,首先把BulletStyle属性设置成CustomImage
 protected void Page_Load(object sender, EventArgs e)
        {
            if(!IsPostBack)
            {
                string[]str = new string [3];
                str[0]= "
父亲节";
                str[1]= "
母亲节";
                str[2]= "
国庆节";
                this.BulletedList1.BulletStyle= BulletStyle.Circle;
                for(int i = 0; i < str.Length; i++)
                {
                    this.BulletedList1.Items.Add(str[i]);
                }
                this.BulletedList1.BulletStyle= BulletStyle.CustomImage;
                for(int i = 0; i < str.Length; i++)
                {
                    this.BulletedList1.Items.Add(str[i]);
                }
            }
        }

 

第七篇 必知必会的30个语言方面的技巧

技巧01PareTryParse的区别
使用Pare方法进行类型转换时无法知道转换是否成功。int.TryParse()方法将传入的字符串转换为整数,如果转换成功返回true,否则返回false
 string a = "123";
 int i;
 if (int.TryParse(a,out i))
 {
   Response.Write(i);
}
技巧02 变量的默认值
如果忘记某个类型的默认值时,可使用default关键字。如果表达式中的类型是引用类型,则返回null
int i=default (int);
double d=default (double );
string s=default (string);
技巧03 判断字符串是否为空
 string a = "";
 if (string.IsNullOrEmpty(a))
{
    Response.Write("
密码不能为空");
 }
技巧04 使语句执行安全的数字计算
将一个数字运算包含在checked运算符中,如果该运算没有意义,就会引发一个异常。
int i = 20000000;
int j = 30000000;
int k=checked (i+j);
Response.Write(k);
技巧05 多用Foreach语句
foreach语句用来遍历那些实现了IEnumerable的容器类型。但缺点是不能对项目进行赋值,
技巧06 理解按位求反运算符
将要运算的值视为二进制,并将值中所有位进行翻转,值为1变成0,0变成1
技巧07 关闭字符串中的特殊字符
@
符号不仅能使C#编译器忽略字符串中的特殊字符串,还能实现不分解成子串的情况下折行显示。
技巧08 接口和抽象类的选择。
技巧09 取枚举类子项的描述信息

       //取枚举类子项的描述信息
        public static stringGetEnumDescription(object enumSubitem)
        {
            enumSubitem=(System .Enum )enumSubitem ;//
将枚举类子项转换成Enum类型
            stringstrValue=enumSubitem .ToString ();//
取枚举类子项的值
           System.Reflection .FieldInfo   fieldinfo =enumSubitem.GetType().GetField(strValue );//
通过反射取枚举类子项的信息
           if (fieldinfo!= null)
           {
               //
取枚举类子项的描述信息
               Object[]objs =fieldinfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute),false);
               if(objs == null || objs.Length == 0)
               {
                   returnstrValue;
               }
               else
               {
                   System.ComponentModel.DescriptionAttributeda = (System.ComponentModel.DescriptionAttribute)objs[0];
                   returnda.Description;
               }
           }
           else
           {
               return"
不限";
           }
        }
        public enum Location
        {
            [IODescription("
")]
            left=0,
            [IODescription("
")]
            top=1,
            [IODescription("
")]
            right=2,
            [IODescription("
")]
            bottom=3
        }
 protected void Page_Load(object sender, EventArgs e)
        {
            stringDescriptStr = GetEnumDescription(Location .top );//
取得的描述信息是
            Response.Write(DescriptStr);

        }
技巧10 接口索引器
 interface interfacel
        {
            intthis[int dex] { get;set;}//
接口索引器
            eventEventHandler ClickEvent;//
接口事件
        }
技巧11 创建自己的Where操作符
扩展方法有3个必备条件:
1
方法所在的类必须是静态的
2
方法也必须是静态的
3
方法的第一个参数必须是你要扩展的那个类型(this只能在第一个参数前面出现)
扩展方法必须定义于非泛型的静态类中。扩展方法虽然能接受任意多个参数,但是第一个参数的类型必须与将要扩展的类型一致,且用this关键字修饰。定义扩展方法的代码如下:
public static IEnumerable<TSource> Where<TSource>(thisIEnumerable<TSource> source, Func<TSource, bool> predicate);
Func<TSource, bool>
:表示泛型委托。
static class MyWhere//
必须是顶级静态类
    {
        public staticIEnumerable<TSource> MyWhere<T>(this IEnumerable<TSource>source, Func<TSource, bool> predicate)//
第一个参数是所有实现IEnumerable接口的集合。第二个是匿名方法或Lambda表达式
        {
            foreach(TSource s in source)
            {
                if(predicate(s))
                {
                    yieldreturn s;
                }
            }
        }
    }
 protected void Page_Load(object sender, EventArgs e)
        {
            List<int>lst = new List<int> { 0,1,2,3,4,5,6,7,8};
            varquery = lst.MyWhere(item=>item %2==0);
            foreach(var item in query)
            {
                Response.Write(item+"</br>");
            }
技巧12 使用new关键字重复使用标示符
interface ParentInterface
        {
            intName { get; }
        }
        interface ChildInterface :ParentInterface
        {
            new intName();//
在方法前加new关键字
        }
技巧13 实现具有相同名称的接口方法
 interface Interface1
    {
        void DoWork();
    }
    interface Interface2
    {
        void DoWork();
    }
    class OurClass : Interface1, Interface2
    {

        void Interface1.DoWork()
        {
            thrownew NotImplementedException();
        }

        void Interface2.DoWork()
        {
            thrownew NotImplementedException();
        }
    }
技巧14 使用is关键字处理接口
 interface Interface1
    {
        void DoWork();
    }
  
    class OurClass1 : Interface1
    {

        void DoWork()
        {
            thrownew NotImplementedException();
        }

    }
    class OurClass2 : Interface1
    {

        public void DoWork()
        {
            thrownew NotImplementedException();
        }
    }
    class Message
    {
        public void ShowMessage()
        {
            OurClass1c1 = new OurClass1();
            OurClass2c2 = new OurClass2();
            ShowMessageFromObject(c1);
            ShowMessageFromObject(c2);
        }
        private voidShowMessageFromObject(object obj)
        {
            Interface1a;
            if (objis Interface1)
            {
                a=objas Interface1;
                a.DoWork();
            }
        }
    }
技巧15 使用非整数表示数组的索引
  public class Chessboard
    {
        private string[,] board;
        public Chessboard()
        {
            board =new string[5, 5] { { "A0", "A1", "A2","A3", "A4" }, { "B0", "B1","B2", "B3", "B4" }, { "C0","C1", "C2", "C3", "C4" }, {"D0", "D1", "D2", "D#", "D4"}, { "E0", "E1", "E2", "E3","E4" } };
        }
        public string this[char column,int rowIndex]
        {
            get
            {
                intcolIdx;
                switch(column)
                {
                    case'A':
                    case'a':
                        colIdx= 0;
                        break;
                    case'B':
                    case'b':
                        colIdx= 1;
                        break;
                    case'C':
                    case'c':
                        colIdx= 2;
                        break;
                    case'D':
                    case'd':
                        colIdx= 3;
                        break;
                    case'E':
                    case'e':
                        colIdx= 4;
                        break;
                    default:
                        thrownew Exception("
无效的列索引");

                }
                returnboard [colIdx ,rowIndex ];
            }
        }
    }
protected void Page_Load(object sender, EventArgs e)
        {
            Chessboardboard = new Chessboard();
            Response.Write(board['e',3]);

        }
技巧16 尽量用StringBuilder
技巧17 对比ArrayListList<>
技巧18 对比StackStack<T>
技巧19 对比QueueQueue<T>
技巧20 对比SortedListSortedList<T>
技巧21 进制转换技巧
Response.Write(Convert .ToString (69,2));//
十进制69转二进制
Response.Write(Convert .ToString (69,8));//
十进制69转八进制
Response.Write(Convert .ToString (68,16));//
十进制69转十六进制
Response.Write(Convert .ToInt32 ("100111101",2));//
二进制100111101转十进制 Response.Write(Convert .ToInt32 ("76",8));//八进制76转十进制
Response.Write(Convert .ToInt32 ("AE",16));//
十六进制转十进制
技巧22 什么是复制构造函数
将一个引用类型变量赋值给另一个变量时,在赋值的同时创建一个全新的对象,而不是将该引用赋值给变量,这就是复制构造函数。
 public class Student
    {
        private string _name;
        public Student(string name)
        {
            this._name= name;
        }
        public Student(Student s)
        { this._name = s._name; }
        public string Name
        {
            get {return _name; }
            set {_name = value; }
        }

    }
protected void Page_Load(object sender, EventArgs e)
        {
            Studentstudent = new Student("A");
            Studentnewstudent = new Student(student );
            student.Name= "B";


        }
技巧23 ToString的使用技巧
技巧24 什么时候使用密封类
如果不希望类中的代码被派生,可以用sealed关键字将该类标记为密封类
1.
类是静态类
2.
类包含带有安全敏感信息的继承的受保护成员
3.
类继承过个虚成员,并且密封每个成员的开发和测试开销明显大于密封整个类
4.
类是一个要求使用反射进行快速搜索的属性,密封属性可提高反射在检索属性时的性能。
技巧25 using关键字的用法
1.
using关键字命名类的别名
using OurClass1=OurNamespace.OurClass;
2.
using关键字为命名空间起别名
using Our1=OurNamespace1;
技巧26 对象和集合初始化器
声明对象的时候就可以设置各个属性的值。
 List<UserInfo> UserList=new List<UserInfo>
            {
                newUserInfo{ID=1,UserName="xiaoy",Passwor="111"},
                 newUserInfo{ID=1,UserName="xiaoy",Passwor="111"},
                  newUserInfo{ID=1,UserName="xiaoy",Passwor="111"},
            }
技巧27 创建匿名类型的对象,数组
使用new关键字和匿名对象初始化器能够创建一个匿名类型的对象。即使我们没有预定义好新类型,也可以将数据与对象组合起来根据需要即时创建。
 //
创建匿名类型的对象
 var UserInfo = new {ID=1,UserName="xiao",Password="111"};
 Response.Write(UserInfo .UserName );
//
匿名数组
var ints = new[] { 1,2,3,45,6};
匿名方法具有如下限制:
1.
在使用匿名类型时,若离开了定义该类型的方法将无法再以强类型的方式使用此匿名类型的实例。
2.
匿名方法的实例是不可变的,一旦创建了一个匿名类型的实例,那么该实例的各个属性值被永远确定下来了。我们无法修改匿名类型实例的属性值。
技巧28 善于使用代码重构
代码重构功能主要包括重命名。提取方法,封装字段等。
技巧29 善于使用条件编译
#define DeBug //
最前面定义
//
其他代码
#if DeBug
            Response.Write ("
这是调试版本");
#else
             Response.Write ("
这是发布版本");
#endif
技巧30 标准化事件驱动的设计
   public delegate void EventNumberHandler(objectsender,EventArgs e);//
定义委托
    public class Counter
    {
        public event EventNumberHandleronEventNumber;//
定义事件
        public  Counter()
        { onEventNumber = null; }
        public void CountTo10()//
包含激发事件的方法
        {
            int a;
            for (a= 0; a < 10; a++)
            {
                if(a % 3 == 0)
                {
                    NumberEventArgse = new NumberEventArgs(a);
                    onEventNumber(this,e);//
激发事件
                }
            }
        }
     

    }
    public class NumberEventArgs : EventArgs
    {
        private int _number;
           publicNumberEventArgs (int num)
           {
               this._number=num;
           }
        public int Number
        {
            get{return_number ;}
        }
    }
protected void Page_Load(object sender, EventArgs e)
        {
            Countercnt = new Counter();
            cnt.onEventNumber+= new EventNumberHandler(Test );//
Test方法安装到事件中

        }

        public void Test(objectsender, EventArgs e)//被安装的方法
        {
            Response.Write((eas NumberEventArgs ).Number );
            Response.Write(".");
        }

 

第八篇 必知必会的15ADO.NETXML方面的经验技巧

技巧01 在数据库连接中使用连接池
数据库连接池:一个存储数据库连接的缓存池,由于连接和断开一个数据库开销很大,反复的连接和断开数据库将对系统的性能产生严重的影响。所以数据库连接都放在连接池中。连接池有选择性保留程序释放的数据库连接,以便以后使用。
用户调用连接对象的Open()方法时池进程会检查池中是否有可用的连接,如果有,那么直接将该连接返回给调用者,如果没有,创建一个新的连接。当应用程序调用连接的Close()方法时,池进程会将此连接返回到活动连接池中而不是真正的关闭。
判断连接池内的连接是否符合用户请求数据库连接需求就看连接字符串。
 using (SqlConnection conn = new SqlConnection(
                "Server=.Database=ExpatiiateAspNet;uid=sa;pwd="))
            {
                //
假设这是系统启动后的第一个数据库连接请求
                //
一个新的连接将建立
                conn.Open();
            }
            using(SqlConnection conn = new SqlConnection(
                 "Server=.Database=ExpatiiateAspNet;uid=sa;pwd="+ "  "))
            {
                //
由于连接字符串和上一个连接不同
                //
所以保存在数据库和连接池中的连接不能被使用
                //
又新建了一个连接
                conn.Open();
            }
            using(SqlConnection conn = new SqlConnection(
               "Server=.Database=ExpatiiateAspNet;uid=sa;pwd="))
            {
                //
连接字符串和第一个相同
                //
保存在数据库连接池中的第一个连接被重复使用
                conn.Open();
            }
技巧02 如何更有效的管理连接字符串
ConnectionStringBuilder类型使开发人员以编程方式创建。修改连接字符串的强类型键/值对。同时也有检查功能,如果添加无效的键值来创建无效的连接字符串将引发异常。
 SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();//
创建连接字符串的构造器对象
            builder["DataSource"] = ".";//
设置数据库服务器为当前机器
            builder["Initial Catalog"]="ExpatiateAspNet";//
设置连接字符串的数据库名
            builder["integrated Security"]=true ;//
使用集成安全验证方式
技巧03 使用DataView操作数据集
DataTable
没有提供类似数据过滤。排序等操作,一般是将其转化为DataView后再进行过滤。排序等操作。DataView可以使用不同排序顺序显示表中的数据,也可以按行状态或筛选表达式来过滤数据。
DataTable dt=new DataTable ();
            //
基于DataTable创建DataView
            //
在构造函数中过滤productCode=001,saleDate进行升序排序
            //
行状态包括未更改行,新行,和已修改的当前行
            DataViewdv=new DataView (dt,"productCode='001'","saleDate",DataViewRowState.CurrentRows );
            GridView1.DataSource=dv;
            GridView1.DataBind ();
            DataViewdv2=new DataView ();
            dv2.RowFilter="productCode='001";
            dv2.Sort ="saleDate";
            GridView1.DataSource =dv2 ;
            GridView1.DataBind ();
          
技巧04 效率最高的数据读取方式
 SqlDataReader dr = cmd.ExecuteReader(CommandBehavior .CloseConnection );
技巧05 XML中加载数据集
//
将符合XML格式的字符串读取到DataSet中形成数据
            DataSetds = new DataSet();
            DataTabledt = new DataTable("table1");
            dt.Columns.Add("col1",typeof(string));
            dt.Columns.Add("col2",typeof(string ));
            ds.Tables.Add(dt);
            //
构造xml字符串
            stringxmldata = "<XmlDS><table1><col1>Value1</col1><col2>Value2</col2></table1><table1><col1>Value11</col1><col2>Value22</col2></table1></XmlDS>";
            StringReadersr = new StringReader(xmldata );
            ds.ReadXml(sr,XmlReadMode.IgnoreSchema);//
忽略任何内联架构读取数据到DataSet架构,如果XML数据与DataSet架构不匹配,就会将这些数据丢弃
            GridView1.DataSource =ds.Tables [0];
            GridView1.DataBind();
技巧06 XML中加载数据集架构信息
DataSet ds = new DataSet();
            stringpath1 = Server.MapPath(".") + @"\App_Data\temp.xsd";//
XML框架文件的路径
            ds.ReadXmlSchema(path1);
            DataSetds2 = new DataSet();
            stringpath2 = Server.MapPath(".") + @"\App_Data\temp.xml";
            ds2.InferXmlSchema(path2,new string[]{""});//
根据XML文件推断出XML框架加载到数据集中
技巧07 根据数据集生成XMLXML架构
 DataSet ds = new DataSet();
            DataTabledt = new DataTable();//CreateDataTable()
            ds.Tables.Add(dt);
            stringpath1 = Server.MapPath(".") + @"\App_Data\temp.xsd";//
XML框架文件的路径
            ds.WriteXmlSchema(path1);//
根据数据集生成XML框架文件
           
            stringpath2 = Server.MapPath(".") + @"\App_Data\temp.xml";
            ds.WriteXml(path2);//
根据数据集生成XML数据文件
技巧08 强类型的DataSet
新建一个数据集:
1.
添加新项,选择数据集
2.
服务器资源管理器选择一个表拖到数据集页面上。
3.
操作:

            dsUserds = new dsUser();//创建强类型数据集对象
            stringstr = "
连接字符串";
            using(SqlConnection con = new SqlConnection(str))
            {
                SqlDataAdaptersda = new SqlDataAdapter("select * form userInfo",con );
                sda.Fill(ds,"UserInfo");
            }
            //
在强类型数据表中添加一行
            dsUser.UserInfoRowrow = ds.UserInfo.NewUserInfoRow();
            row.UserID= -1;
            row.UserName= "xiao";
            row.UserCode= "-1";
            ds.UserInfo.AddUserInfoRow(row);
            stringuserName = ds.UserInfo.FindByUserID(-1).UserName;
            GridView1.DataSource= ds.UserInfo;
            GridView1.DataBind();

技巧09 数据集与XML建立同步关联
 DataSet ds = new DataSet();
            DataTabledt = new DataTable();//CreateDataTable()
            ds.Tables.Add(dt);
            //
创建 XmlDataDocument对象并以DataSet进行同步关联
            XmlDataDocumentxmldoc = new XmlDataDocument(ds);
            dt.Rows[0]["productCode"]= "00000";
            dt.Rows[2].Delete();
            stringpath2 = Server.MapPath(".") + @"\App_Data\temp.xml";
            xmldoc.Save(path2);
技巧10 数据关系导航DataRelation
DataRelation对象描述一个DataSetDataTable之间的关系。
DataSet ds = new DataSet();
            stringstr = "
连接字符串";
            using(SqlConnection con = new SqlConnection(str))
            {
                SqlDataAdaptersda = new SqlDataAdapter("select * from DictionaryType",con);
                sda.Fill(ds,"DictionaryType");
                sda= new SqlDataAdapter("select * from DictionaryItem",con);
                sda.Fill(ds,"DictionaryItem");
                DataRelationTypeItem = ds.Relations.Add("TypeItem",ds.Tables["DictionaryType"].Columns ["DictTypeID"],ds.Tables["DictionnaryItem"].Columns ["DictTypeID"]);
                foreach(DataRow typeRow in ds.Tables["DictionaryType"].Rows)
                {
                   
                    Response.Write(typeRow["DictTypeName"].ToString()+"</br>");
               
                //
通过建立的关系可以获得主表某一行对应子表的行集合
                    foreach(DataRow itemRow in typeRow.GetChildRows(TypeItem))
                    {
                        Response.Write(itemRow["DictItemName"].ToString ()+"</br>");
                    }
                }
            }
技巧11  合并两个数据集的数据内容
 ds.Merge(ds2);
技巧12 复制数据集
  DataSet ds = new DataSet();
            DataTabledt = new DataTable();
            ds.Tables.Add(dt);
            DataSetcopeset = ds.Copy();//
复制整个数据集
            DataSetchangeset = ds.GetChanges();//
仅复制源数据集中表数据被更改的部分
            DataSetchangeAddset = ds.GetChanges(DataRowState.Added);//
仅复制源数据集中表数据行状态为添加状态的部分
            DataSetsetSchema = ds.Clone();//
仅复制源数据集的架构
            DataRow[]copeRow = ds.Tables[0].Select("prodectCode='001'");
            DataTabledts = ds.Tables[0];
            foreach(DataRow copy in copeRow)
            {
                dts.ImportRow(copy);//
将行数组导入目标数据集
            }
技巧13 动态创建DataTable技术全析
技巧14 DataTable行状态与行版本
技巧15 实现数据表行列转换
实现行列转换的关键在构造的SQL语句上。
 string sql1 = "select department as
部门,product as 材料,amount as 金额 from DepartmentProduct";
            DataSetds1 = GetDataSet(sql1 );
            GridView1.DataSource= ds1;
            GridView1.DataBind();
            stringsql2 =
                "selectdepartment as
部门," +
                
"SUM(CASE product WHEN '材料1' THEN amount ELSE 0 END)材料1," +
                 "SUM(CASEproduct WHEN '
材料2' THEN amount ELSE 0 END)材料2," +
                 "fromDepartmentProduct" +
                 "groupby department";
            DataSetds2 = GetDataSet(sql2 );
            GridView1.DataSource= ds1;
            GridView1.DataBind();
          
        }
        private DataSetGetDataSet(string sql)
        {
            DataSetds = new DataSet();
            stringstr = "
连接字符串";
            using(SqlConnection con = new SqlConnection(str))
            {
                con.Open();
                SqlDataAdaptersda = new SqlDataAdapter(sql, con);
                sda.Fill(ds,"DepartmentProdut");
            }
            returnds;
               
        }

 

第九篇 必知必会的65Web方面的经验技巧

01 meta标签增强网页性能
1.
指定页面使用的字符
<head runat="server">
    <meta  http-equiv ="Content-Type"content="text/html; Charset=gb2312 "/>
</head>
2.Refresh
:页面每隔10S自动刷新一次
 <meta  http-equiv="Refresh "content="10Url=Default.aspx"/>
3.Expires
期限:必须使用GMT的时间格式
   <meta  http-equiv ="Expires" content="0"/>
    <meta  http-equiv ="Expires"content ="Web,1 Feb 1990 00:00:00 GMT"/>
4.Pragma
cath模式):
 <meta  http-equiv ="Pragma" content="No-cath"/>
5.Set-Cookie:
 <meta  http-equiv ="Set-Cookie" content="cookievalue=xxx;expires=Wednesday,21-Oct-98 16:12:12GMT;path=/"/>
 
技巧02 给服务器控件添加不存在的属性
如果在ASPNET服务器的HTML代码中包括的属性未映射到控件类的属性,ASPNET将在服务器处理期间忽略该属性,它会将该属性作为该控件所生成的标记的一部分按原样传递给浏览器。
<asp:Panel ID="Panel1" runat="server">
    </asp:Panel>  <asp:TextBoxID="TextBox1"runat="server"onkeyup="Panel1.innerText=this.value.lenght;"></asp:TextBox>
   
技巧03 如何动态使用表格
 Table table = new Table();
            TableRowtr = new TableRow();
            TableCelltd = new TableCell();
            td.Font.Size= FontUnit.XXSmall;//
设置单元格的字体大小
            td.Text= "wenben";
            td.Width= 80;
            tr.Cells.Add(td);
            TableCelltd2 = new TableCell();
            td2.Font.Size= FontUnit.XXSmall;//
设置单元格的字体大小
            td2.Text= "wenben";
            td2.Width= 80;
            tr.Cells.Add(td2);
            TableCelltd3 = new TableCell();
            td3.Font.Size= FontUnit.XXSmall;//
设置单元格的字体大小
            td3.Text= "wenben";
            td3.Width= 80;
            tr.Cells.Add(td3);
            table.Rows.Add(tr);
技巧04 PlaceHolder容器控件的使用技巧
PlaceHolder
可以看做是在网页中标记一个位置的容器控件。比便运行时动态的将子元素添加到该容器中。PlaceHolder控件在网页中只呈现添加其Controls集合属性的子元素,不呈现自身的任何元素。
 <asp:PlaceHolder ID="PlaceHolder1"runat="server"></asp:PlaceHolder>
     TextBox myText = new TextBox();
            myText.ID= "TextBox1";
            myText.Text= "
文本框1";
            PlaceHolder1.Controls.Add(myText);
技巧05 用框架定制页面布局的技巧
框架让你能够在同一浏览器窗口中显示多个HTML页面。在使用FrameSet框架布局页面时,首先在<frameset></frameset>中添加<frame></frame>元素,以链接框架页,然后在<frame>元素设置以下属性。
src:
要在框架中显示的页面的URL
name:
用来设置框架名,以标识该框架。
在一个页面中不能同时使用多个<frameset>节,但可以再<frameset>中嵌套<frameset>
<frameset rows ="80,*" cols ="*" style ="border:1px;" target="MainFrame">
<frame src ="Top.aspx " name="Topframe" scrolling="no" noresize="noresize"   />
<frameset  rows ="*" cols ="150,*"framespacing="1" style ="border :1" >
<frame  src="Left.aspx"/ name="LeftFrame" scrolling="no" noresize ="noresize" >
<frame src="Right.aspx" name="RightFrame" scrolling="no" noresize ="noresize"  />
</frameset>
</frameset>
技巧06 HTML中创建ArrayList对象
<head runat="server">
    <title></title>
    <object id ="colors" class="System.Collections.ArrayList" runat ="server"></object>
</head>
protected void Page_Load(object sender, EventArgs e)
        {
            colors.Add("Red");
            colors.Add("Green");
        }
技巧07 JavascriptC#之间的互相调用与访问
1.
HTML中使用<%=%>标记,访问格式是<%=C#变量名%>
2.
在控件模板中使用<%#%>标记,访问格式是<%#eval_r("表达式")%>
技巧08 自定义实现让TextBox控件只能输入数字
 <script language ="javascript"  type="text/javascript" >
        function IsNumber() {
            if(event.keyCode < 45 || event.keyCode > 57) {
                event.keyCode= 0;
            }
        }
    </script>
<div>
        <asp:TextBoxID="TextBox1" runat="server"onkeyPress="IsNumber()"></asp:TextBox>
        <asp:ButtonID="btnSave" runat="server" Text="
保存" onclick="btnSave_Click" />
    </div>
 protected void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                Convert.ToDouble(TextBox1.Text.Trim());
            }
            catch
            {
                Response.Write("<script>alter('
请输入正确的数字格式')</script>");
                TextBox1.Text= "";
                ScriptManager.RegisterStartupScript(Page  ,typeof(string),"focus","<script>document.forms[0]['TextBox1'].focus();</script>",false);
            }
技巧09 绝对路径表示方法
“~”始终表示网站的根目录。
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/catalog.bmp"/>
技巧10 在刷新或提交页面后保持页面滚动条的位置
PageMaintainScrollPositionOnPostBack属性值设置为true即可实现保持上次的滚动位置。
<%@ Page Language="C#" CodeBehind="WebForm1.aspx.cs"Inherits="Test3.WebForm1" MaintainScrollPositionOnPostback="true" %>
技巧11 设置Web窗体的默认按钮
 <form id="form1" runat="server" defaultbutton="btnSave">
    <div>
        <asp:TextBoxID="TextBox1" runat="server"onkeyPress="IsNumber()"></asp:TextBox>
        <asp:ButtonID="btnSave" runat="server" Text="
保存" onclick="btnSave_Click" />
    </div>
    </form>
技巧12 设置Web窗体的默认焦点控件
<form id="form1" runat="server" defaultbutton="btnSave" defaultfocus ="TextBoxe1">
    <div>
        <asp:TextBoxID="TextBox1" runat="server"onkeyPress="IsNumber()"></asp:TextBox>
        <asp:ButtonID="btnSave" runat="server" Text="
保存" onclick="btnSave_Click" />
    </div>
    </form>
技巧13 页面传值方式博览
1.
首先介绍使用查询字符串的传值方式
Response
Redirect"Target.aspx?str=querystring.value");
2.
使用session
技巧14 动态创建客户端脚本
1.
使用RegisterOnSubmitStatement()方法注册当页面提交到服务器时执行的脚步。
protected void Page_Load(object sender, EventArgs e)
        {
            stringscriptText = "return confirm('
是否确认提交?')";
            ClientScript.RegisterOnSubmitStatement(this.GetType(),"ConfirmSubmit",scriptText  );
        }
2.
使用RegisterClientScriptBlock方法注册按钮的客户端onclick事件脚本。
 protected void Page_Load(object sender, EventArgs e)
        {
           //
判断是否已经注册clientScript键的客户端脚本
            if(!ClientScript.IsClientScriptBlockRegistered("clientScript"))
            {
                stringscriptString = "<script language="javascript"type="text/javasript">" +
                    "functiondoClick()" +
                    "{"+
                         "alter('ButtonClick');" +
                         "}"+
                         "</script>";
                ClientScript.RegisterClientScriptBlock(this.GetType(),"clientScript",scriptString ,false );
            }
        }
技巧15 HyperLinkLinkButton按钮的区别
LinkButton
控件先将请求回传至服务器端,再由服务器端转到目标网页。HypeLink控件则不经过服务器端直接跳转到目标网页。
技巧16 用最简单的方法实现站点导航
使用TreeView控件和SiteMapDataSource控件可以实现站点导航功能
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="" title="
进销存管理中心"  description="进销存管理中心">
    <siteMapNode url="" title="
基本信息"  description="基本信息" />
       <siteMapNodeurl="~/BaseInfo/EmployeeInfoInput" title="
员工信息录入"  description="员工信息录入" />
       <siteMapNode  url="~/BaseInfo/WarehouseInput" title ="
建立仓库信息" description ="建立仓库"/>
    </siteMapNode>

</siteMap>
 <asp:TreeView ID="TreeView1" runat="server"DataSourceID="SiteMapDataSource1">
        </asp:TreeView>
        <asp:SiteMapDataSourceID="SiteMapDataSource1" runat="server" />
技巧17 以编程方式向TreeView控件中添加节点
TreeView tv=new TreeView ();
            TreeNodenod = new TreeNode();
            nod.Value= "1";
            nod.Text= "
质量管理";
            nod.NavigateUrl= "~/Left.aspx";
            nod.ToolTip=""//
描述信息
            nod.ImageUrl="~/BaseInfo/Image/a.jpg";
            tv.Nodes.Add(nod );
技巧18 Menu控件绑定站点地图实现导航
使用Menu控件和SiteMapDataSource控件可以实现站点导航功能
 <asp:Menu ID="Menu1" runat="server"DataSourceID="SiteMapDataSource1" Orientation ="Horizontal"StaticDisplayLevels ="2">
        </asp:Menu>
技巧19 网页代码文件中定义变量的技巧
使用ViewState对变量做持久化处理可以解决在回传过程中变量丢值的问题。
ViewStat[""]=value;
技巧20 实现GridView无刷新换页及排序
GridViewEnableSortingAndPagingCallbacks属性设为true
  <asp:GridView ID="GridView1" runat="server"EnableSortingAndPagingCallbacks ="true" >
    </asp:GridView>
技巧21 合理使用GridView
因为GridView产生的性能开销很大,所以在只需简单显示数据列表时,选择RepeaterDataList控件同样可以达到目的,而不必使用GridView,这样可以减少了性能的开销
技巧22 使用GridView实现简单排序功能
GridViewAllowSorting属性设为true即可实现简单排序功能。
  <asp:GridView ID="GridView1" runat="server"AllowSorting="true" >
    </asp:GridView>
 protected void Page_Load(object sender, EventArgs e)
        {

            if(!IsPostBack)
            {
                ViewState["SortOrder"]= "UserCode";//
设置排序字段
                ViewState["OderDire"]= "DESC";//
设置排序方式:降序
                BindGridView();
            }
          

          
        }
 protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
        {
            stringSortOder = e.SortExpression;//
排序表达式
            if(ViewState["SortOrder"].ToString() == SortOder)
            {
                if(ViewState["OrderDire"].ToString() == "DESC")
                {
                    ViewState["OrderDire"]= "ASC";
                }
                else
                {
                    ViewState["OrderDire"]= "DESC";
                }
            }
            else
            {
                ViewState["SortOrder"]= e.SortExpression;
            }
            BindGridView();
        }
        protected void BindGridView()
        {
            GridView1.AllowSorting= true;
            DataSetds=new DataSet ();
            DataViewdv = ds.Tables[0].DefaultView;
            
dv.Sort = (string)ViewState["SortOrder"] + "" +(string)ViewState["OrderDire"];
            GridView1.DataSource= dv;
            GridView1.DataBind();
        }
技巧23 GridView上加滚动条
GridView放在div之中,并且对div设置后能实现此功能。
  <div  style ="height :150px; width :450px;overflow :auto ;">
    <asp:GridView ID="GridView1"runat="server"  AllowSorting ="true"
        onsorting="GridView1_Sorting"  >
    </asp:GridView>
    </div>
   
技巧24 删除行时弹出确认对话框
 protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {
                GridViewgrid = sender as GridView;
                ((LinkButton)(e.Row.Cells[grid.Columns .Count  -1].Controls[0])).Attributes.Add("onclick","return confirm('
确认删除?');");
            }
        }
      
技巧25 改变GridView当前行的颜色
 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgse)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
                //
为当前行添加鼠标移入事件
               e.Row.Attributes.Add("onmouseover","c=this.style.backgroundColor;this.style.backgroundColor='#6699ff'");
                //
为当前行添加鼠标移出事件
                e.Row.Attributes.Add("onmouseout","this.style.backgroundColor=c");
           
            }
技巧26 单击GridView中的按钮执行客户端脚本
实现思路是在RowDataBound事件中为Gridview数据行按钮添加onclick事件
  protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {
                 GridViewgrid = sender as GridView;
                 stringid = grid.DataKeys[e.Row.RowIndex].Value.ToString();
                 stringname = e.Row.Cells[2].Text;
                ((LinkButton)(e.Row.Cells[grid.Columns .Count  -1].Controls[0])).Attributes.Add("onclick","returnbtnSelect_onclick('"+id+"','"+name+"')");
           
            }
           
        }
<script language ="javascript" type ="text/javascript">
        function btnSelect_onclick(id,name) {
            alert("
用户Id"+id+"用户名:"+name );
            return  false;
         }
    </script>
技巧27 设置GridView列的显示格式
<asp:GridView ID="GridView1"runat="server"  AllowSorting ="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"  >
        <Columns>
            <asp:BoundFieldDataFormatString="{0:yyyy-MM-dd}" SortExpression="saleDate"/>
        </Columns>
    </asp:GridView>
技巧28 DropDownList控件嵌入GridView
  <asp:GridView ID="GridView1"runat="server"  AllowSorting ="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"  >
        <Columns>
            <asp:TemplateField  HeaderText="
菜单级别" SortExpression="MenuLeval">
            <ItemTemplate>
              <asp:DropDownList  ID="DropDownList1" runat ="server" Enabled="false" selectedVlue='<% Bind("MenuLevel")%>'>
                 <asp:ListItemValue ="1">
一级菜单</asp:ListItem>
                 <asp:ListItemValue ="2">
二级菜单</asp:ListItem>
                 <asp:ListItemValue ="3">
三级菜单</asp:ListItem>
              </asp:DropDownList>
            </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
技巧29 CheckBox控件嵌入GridView
 <asp:GridView ID="GridView1"runat="server"  AllowSorting ="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"  >
        <Columns>
          
            <asp:CheckBoxFieldDataField="IsLeaf" HeaderText="
是否末级菜单"
                SortExpression="IsLeaf"/>
        </Columns>
    </asp:GridView>
技巧30 实现自动编号功能
  protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {
                 GridViewgrid = sender as GridView;
                 introwNo = e.Row.RowIndex + 1;
                 e.Row.Cells[0].Text= rowNo.ToString();
           
            }
           
        }
技巧31 实现用。。。代替超长字符串
 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgse)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {
                 stringcontent=e.Row .Cells [2].Text .ToString ();
                 e.Row.Cells[2].Text= SubStr(content ,10);
           
            }
           
        }

        public stringSubStr(string str, int len)
        {
            if(str.Length <= len)
            {
                returnstr;
            }
            stringnewStr = str.Substring(0,len );
            newStr+= "....";
            returnnewStr;
        }
技巧32 GridView一般换行与强制换行
Gridview
本身具有自动换行的功能,但是它不能对英文进行正确的换行。对英文单词换行方法是为单元格添加word-break样式属性。
1.
先设置ItemStyle-BorderWidth
<asp:GridView ID="GridView1"runat="server"  AllowSorting ="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"  >
        <Columns>
            <asp:BoundFieldDataFormatString="{0:yyyy-MM-dd}"SortExpression="saleDate" ItemStyle-BorderWidth="200"/>
          
        </Columns>
    </asp:GridView>
2.
 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgse)
        {
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {
                e.Row.Cells[2].Style.Add("word-break","break-all");
           
            }
           
        }
技巧33 创建表头固定表体可滚动的GridView
思路:首先实现Gridview数据的滚动效果其次创建实现锁定表头功能的客户端自定义函数fixHead(),最后在客户端页面加载事件中应用该函数。
  <script language ="javascript" type="text/javascript" >
   
         function fixHead()
         {
           var grid  =document.getElementByIdx_x("<%=GridView1.ClientID%>>");
           var grid2=grid.cloneNode(true);
           for(i=grid2.rows.length-1;i>0;i--){
               grid2.deleteRow(i);
               grid.deleteRow(0);
               divHead.appendChild(grid2);
           }
       }
       window.onload=fixHead
    </script>
技巧34 GridView加入小计
Gridview
具有数据合计功能,本实例将Gridview的显示脚本属性ShowFooter设为true
    <asp:GridView ID="GridView1"runat="server"  AllowSorting ="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"   ShowFooter="true" >
    </asp:GridView>
 double sum;
            if(e.Row.RowType == DataControlRowType.DataRow)//
如果是数据行
            {

                if(!string.IsNullOrEmpty(e.Row.Cells[2].Text))
                {

                    sum+= Convert.ToDouble(e.Row.Cells[2].Text);
                }
                elseif (e.Row.RowType ==DataControlRowType.DataRow )
                {
                    e.Row.Cells[0].Text= "
总销售额";
                    e.Row.Cells[2].Text= sum.ToString();
                }

技巧35 页面跳转方法对比分析
1.<a href="Target.aspx">Target.aspx</a>
2.
使用javascript设置windowslocation实现页面跳转
<input id="Button1" type="button"value=""onclick="windows.location='Target.aspx'"/>
3.<asp:HyperLink="HyperLink1" runat="server"NavigateUrl="~/Target.aspx">afdas</asp:HyperLink>
4.<asp:LinkButton id="" runat="server"PostBackUrl="~/Taget.aspx">dafewa</asp:LinkButton>
5.Response.Redirect("~/Target.aspx");
6.Server.Transfer("~/Target.aspx");
7.Server.Execute("~/Target.aspx");
注意:ServerTransferServerExecute方法进行页面跳转后,浏览器的地址栏仍然显示原来网页的地址。
技巧36 关闭子窗口时刷新父窗口
实现思路:使用子窗口的opener属性获得打开当前窗口的父窗口,调用openerlocationreload()方法刷新父窗口。
  <input id="btnOpenWin" type="button"value="
打开子窗口" onclick="windows.open('ChildWin.aspx','','width=300,height=250');" />
    <input id="btnSave" type="button" value="
保存" onclick ="aler('保存成功');opener.location.reload();window.close();"/>
  
技巧37 使用主题实现网页皮肤动态切换
XML
文件:
 <Config>
      <Theme>
        <ThemeName>
          Green
        </ThemeName>
      </Theme>
    </Config>
 protected void Page_PreInit(object sender, EventArgs e)
        {
            stringstyleSheetTheme = "Blue";
            try
            {
                //
根据Web服务器上虚拟路径取XML文件的物理路径
                stringxmlFilePath = Server.MapPath("~/CustomConfig");
                XElementxe = XElement.Load(xmlFilePath );
                IEnumerable<XElement>elements = from ee in xe.Descendants("ThemeName")
                                                 selectee;
                if(elements.Count() > 0)
                {
                    XElementfirst = elements.First();
                    styleSheetTheme= first.Value();
                }
            }
            catch
            { }
            Page.Theme= styleSheetTheme;
        }
  protected void menuTemplate_MenuItemClick(object sender, EventArgse)
        {
            stringxmlFilePath = Server.MapPath("~/CustomConfig");
            XElementxe = XElement.Load(xmlFilePath);
            IEnumerable<XElement>elements = from ee in xe.Descendants("ThemeName")
                                             selectee;
            if(elements.Count() > 0)
            {
                XElementfirst = elements.First();
                first.SelectValue(memuTemplate.SelectedValue);
            }
            xe.Save(xmlFilePath);
            Response.Redirect(Request.Path );
        }
技巧38 访问母版页中的成员
实现思路:首先在内容页的HTML头部添加@MasterType指令以创建内容页对母版页的强类型引用,其次在内容页的代码文件中调用Page类的Master属性即可访问母版页中的成员变量。
<%@ MasterType VirtualPath ="~/Site1.Master" %>
public string ErrorMsg = "
这是母版页的全局变量";
public string ErrorMsg = "
这是母版页的全局变量";
技巧39 访问母版页中控件的值
 protected void Page_Load(object sender, EventArgs e)
        {
            LabelmyLabel =(Label ) Master.FindControl("Label1");
            if(myLabel != null)
            {
                Response.Write("<script>aler('"+myLabel.Text +"')</script>");
            }
        }
技巧40 自定义HTTP处理程序
1
,创建自定义HTTP处理程序类,必须实现IHttpHandler接口。
 public class HelloWorldHandler:IHttpHandler
    {
        public HelloWorldHandler()
        { }
        bool IHttpHandler.IsReusable//
成员
        {
            get {return false; }
        }

        voidIHttpHandler.ProcessRequest(HttpContext context)//成员
        {
            HttpRequestRequest = context.Request;
            HttpResponseResponse = context.Response;
            Response.Write("<html>");
            Response.Write("<body>");
            Response.Write("<h1>
这是一个自定义的HTTP处理程序</h1>");
            Response.Write("</body>");
            Response.Write("</html>");
        }
    }
2.
webconfig文件中注册自定义的Http处理程序,也就是将指定的扩展名(。sample)与自定义HTTP处理程序类关联起来。
 <httpHandlers >
      <add verb ="*" path="*.sample" type ="HelloWorldHandler"/>
    </httpHandlers>
3.
在网页地址输入包含指定扩展名的URL,调用自定义的HTTP处理程序。
技巧41 HTTP模块
HTTP
模块式每次针对应用程序发出请求时都需要调用的一个功能集合。是HTTP必经之路。在一个Web应用程序中定制的HTTP模块,可以在其他Web应用程序中重复使用。
步骤:
1.
创建一个实现IHttpModule接口的类
2.
Init()方法中订阅HTTP模块所需要的事件。
3.
为已经订阅的事件编写代码。
4.
web.config文件注册HTTP模块
public class HelloWorldModule:IHttpModule
    {
        public HelloWorldModule()
        { }
        public string ModuleName
        {
            get
            {
                return"HelloWorldModule";
            }
        }
        //
开始请求事件
        private voidApplication_BeginRequest(object source, EventArgs e)
        {
            HttpApplicationapplication = (HttpApplication )source;
            HttpContextcontext = application.Context;
            stringfilePath = context.Request.FilePath;
            stringfileExtension = VirtualPathUtility.GetExtension(filePath );
            if(fileExtension.Equals(".aspx"))
            {
                context.Response.Write("<h2><fontcolor=red>"+
                    "HelloWorldModule:
开始请求"+
                    "</font></h2><br>");
            }
          
        }
        //
接受请求事件
        private voidApplication_EndRequest(object source, EventArgs e)
        {
            HttpApplicationapplication = (HttpApplication)source;
            HttpContextcontext = application.Context;
            stringfilePath = context.Request.FilePath;
            stringfileExtension = VirtualPathUtility.GetExtension(filePath);
            if(fileExtension.Equals(".aspx"))
            {
                context.Response.Write("<h2><fontcolor=red>" +
                    "HelloWorldModule:
结束请求" +
                    "</font></h2><br>");
            }
        }
        public void Dispose()
        {
            thrownew NotImplementedException();//
成员
        }

        public voidInit(HttpApplication context)//成员
        {
            context.BeginRequest +=(new EventHandler (this.Application_BeginRequest ));
            context.EndRequest +=(new EventHandler (this.Application_EndRequest ));
        }
    }
  <httpModules>
      <add name="HelloWorldModule"type ="HelloWorldModule"/>
    </httpModules>
技巧42 缓存页面的技巧
1.
使用OutputCache指令静态设置页面缓存
<%@ OutputCache Duration ="10" VaryByParam ="none"Location ="Server" %>
2.
以编程的方式动态设置页面缓存
 Response.Cache.SetExpires(DateTime .Now .AddSeconds (10));
Response.Cache.SetCacheability(HttpCacheability .Public );
3.
web.config中配置整个网站都进行页面缓存
<%@OutputCahe CacheProfile="Cache10Seconds"%>
技巧43 尽量使用数据缓存
 protected void Page_Load(object sender, EventArgs e)
        {
            DataSetds = new DataSet();
            if(Cache["key"] == null)
            {
                ds.ReadXml(Server.MapPath("~/XMLFile.xml"));
                this.GridView1.DataSource= ds;
                this.GridView1.DataBind();
            }
            else
            {
                ds=(DataSet)Cache ["key"];
                this.GridView1.DataSource= ds;
                this.GridView1.DataBind();
            }
        }

        protected voidbtnSave_Click(object sender, EventArgs e)
        {
            if(Cache["key"] == null)
            {
                DataSetds = new DataSet();
                ds.ReadXml(Server.MapPath ("~/XMLFile.xml"));
                //
将数据集放入数据缓存
                Cache.Insert("key",newSystem .Web.Caching .CacheDependency (Server.MapPath("~/XMLFile.xml")));
            }
        }
 
注意:System .Web.Caching .CacheDependency对象表示该缓存项与XMLFilexml文件建立依附性关系,当XMLFilexml文件内容改变时自动从数据缓存中移除该缓存项
技巧44 使用脚本管理控件引入脚本资源
ScriptManager控件负责管理Page页面中所有的AJAX服务器控件,是AJAX的核心。有了ScriptManager控件才能够让Page局部更新起作用,所需要的Javascript才会自动管理。
使用<Script>标记引用Javascript脚本。
<asp:ScriptManager ID="ScriptManager1"runat="server">
        <Scripts >
        <asp:ScriptReference  Path="~/Scripts/jquery-1.4.1.js"/>
        </Scripts>
        </asp:ScriptManager>
技巧45 使用Timer控件实现计时器功能
1.Interval
属性:用于设置Timer控件的Tick事件间隔时间。单位为ms
2.Tick
事件:用于在指定时间间隔进行触发事件。
使用Timer控件实现定时器功能不但用户体验差,每次触发事件都要产生一个回传。解决的方法是,使用AJAX Frame work 构建一个AJAX Timer服务器控件,设置AJAX Timer服务器控件的时间间隔,定时触发异步事件。(把它放在UpdatePanel控件里)
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <Triggers >
        <asp:AsyncPostBackTriggerControlID ="Timer1" EventName ="Tick" />
        </Triggers>
        </asp:UpdatePanel>
技巧46 使用UpdatePanel控件实现局部更新
UpdatePanel
控件具有局部更新功能。基本思想是把Web页面分解为一到多个独立的区域,其中每个区域都包含在一个不可见的UpdatePanel中,当UpdatePanel中要引发Post back时,UpdatePanel截获该事件,执行一次异步回调以取代该事件。
1.
同步方式
 <asp:UpdatePanel ID="UpdatePanel1"runat="server">
        <ContentTemplate >
        <div>
            <asp:ButtonID="Button1" runat="server" Text="Button" />
        </div>
        </ContentTemplate>
        <Triggers >
       <asp:PostBackTrigger ControlID="Button1" />
        </Triggers>
        </asp:UpdatePanel>
2.
静态设置的异步方式
 <ContentTemplate >
        <div>
           <!--
其他代码-->
        </div>
        </ContentTemplate>
        <Triggers >
       <asp:AsyncPostBackTrigger ControlID="Button1" EventName ="Click" />
        </Triggers>
        </asp:UpdatePanel>
         <asp:ButtonID="Button1" runat="server" Text="Button" />
3.
动态设置的异步方式
protected void Page_Load(object sender, EventArgs e)
        {
            this.ScriptManager1.RegisterAsyncPostBackControl(this.Button1);
        }
技巧47 多个UpdatePanel控件之间的关系
UpdatePanel控件的UpdateMode属性设置为Always模式时,当页面上其他UpdatePanel控件执行异步更新时,它的异步更新操作也会被触发。如果将UpdateMode属性设置为Conditional,就可以避免连带受到其他UpdatePanel的影响。
技巧48 为控件添加水印提示
TextBoxWatermark
扩展控件可以为TextBox服务器控件添加水印效果。添加水印效果的文本框内将显示水印提示内容,当文本框获得焦点或在文本框内单击鼠标时水印文字会立即消失,变成空白的,可输入内容的文本框。
TextBoxWatermark
扩展控件常用的属性:
TargetControlID
:目标TextBox控件ID
WatermarkText
:设定显示的水印文字
WatermarkCssClass
:水印文字应用的Css
技巧49 智能提示输入密码的强度
使用ASP.NET AJAX Control Tookit中的PasswordStrength扩展控件可以为设置密码的TextBox添加即时的密码强度检测功能,将检测的密码强度以及安全提醒返回给客户端。
常用属性
TargetControlID
:要检测密码的TextBox控件ID
DisplayPosition
:提示的信息的位置,如:DisplayPosition="RightSide|LeftSide|BelowLeft"
StrengthIndicatorType
:强度信息提示方式,有文本和进度条StrengthIndicatorType="Text| BarIndicator"
PreferredPasswordLength
密码的长度
PrefixText
用文本方式时开头的文字PrefixText="强度:"
TextCssClass
用文本方时文字的CSS样式
MinimumNumericCharacters
密码中最少要包含的数字数量
MinimumSymbolCharacters
密码中最好要包含的符号数量(*#
RequiresUpperAndLowerCaseCharacters
是否需要区分大小写
TextStrengthDescriptions
文本方式时的文字提示信息TextStrengthDescriptions="极弱;;中等;;超强"
BarIndicatorCssClass
进度条的CSS样式
BarBorderCssClass
进度条边框的CSS样式
HelpStatusLabelID
帮助提示信息的Lable控件ID
 <atlasToolkit:PasswordStrength ID="PS"runat="server">
    <atlasToolkit:PasswordStrengthExtenderProperties

        TargetControlID="TextBox1"

        DisplayPosition="RightSide"

        StrengthIndicatorType="Text"

        PreferredPasswordLength="10"

        PrefixText="Strength:"

        TextCssClass="TextIndicator_TextBox1"

        MinimumNumericCharacters="0"

        MinimumSymbolCharacters="0"

        RequiresUpperAndLowerCaseCharacters="false"

        TextStrengthDescriptions="VeryPoor;Weak;Average;Strong;Excellent" />

</atlasToolkit:PasswordStrength>

技巧50 无刷新播放照片
使用ASP.NET AJAX Control Tookit中的SlideShow扩展控件可以实现自动播放照片的功能
常用属性:
a.       TargetControlID:SlideShow
控件所控制的现实图片的那个image控件ID.
 
b.       SlideShowServicePath:
控件使用到的webservice所在的路径.
 
c.       SlideShowServiceMethod:
调用webservice提供图片所用到的方法。方法必须满足如下特性:
 
d.       ContextKey:
作为WebService的参数
 
e.       UseContextKey:
设置为truefalse,webservice是否使用参数
 
f.        NextButtonID:
点击这个按钮时会显示下一张图片。
 
g.       PlayButtonID:
用来停止或播放图片的按钮。
 
h.       PreviousButton:
用来显示前一张图片的按钮。
 
i.         PlayButtonText:
当状态为播放时显示的文字
 
j.         StopButtonText:
当状态为停止时显示的文字。
 
k.       PlayInterval:
两张图片切换的周期设置。
 
l.         ImageDescriptionLabelID:
用来用文字描述当前图片的LabelID
 
m.     Loop:
设置是否循环播放
 
n.       AutoPlay:
是否自动播放。
<ajaxToolkit:SlideShowExtender ID="SlideShowExtender1"runat="server"     TargetControlID="Image1"      SlideShowServiceMethod="GetSlides"           ImageTitleLabelID="imageTitle"     ImageDescriptionLabelID="imageDescription"    NextButtonID="nextButton"      PlayButtonText="Play"      StopButtonText="Stop"     PreviousButtonID="prevButton"      PlayButtonID="playButton"      Loop="true"/>
WebService
代码:


技巧51 实现弹出模态窗体
使用ASP.NET AJAX Control Tookit中的ModalPopupExtender扩展控件可以实现弹出模态对话框。
常用属性:
TargetControlID
:用于触发弹出面板的控件。
       OkControlID
:弹出面板中的确认按钮,用于确认新的样式。
        OnOkScript
:当单击确认按钮后,关闭样式面板后,执行脚本。
       CancelControlID
:样式面板中的取消按钮,用于取消应用样式。
       PopupDragHandleControlID
:样式面板中用于触发面板的控件。
       DropShadow
:样式面板是否有阴影。值为True,则有阴影;值为False,则没有阴影。
       BackgroundCssClass
:样式面板中应用的css样式。
 <asp:ScriptManager ID="ScriptManager1"runat="server">
     </asp:ScriptManager>
     <div>
    
         <asp:ButtonID="Button1" runat="server" Text="Button" />
         <cc1:ModalPopupExtenderID="Button1_ModalPopupExtender" runat="server"
             DynamicServicePath=""Enabled="True" TargetControlID="Button1"PopupControlID="Panel1">
         </cc1:ModalPopupExtender>
    
     </div>
  <asp:Panel ID="Panel1" runat="server"Height="176px" Width="141px">
     </asp:Panel>
技巧52 实现日期选择下拉框
使用ASP.NET AJAX Control Tookit中的CalendarExtender扩展控件实现日期选择下拉框效果
常用属性:
TargetControlID
:通过该属性设置当哪个控件获取焦点时,弹出日期面板并将日期值返回到这个控件中,通常设置为文本框。
Format
:通过该属性,设置返回日期的格式。
PopupButtonID
:通过该属性,设置当哪个控件点击时,弹出日期面板,此控件不授受返回值
<asp:ScriptManager ID="ScriptManager1"runat="server">
        </asp:ScriptManager>
    <div>
        <br /><br />
        <b>DefaultCalendar:</b>
        <asp:TextBoxID="Data1" runat="server"></asp:TextBox>
           <cc1:CalendarExtenderID="CalendarExtender1" runat="server"TargetControlID="Data1">
    </cc1:CalendarExtender>
</div>
技巧53 为异步操作提供进度提示
使用UpdateProgress控件为异步操作提供进度提示功能。
    <div>
        <asp:ScriptManagerID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanelID="UpdatePanel1" runat="server">
        <ContentTemplate >
            <asp:TextBoxID="TextBox1" runat="server"></asp:TextBox>
            <asp:ButtonID="Button2"runat="server" Text="
带进度条的异步操作" OnClick="Button1_Click" />
        </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdateProgressID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
        <ProgressTemplate >
        
正在运行。。。。。
        <input  type="button" value ="
终止" onclick =
        "if(System.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
        {System.WebForms.PageRequestManager.getInstance().abortPostBack();}"/>
        </ProgressTemplate>
        </asp:UpdateProgress>
    </div>
System.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()
:判断当前正在执行的操作是否是异步操作
System.WebForms.PageRequestManager.getInstance().abortPostBack()
:立即终止异步操作。
技巧54 使用缓存区输出图像
缓存处理的关键技术:
启用缓存处理,必须在asp.net网页的前面加上:Response.BufferOutput=true
取消缓存处理:必须在asp.net网页的前面加上:Response.BufferOutput=false
Response
对象提供三个方法来处理缓冲区里的数据。Response.ClearContent()用于清除存放在缓冲区尚未发送到客户端的输出。
Response.Flush()
方法用于把存放在缓冲区的输出发送到客户端,同时清除缓冲区。
Response.ClearHeaders()
用于清除所有存放在缓冲区的HTTP报头。
技巧55 使用jQuery实现带进度的上传文件功能
使用JQueryuploadify插件实现带进度提示的上传文件功能。
<script src="Scripts/jquery-1.4.1-vsdoc.js"type="text/javascript"></script>
    <script src="Scripts/jquery-1.4.1.js"type="text/javascript"></script>
    <script src="Scripts/jquery-1.4.1.min.js"type="text/javascript"></script>
 <script  type="text/javascript" >
$(document).ready(function()
{
    $("#uploadify").uploadify({
        'uploader':'JS/jquery.uploadify-v2.1.0/uploadify.swf',
        'script': 'UploadHandler.ashx',
        'cancelImg':'JS/jquery.uploadify-v2.1.0/cancel.png',
        'folder': 'UploadFile',
        'queueID': 'fileQueue',
        'auto': false,
        'multi': true,
        'onInit':function(){alert("1");},
        'onSelect': function(e,queueId, fileObj)
        {
            alert("
唯一标识:" + queueId + "\r\n" +
                  "
文件名:" + fileObj.name + "\r\n" +
                  "
文件大小:" + fileObj.size + "\r\n" +
                  "
创建时间:" + fileObj.creationDate + "\r\n" +
                  "
最后修改时间:" + fileObj.modificationDate +"\r\n" +
                  "
文件类型:" + fileObj.type
            );

        }
    });
}); 
 </script>
参数介绍:
uploader
uploadify.swf 文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf
script
   后台处理程序的相对路径。默认值:uploadify.php
checkScript
:用来判断上传选择的文件在服务器是否存在的后台处理程序的相对路径
fileDataName
:设置一个名字,在服务器处理程序中根据该名字来取上传文件的数据。默认为Filedata
method
提交方式Post Get 默认为Post
scriptAccess
flash脚本文件的访问模式,如果在本地测试设置为always,默认值:sameDomain 
folder
  上传文件存放的目录
queueID
文件队列的ID,该ID与存放文件队列的divID一致。
queueSizeLimit
当允许多文件生成时,设置选择文件的个数,默认值:999
multi
设置为true时可以上传多个文件。
auto
设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传
fileDesc
这个属性值必须设置fileExt属性后才有效,用来设置选择文件对话框中的提示文本,如设置fileDesc请选择rar doc pdf文件,打开文件选择框效果如下图:
fileExt
设置可以选择的文件的类型,格式如:'*.doc;*.pdf;*.rar'
sizeLimit
上传文件的大小限制
simUploadLimit
允许同时上传的个数默认值:1
buttonText
浏览按钮的文本,默认值:BROWSE
buttonImg
浏览按钮的图片的路径
hideButton
设置为true则隐藏浏览按钮的图片
rollover
值为truefalse,设置为true时当鼠标移到浏览按钮上时有反转效果。
width
设置浏览按钮的宽度,默认值:110
height
设置浏览按钮的高度,默认值:30
wmode
设置该项为transparent 可以使浏览按钮的flash背景文件透明,并且flash文件会被置为页面的最高层。默认值:opaque
cancelImg
:选择文件到文件队列中后的每一个文件上的关闭按钮图标,如下图:

上面介绍的key值的value都为字符串或是布尔类型,比较简单,接下来要介绍的key值的value为一个函数,可以在选择文件、出错或其他一些操作的时候返回一些信息给用户。

onInit : 做一些初始化的工作。

onSelect :选择文件时触发,该函数有三个参数
?event:
事件对象。
?queueID
:文件的唯一标识,由6为随机字符组成。
?fileObj
:选择的文件对象,有namesizecreationDatemodificationDatetype 5个属性。
?
 

onSelectOnce :在单文件或多文件上传时,选择文件时触发。该函数有两个参数eventdatadata对象有以下几个属性:
?fileCount
:选择文件的总数。
?filesSelected
:同时选择文件的个数,如果一次选择了3个文件该属性值为3
?filesReplaced
:如果文件队列中已经存在AB两个文件,再次选择文件时又选择了AB,该属性值为2
?allBytesTotal
:所有选择的文件的总大小。

onCancel : 当点击文件队列中文件的关闭按钮或点击取消上传时触发。该函数有eventqueueIdfileObjdata四个参数,前三个参数同onSelect 中的三个参数,data对象有两个属性fileCountallBytesTotal
?fileCount
:取消一个文件后,文件队列中剩余文件的个数。
?allBytesTotal
:取消一个文件后,文件队列中剩余文件的大小。

onClearQueue :当调用函数fileUploadClearQueue时触发。有eventdata两个参数,同onCancel 中的两个对应参数。

onQueueFull :当设置了queueSizeLimit并且选择的文件个数超出了queueSizeLimit的值时触发。该函数有两个参数eventqueueSizeLimit

onError :当上传过程中发生错误时触发。该函数有eventqueueIdfileObjerrorObj四个参数,其中前三个参数同上,errorObj对象有typeinfo两个属性。
?type
:错误的类型,有三种‘HTTP’, ‘IO’, or ‘Security’
?info
:错误的描述

onOpen :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列。该函数有eventqueueIdfileObj三个参数,参数的解释同上。

onProgress :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列,在onOpen之后触发。该函数有eventqueueIdfileObjdata四个参数,前三个参数的解释同上。data对象有四个属性percentagebytesLoadedallBytesLoadedspeed
?percentage
:当前完成的百分比
?bytesLoaded
:当前上传的大小
?allBytesLoaded
:文件队列中已经上传完的大小
?speed
:上传速率 kb/s

onComplete:文件上传完成后触发。该函数有四个参数eventqueueIdfileObjresponsedata五个参数,前三个参数同上。response为后台处理程序返回的值,在上面的例子中为10data有两个属性fileCountspeed
?fileCount
:剩余没有上传完成的文件的个数。
?speed
:文件上传的平均速率 kb/s

注:fileObj对象和上面讲到的有些不太一样,onComplete fileObj对象有个filePath属性可以取出上传文件的路径。

onAllComplete:文件队列中所有的文件上传完成后触发。该函数有eventdata两个参数,data有四个属性,分别为:
?filesUploaded :
上传的所有文件个数。
?errors
:出现错误的个数。
?allBytesLoaded
:所有上传文件的总大小。
?speed
:平均上传速率 kb/s

技巧56 如何下载大文件
实现思路:使用文件流每次读取指定字节的文件内容,然后将读取的字节以二进制流的形式输出到客户端(每次都调用ResponseFlush()将缓冲区的内容强制输出到客户端),直到读取全部的内容。
//
分步下载大文件
        private voidDownloadFile(string fileName)
        {
            System.IO.StreamiStream = null;
            byte[]buffer=newbyte [10000];
            intlength;
            longdataToRead;
            stringfilepath = fileName;
            stringfilename = System.IO.Path.GetFileName(filepath );//
取下载文件名
            try
            {
                //
使用文件流读取要下载的文件
                iStream= new System.IO.FileStream(filepath, System.IO.FileMode.Open,System.IO.FileAccess.Read, System.IO.FileShare.Read);
                dataToRead= iStream.Length;//
取文件的大小
                Response.ContentType= "application/octet-stream";//
设置输出流的HTTP MIME 类型
                //
HTTP表头添加到输出流
                Response.AddHeader("Content-Disposition","attachment;filename=" + filename);
                while(dataToRead > 0)
                {
                    if(Response.IsClientConnected)//
客户端是否连接在服务器上
                    {
                        length= iStream.Read(buffer, 0, 10000);//
从文件流中读取指定的字节数
                        Response.OutputStream.Write(buffer,0, length);//
将读取的字节数输出
                        Response.Flush();//
将缓冲区的内容强制向客户端输出
                        buffer= new byte[10000];
                        dataToRead= dataToRead - length;
                    }
                    else
                    {
                        dataToRead= -1;
                    }
                }
            }
            catch(Exception ex)
            {
                Response.Write("Error:"+ ex.Message);
            }
            finally
            {
                if(iStream != null)
                {
                    iStream.Close();
                }
            }
        }
技巧57 GridView中跨页面实现多行选择
实现思路:使用隐藏字段记录选中行。
<asp:GridView ID="GridView1" runat="server"  AllowSorting="True"
        onsorting="GridView1_Sorting"onrowdatabound="GridView1_RowDataBound"   ShowFooter="true" EmptyDataText ="
没有显示的数据记录" >
        <Columns >
        <asp:TemplateField >
        <ItemTemplate >
        <input  id="checkbox1"type ="checkbox" runat ="server" onclick="AddRemoveValues(this)" value='<%#DataBinder.eval_r(Container.DataItem,"UserName") %>'/>
        </ItemTemplate>
        </asp:TemplateField>
        </Columns>
    </asp:GridView>
<asp:HiddenField ID="HiddenField1" runat="server" />
<script language ="javascript" type ="text/javascript">

        functionAddRemoveValues(oChk) {
            if(oChk.checked) {
                document.getElementByIdx_x("HiddenField1").value+= "," + oChk.value;
            }
            else {
                document.getElementByIdx_x("HiddenField1").value=document.getElementByIdx_x("HiddenField1").value.replace(","+oChk.value,"");
            }
        }
    </script>

技巧58 在浏览器中访问Word文件
可以通过ResponseRedirect()方法实现
前提:把word文档放入到工程中了。
Response.Redirect(<script language="javascript">this.parent.rightFrame.lacation.href='File/
细说ASP.net.doc'</script>);
技巧59 通过Forms身份验证之前也能访问网站资源
web.config中设置location标记,实现在通过Forms身份验证之前也能访问指定的网站资源。
 <location path ="Images">
    <system.web >
      <authorization >
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
web.config设置Form身份验证
 <authentication mode="Forms">
      <formsloginUrl="~/Account/Login.aspx" timeout="2880"  defaultUrl="~/Default.aspx"/>
    </authentication>
    <authorization >
      <deny users ="?"/>
    </authorization>
技巧60 利用PostBackUrl属性实现页面传值
 <asp:Button ID="Button1" runat="server"Text="Button"   PostBackUrl="~/Default.aspx" />
技巧61 Table控件中显示标题
 <table><caption >
这是表格的标题</caption></table>
技巧62 Web页中使用广告控件
使用广告轮播控件AdRotator实现广告图片轮流显示
1.
创建XML文件
2.
XML文件与AdRotator控件绑定
<?xml version="1.0" encoding="utf-8" ?>
<Advertisement>
  <Ad>
    <ImageUrl>~/images/1.jpg</ImageUrl>
    <NavigateUrl>http://www.mingrisoft.com</NavigateUrl>
    <AlternateText>
中介</AlternateText>
    <Impression>100</Impression>
    <Keyword>
中介</Keyword>
  </Ad>
  <Ad>
    <ImageUrl>~/images/2.jpg</ImageUrl>
    <NavigateUrl>http://www.mingrisoft.com</NavigateUrl>
    <AlternateText>
中介</AlternateText>
    <Impression>100</Impression>
    <Keyword>
中介</Keyword>
  </Ad>
  <Ad>
    <ImageUrl>~/images/3.jpg</ImageUrl>
    <NavigateUrl>http://www.mingrisoft.com</NavigateUrl>
    <AlternateText>
中介</AlternateText>
    <Impression>100</Impression>
    <Keyword>
中介</Keyword>
  </Ad>
</Advertisement>
 <asp:AdRotator ID="AdRotator1" runat="server"AdvertisementFile ="~/App_Data/ad.xml" Target="_blank"  />
注意:XML文件放入App_Data文件夹时,XML文件就自动具有允许ASP.NET在运行时对其进行读取的相应权限。将XML文件放入App_Data文件夹有助于防止该文件在浏览器中被查看。
技巧63 Web页中滚动显示公告信息
使用marquee元素在页面中创建一个连续滚动文本的区域。主要属性如下:
direction
:设置文本滚动的方向。
onmouseout:
调用this.start()方法,在光标离开marquee时继续滚动显示。
onmouseover:
调用this.stop()方法,在光标滑过marquee时停止滚动显示。
 <marquee direct="up"onmouseon="this.start()"onmouseover="this.stop()" scrollAmount="2"scrollDelay="7" style="width:426px;height:332px">
    <span >
    
我爱我的祖国
    </span>
    </marquee>
技巧64 TextBox控件设置热键
Label
控件除了可以再Web窗体上显示信息,还可以设置TextBox控件获得焦点的热键。将Label控件的AccessKey属性设置为“U”,表示热键是<ALT+U>,将AssociatedControlID属性设为“txtUserName”表示在页面上按<ATL+U>键时txtUserName控件获得焦点。

       <asp:LabelID="Label1" runat="server" Text="Label" AccessKey="U" AssociatedControlID="txtUserName"></asp:Label>
        <asp:TextBoxID="txtUserName" runat="server"></asp:TextBox>
技巧65实现客户端回调CallBack

 

第十篇 必知必会的40LINQ方面的经验技巧

技巧01 查询非泛型集合
使用Cast()方法将非泛型的IEnumerable类型转为泛型的IEnumerable<T>
Cast
()方法并不能转换为任意类型,通常只能转换为该变量装箱之前的类型。
 ArrayList arrList = new ArrayList();
            for(int i = 0; i < 100; i++)
            {
                arrList.Add(i.ToString());
            }
            //
使用Cast()方法进行数据类型转换
            varquery = from item in arrList.Cast<string>()
                        whereitem.IndexOf("9") > -1
                        selectitem;
            Response.Write("
包含9的数值是:");
            foreach(var item in query)
            {
                Response.Write(item+".");
            }
技巧02 筛选指定类型元素
通过OfType()方法可以从数据源中筛选出指定类型的元素。
  ArrayList arrList = new ArrayList();
            arrList.Add(1);
            arrList.Add(2);
            arrList.Add("Ad");
            arrList.Add("dad");
            //
使用LINQ查询动态数组中指定类型的元素
            varquery = from item in arrList.OfType <string>()
                        selectitem;
            Response.Write("
是字符串类型的有:");
            foreach(var item in query)
            {
                Response.Write(item+".");
技巧03 转换为泛型列表
使用ToList()可以实现将IEnumerable<T>转换为List<T>类型。
 List<UserInfo> users = new List<UserInfo> {
            newUserInfo{UserCode=1,UserName="User001",Password="001"},
            newUserInfo{UserCode=2,UserName="User002",Password="002"},
            newUserInfo{UserCode=3,UserName="User003",Password="003"},
            newUserInfo{UserCode=4,UserName="User004",Password="004"}};
            varquery = from item in users
                        whereitem.UserName == "User001" || item.Password == "003"
                        selectitem;
            //
使用ToList()可以实现将IEnumerable<T>转换为List<T>类型。
            List<UserInfo>filteredUsers = query.ToList<UserInfo>();
技巧04 转换为数组
使用ToArray()可以实现将IEnumerable<T>转换为T[]类型。
 List<UserInfo> users = new List<UserInfo> {
            newUserInfo{UserCode=1,UserName="User001",Password="001"},
            newUserInfo{UserCode=2,UserName="User002",Password="002"},
            newUserInfo{UserCode=3,UserName="User003",Password="003"},
            newUserInfo{UserCode=4,UserName="User004",Password="004"}};
            varquery = from item in users
                        orderbyitem.UserCode descending
                        selectitem;
            //
使用ToArray()可以实现将IEnumerable<T>转换为T[]类型。
            UserInfo[]userArr = query.ToArray<UserInfo>();
技巧05 转换为字典类型
使用ToDicionary()可以实现将IEnumerable<T>类型转换为字典类,转换过程中按照指定的键值将数据源的元素一对一的放入字典类型中。
 List<UserInfo> users = new List<UserInfo> {
            newUserInfo{UserCode=1,UserName="User001",Password="001"},
            newUserInfo{UserCode=2,UserName="User002",Password="002"},
            newUserInfo{UserCode=3,UserName="User003",Password="003"},
            newUserInfo{UserCode=4,UserName="User004",Password="004"}};
            varquery = from item in users
                        orderbyitem.UserCode >2
                        selectitem;
            //
使用ToDictionary()可以实现将query转换为字典类型
             Dictionary<int ,UserInfo> userArr = query.ToDictionary (Item=>Item.UserCode);
技巧06 转换为一对多的字典
一对多的字典类型Lookup<TKeyTValue>中可以有重复的键TKey,并且按键分组存放值类型TValue,即一个键类型中存放的是一个值类型的列表。
  List<UserInfo> users = new List<UserInfo> {
            newUserInfo{UserCode=1,UserName="User001",Password="001"},
            newUserInfo{UserCode=1,UserName="User002",Password="002"},
            newUserInfo{UserCode=2,UserName="User003",Password="003"},
            newUserInfo{UserCode=2,UserName="User004",Password="004"}};
            varquery = from item in users
                        orderbyitem.UserCode <3
                        selectitem;
            //
使用ToLookup方法将query转换为一对多字典类型
             Dictionary<int ,UserInfo> userArr = query.ToLookup  (Item=>Item.UserCode);

技巧07 创建包含默认元素或空值的集合
使用DefaultIfEmpty()方法判断带元素的数组是否为空。
 int[] arr1 = { 1,2,3,4,5,6,7,8,9};
            int[]arr2 = { };
            varquery1 = arr1.DefaultIfEmpty();//
判断元素是否为空
            varquery2 = arr2.DefaultIfEmpty();//
该方法判断如果元素为空返回-1
            foreach(var item in query1)
            {
                Response.Write(item+ ".");//
结果为{1,2,3,4,5,6,7,8,9}
            }
            foreach(var item in query2)
            {
                Response.Write(item+".");//
结果为{-1}
            }
技巧08 比较两个数据表数据是否完全相同
实现思路是调用Intersect()方法取两个数据表的交集,如果交集的行数与两个数据表的行数都相等就表示两个数据表的数据完全相同。
DataSet ds = new DataSet();
            DataTabledt = new DataTable();
            ds.Tables.Add(dt);
            varquery1 = from item in ds.Tables[0].AsEnumerable()
                         whereitem.Field<double>("saleAmount") > 1000
                         selectitem;
            varquery2 = from item in ds.Tables[0].AsEnumerable()
                         selectitem;
            varcompare = query1.Intersect(query2 );//
获取两个集合的交集
            if(query1.Count() == query2.Count() && query1.Count() == compare.Count())
                Response.Write("query1
query2中的数据完成相同");
         
技巧09 创建指定范围值的序列
Enumerable类的Range()方法可以通过指定数值的下限和上限创建指定范围的整数序列。
var query = Enumerable.Range(11,10);//
查询并返回从11开始至20范围内的数字序列
技巧10 创建包含指定数量重复值的序列
使用Repeat()方法可以创建一个包含指定数量重复值的序列。
var query = Enumerable.Repeat(9,10);
技巧11 LINQ查询中的限定符
ALL
:检测序列中的所有元素是否满足指定的条件。如果满足返回true,否则返回false
Any
:检测序列中是否存在满足指定条件的元素,如果存在返回true,否则返回false
Contains
:检测序列中是否包含指定的元素,如果包含返回true,否则返回false
 List<UserInfo> users = new List<UserInfo> {
            newUserInfo{UserCode=1,UserName="User001",Password="001"},
            newUserInfo{UserCode=2,UserName="User002",Password="002"},
            newUserInfo{UserCode=3,UserName="User003",Password="003"},
            newUserInfo{UserCode=4,UserName="User004",Password="004"}};
            boolisAll = users.All(item=>item.UserCode>1);//
返回false
            boolisAny = users.Any(item => item.UserCode > 2);//
返回true
            UserInfotempUser = users[3];
            boolisContain = users.Contains(tempUser );//
返回true
技巧12 查询序列中指定区域的元素
Skip
操作:跳过序列中指定数量的元素,返回由剩余元素组成的序列。
SkipWhile
操作:跳过序列中满足指定条件的元素,返回由剩余元素组成的序列
Take
操作:从序列的开头开始取指定数量的元素返回有这些元素组成的序列
Take While
操作:从序列的开头的开始取满足指定条件的元素,返回由这些元素组成的序列。
 int[] arr = { 0,1,2,3,4,5,6,7,8,9};
            varquery1 = arr.Skip(8);//
跳过8个元素取值
            foreach(var item in query1)
            {
                Response.Write(item+".");
            }
            varquery2 = arr.SkipWhile(item=>item<8);//
跳过小于8的元素取值
            varquery3 = arr.Take(2);//
取序列的头两个元素
            varquery4 = arr.TakeWhile(itm=>itm<2);//
从头开始取小于2的元素
技巧13 判断两个序列是否相等
两个序列相等有两个条件:
1.
序列元素的数量相等,即序列的长度相同
2.
两个序列的对应元素值相等。
使用Enumerable类的SequenceEqual()方法判断两个序列是否相等。
int[] arr = { 0,1,2,3,4,5,6,7,8,9};
int[] arr1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 bool isEqual = arr.SequenceEqual(arr1 );
           
技巧14 将两个序列串联起来
使用Contact()方法可以串联两个序列。串联操作是指将一个序列的元素按顺序全部追加到另一个序列中。
 int[] arr = { 0,1,2,3,4,5,6,7,8,9};
int[] arr1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var contactArr = arr.Concat(arr1 );
//
输出 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9
技巧15 使用嵌套查询
  DataClassesDataContext dc = new DataClassesDataContext();
            varquery=from type in dc.DictionaryType
                      selectnew
                      {
                          DictTypeName=type.DictTypeName,
                          //
以下是嵌套的子查询
                          ItemList=fromitem in dc.DictionaryItem
                                   whereitem.DictTypeID==type.DictTypeID
                                   selectitem
                      }
如果在LINQ to SQL设计器已为字典类别表和字典项表建立了关联关系,则为每个字典类别自动添加DictionaryItem属性。直接调用DictionaryItem属性也能获得该字典类别关联的字典项集合。
上面代码等价于:
DataClassesDataContext dc = new DataClassesDataContext();
            varquery=from type in dc.DictionaryType
                      selectnew
                      {
                          DictTypeName=type.DictTypeName,
                          //
以下是嵌套的子查询
                          ItemList=type.DictionaryItem
                      }
技巧16 操作泛型排序列表
泛型排序列表SortList<TKey,TValue>表示按照键进行排序的键/值对的集合。键值对是KeyValuePair<TKey,TValue>类型,泛型排序列表具有以下3个特点:
1.
将添加到泛型排序列表的元素自动按键进行排序。
2.
泛型排序列表中的键不能修改,不能为空,不能重复
3.
泛型排序列表中的值可以修改,可以为空,可以重复。
 SortedList<int, UserInfo> users = new SortedList<int,UserInfo>();
            users.Add(3,newUserInfo (1,"User01","01"));
            users.Add(2,new UserInfo(2, "User02", "02"));
            users.Add(1,new UserInfo(3, "User03", "02"));
//
泛型排序列表按键自动进行排序
            foreach(var item in query)
            {
                Response.Write(string.Format ("{0},{1}",item.Value ,item .Value.UserName));
            }
技巧17 操作泛型双向链表
LinkedList<T>表示由T指定类型的双向链表,它通过当前元素可以直接访问该元素的前一个或后一个元素(如果不存在返回空)。元素为LinkedListNode<T>类型。泛型双向链表具有以下两个特点
1.
每个节点都有指向前一个节点的Previous属性和指向后一个节点的Next属性。
2.
当前节点可以直接操作它的前一个或后一个节点。
 LinkedList<int> ints = new LinkedList<int>();
            ints.AddFirst(0);
            for(int i = 1; i < 10; i++)
            {
                ints.AddAfter(ints.Find(i- 1), i);
            }
            varquery = from item in ints
                        whereitem > 0 && item < 9
                        orderbyitem descending
                        selectitem;
            foreach(var item in query)
            {
                Response.Write(item+".");
            }
技巧18 操作泛型队列
泛型Queue<T>是由T指定类型的先进先出的线性表。使用Enqueue()方法进行元素入队操作。使用Dequeue()方法进行元素出队操作。使用Clear()方法进行清空队列操作。泛型队列具有以下3个特点:
1.
添加元素到泛型队列中称为入队,删除元素称为出对。
2.
泛型队列具有先进先出的特点,及元素进入队列的顺序和队列中删除的顺序一致。
3.
泛型队列允许包含重复的元素甚至可以包含空元素。
  Queue<int> arr2 = new Queue<int>();
            for (inti = 0; i < 10; i++)
            {
                arr2.Enqueue(i);
            }

技巧19 按照多个条件分组
实现思路是通过匿名类型将需要作为分组条件的属性封装为一个对象。
List<Store>StoreList=new List<Store>
            {
                newStore{WareHouse="
一号仓库",Product="电视机",Quantity=10},
                newStore{WareHouse="
一号仓库",Product="电视机",Quantity=10},
                newStore{WareHouse="
一号仓库",Product="洗衣机",Quantity=10},
                newStore{WareHouse="
二号仓库",Product="洗衣机",Quantity=40}
            }
            //
按一个条件分组
            varquery=from item  in StoreList
                      groupitem by item.WareHouse into g
                      selectnew
                      {
                          
仓库名=g.Key ,
                          
数量=g.Sum (item=>item.Quantity)
                      };
            //
按多个条件分组
            varquery2=from item in StoreList
                       groupitem by new{item.WareHouse,item.Product}into g
                       selectnew
                       {
                           
仓库名=g.Key.WareHouse  ,
                           
商品名=g.Key.Product ,
                          
数量=g.Sum (item=>item.Quantity)
                       };
技巧20 操作泛型哈希集合
泛型哈希集合Hash<T>是由T指定类型的基于集合的模型,泛型哈希集合可以提供性能的如并集、交集、补集等集合运算。泛型哈希集合具有以下2个特点:
1.
泛型哈希集合中的元素不能重复。
2.
泛型哈希集合提供许多集合操作。
 HashSet <int >arr=new HashSet<int> ();
技巧21 实现LINQ动态查询的方法
 public IEnumerable<TSource>ConditionQuery<TSource>(IEnumerable<TSource> source,Func<TSource, bool> condition)
        {
            returnsource.Where(condition );
        }
    List <int>ints=new List<int>{0,1,2,3,4,5,6,7,8,9};
            varquery=ConditionQuery (ints,itm=>itm%2==0);

技巧22 操作泛型排序字典
泛型排序字典SortedDictionary<TKeyTValue>。跟泛型字典最大的区别是泛型排序字典对添加的元素自动按键进行排序。
技巧23 查找字符串中指定类型的字符
string
类型实现了IEnumerable接口和IEnumerable<char>接口,所以我们可以使用LINQ对字符串进行操作。可以把字符串看做序列,把字符串中的字符看做元素。
string sourceString = "int i=5;string s=(i%2==0?\"
偶数\":\"奇数\");";
            varquery = from item in sourceString //
查询所有的数字、标点、符号
                        wherechar.IsDigit(item) || char.IsSymbol(item) || char.IsPunctuation(item)
                        selectitem;
            foreach(var item in query )
            {
                Response.Write(item.ToString()+"   ");//
查询结果:=5=%2==0"":""
            }
技巧24 过滤出包含指定单词的句子
  string text="dsaf,msadfdm,.a.asd./as";
            string[]sentences = text.Split('.','?','!');
            varquery1 = from item in sentences
                         letwords = item.Split(new char[] { '.', '?', '!', ',', ';', ':' },StringSplitOptions.RemoveEmptyEntries)
                         wherewords.Contains("of")
                         selectitem;

技巧25 统计每个单词在文章中的出现次数
 string text="dsaf,msadfdm,.a.asd./as";
            string[]sentences = text.Split(new char[] { '.', '?', '!', ',', ';', ':' },StringSplitOptions.RemoveEmptyEntries);
            string[]distinctWords = sentences.Distinct().ToArray<string>();//
去掉重复
            int[]counts=newint [distinctWords .Length ];
            for(int i = 0; i < distinctWords.Length; i++)
            {
                stringtempWord=distinctWords [i];
                varquery = from item in sentences
                            whereitem.ToLower() == tempWord.ToLower()
                            selectitem;
                counts[i]= query.Count();
            }
技巧26 查找在文章中以ing结尾的单词
技巧27 取两个目录中的同名文件
实现思路是将两个目录中的文件信息分别放入两个文件信息列表,使用LINQ将两个文件信息列表按文件名进行关联。
  string dir1 = Server.MapPath("~/App_Data/Dir1/");
            List<FileInfo>files1 = new List<FileInfo>();
            foreach(string file in Directory.GetFiles(dir1))
            {
                files1.Add(newFileInfo (file));
            }
            stringdir2 = Server.MapPath("~/App_Data/Dir2/");
            List<FileInfo>files2 = new List<FileInfo>();
            foreach(string file in Directory.GetFiles(dir2))
            {
                files2.Add(newFileInfo(file));
            }
            //LINQ
查找出两个文件夹中包含的同名文件
            varquery = from file1 in files1
                        joinfile2 in files2 on file1.Name equals file2.Name
                        orderbyfile1.Name
                        selectfile1;
            foreach(var item in query)
            {
                Response.Write(string.Format("{0},{1}",item.Name ,item.Length ));
            }

           
        }
        publicIEnumerable<TSource>ConditionQuery<TSource>(IEnumerable<TSource> source,Func<TSource, bool> condition)
        {
            returnsource.Where(condition );
        }
技巧28 使用LINQ创建DataView
DataSet ds = new DataSet();
            varquery = from item in ds.Tables[0].AsEnumerable()
                        selectitem;
            DataViewdv = query.AsDataView();//
将序列转换为DataView
            DataTabledt = query.CopyToDataTable();//
将序列转换为DataTable
技巧29 使用LINQ创建XML文件
 string path = Server.MapPath("App_Data/new.xml");
            XDocumentdoc = new XDocument(
                newXDeclaration("1.0", "utf-8", "yes"),
                newXElement("People",
                    newXAttribute("IDCard", "460104"),
                    newXElement("Name", "
张三"),
                    newXElement("Sex", "
"),
                    newXElement("Old","20")
                    )
                    );
            doc.Save(path);
技巧30 添加元素到XML文件
 string path = Server.MapPath("App_Data/new.xml");
            XElementxe = XElement.Load(path);
         
                XElementnewPerson= new XElement("People",
                    newXAttribute("IDCard", "460104"),
                    newXElement("Name", "
张三"),
                    newXElement("Sex", "
"),
                    newXElement("Old","20")
                    );
                xe.Add(newPerson);
           xe.Save(path);
技巧31 修改XML文件中元素
string path = Server.MapPath("App_Data/new.xml");
            XElementxe = XElement.Load(path);
            IEnumerable<XElement>element = from ee in xe.Elements("Person")
                                            whereee.Attribute("IDCard").Value == "460104" &&ee.Element("Name").Value == "
张三"
                                            selectee;
            if(element.Count ()>0)
            {
                XElementfirst = element.First();
                first.SetAttributeValue("IDCard","555555");
                first.SetElementValue("Name","
李四");
                //
全部替换为新元素的内容
                first.ReplaceNodes(
                    newXElement ("Sex","
"),
                    newXElement("Name", "dsa"),
                    newXElement ("Old","22"));
            }
 xe.Save(path );
技巧32 删除XML文件中的元素
string path = Server.MapPath("App_Data/new.xml");
            XElementxe = XElement.Load(path);
            IEnumerable<XElement>element = from ee in xe.Elements("Person")
                                            whereee.Attribute("IDCard").Value == "460104" &&ee.Element("Name").Value == "
张三"
                                            selectee;
            if(element.Count ()>0)
            {
                XElementfirst = element.First();
               first.Remove();
            }
 xe.Save(path );
技巧33 XML文件中的属性转换为元素
 string path = Server.MapPath("App_Data/new.xml");
            XElementxe = XElement.Load(path);
            IEnumerable<XElement>element = from ee in xe.Elements("Person")
                                            whereee.Attribute("IDCard").Value == "460104" && ee.Element("Name").Value== "
张三"
                                            selectee;
            if(element.Count ()>0)
            {
                XElementfirst = element.First();
                XAttributeattribute = first.Attribute("IDCard");
                first.AddFirst(
                    newXElement (attribute .Name ,attribute .Value ));
                first.RemoveAttributes();
            }
            xe.Save(path);
技巧34 查找指定名称的文件
 string dir1 = Server.MapPath("~/App_Data/Dir1/");
            List<FileInfo>files1 = new List<FileInfo>();
            foreach(string file in Directory.GetFiles(dir1))
            {
                files1.Add(newFileInfo(file));
            }
            varquery = from item in files1
                        whereitem.Extension == ".doc" &&item.Name.IndexOf(".net") > -1
                        orderbyitem.Name
                        selectitem;
技巧35 查找指定属性的文件
 string dir1 = Server.MapPath("~/App_Data/Dir1/");
            List<FileInfo>files1 = new List<FileInfo>();
            foreach(string file in Directory.GetFiles(dir1))
            {
                files1.Add(newFileInfo(file));
            }
            varquery = from item in files1
                        whereitem.Length >=20000&&item.Length <500000
                        orderbyitem.Length
                        selectitem;
技巧36 查找包含指定内容的文件
 string dir1 = Server.MapPath("~/App_Data/Dir1/");
            List<FileInfo>files1 = new List<FileInfo>();
            foreach(string file in Directory.GetFiles(dir1))
            {
                files1.Add(newFileInfo(file));
            }
            stringfindStr = "
";
            varquery = from item in files1
                        whereitem.Extension ==".txt"
                        letcoutent = System .IO.File .ReadAllText (item.FullName ,System .Text .Encoding.Default )
                        wherecoutent .Contains (findStr )==true
                        orderbyitem.Name
                        selectitem;
技巧37 合计XML元素值
    string path =Server.MapPath("App_Data/new.xml");
            XElementxe = XElement.Load(path);
            IEnumerable<XElement>element = from ee in xe.Elements("Person")
                                            selectee;
            decimaloldSum = element.Sum(itm=>Convert .ToDecimal (itm.Element("Old").Value ));
技巧38 将字符串数组按元素长度分组
 string[] words = new string[] {"what","is","your","name","?","my","name","is","cai"};
            varGroups = from word in words
                         groupword by word.Length into lengthGroups
                         selectnew
                         {
                             Lenth= lengthGroups.Key,
                             WordCollect= lengthGroups
                         };
技巧39 使用LINQListView提供数据

技巧40 获得序列中元素的索引位置
使用selectselectMany操作符能够获得序列中该元素的索引位置。

 

你可能感兴趣的:(C#,编程感悟)