技巧 os javascript html asp.net
通过ASP.NET可以对一些无用的进程进行远程杀死,下面的代码先列出正在活动的所有进程,然后进行杀死。需要注意的是:这个文件要放在具有Administrator访问权限的虚拟目录下。
以下是C#代码:
<%@ Page Language="c#" %>
<HTML>
<HEAD>
<% @ Import namespace= "System.Diagnostics" %>
<script language="C#" runat="Server" debug="true">
void Page_Load(Object Sender, EventArgs e){
btnKill.Attributes.Add("onclick", "javascript: return confirm('你真的要杀死这个进程吗?');");
}
private void KillProcess(string processName){
System.Diagnostics.Process myproc= new System.Diagnostics.Process();
//得到所有打开的进程
try{
foreach (Process thisproc in Process.GetProcessesByName(processName)) {
if(!thisproc.CloseMainWindow()){
thisproc.Kill();
}
}
}
catch(Exception Exc)
{
msg.Text+= "杀死" +procname.SelectedItem.Text + "失败!";
}
}
public void btnKill_Click(object sender, System.EventArgs e)
{
KillProcess(procname.SelectedItem.Text);
msg.Text= procname.SelectedItem.Text +" 已经被杀死。";
}
public void btnShow_Click(object sender, System.EventArgs e){
ArrayList procList =new ArrayList();
string tempName="";
int begpos;
int endpos;
foreach (Process thisProc in System.Diagnostics.Process.GetProcesses()) {
tempName=thisProc.ToString();
begpos = tempName.IndexOf("(")+1;
endpos= tempName.IndexOf(")");
tempName=tempName.Substring(begpos,endpos-begpos);
procList.Add(tempName);
}
procname.DataSource=procList;
procname.DataBind();
}
</script>
</HEAD>
<body>
<Basefont Face="Tahoma" />
<center><h2>ASP.NET 进程杀死器!</h2>
<Table cellspacing=2 cellpadding=2 border=0 BGCOLOR="#fFCC66">
<form id="frmProc" runat="Server" method="post">
<TR><TD><ASP:DropDownList id="procname" runat="server" /></TD><TD>
进程名字</TD></TR>
<TR><TD>
<asp:button id="btnKill" Text="杀死进程" runat="server" CausesValidation="False" onclick="btnKill_Click" />
</TD>
<TD><asp:button id="btnShow" Text="列出所有进程" runat="server" CausesValidation="False" onclick="btnShow_Click" />
</TD></TR>
</TABLE>
<center><asp:Label id="msg" runat="server"/></center>
</form>
</center>
</body>
</HTML>
posted @ 2008-01-19 16:44 小罗 阅读(162) 评论(0)
编辑
关于Forms验证的文章网上千百篇,但我花了1天半的时间学会了“一点点”,
现在把代码分享出来,希望对像我一样的初学者所有帮助,也希望高手给指点一下:
--------------------------------------------------------------------------------
Step 1:新建数据库(库:MyForms ;表:users ;字段:ID,userName, userPwd);
Step 2:新建网站,web.config 的文件全部代码如下:
web.config 的全部代码
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true"/>
<sessionState cookieless="AutoDetect"/>
<!--解决当浏览器端禁用Cookie时-->
<authentication mode="Forms">
<forms name="CookieName" loginUrl="login.aspx" protection="All"></forms>
<!--loginUrl为登录面URL,如果没有身份验证Cookie,客户端将被重定向到此URL-->
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
</system.web>
</configuration>
Step 3:添加一个 login.aspx 页面;拖2个 TextBox ,1个Button 和1个CheckBox ;
并将CheckBox 的text 属性设为:“是否保存Cookis ";
Step 4:login.aspx 的隐藏代码如下:
login 全部隐藏代码
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient; //导入命名空间
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
string userName = TextBox1.Text.Trim();
string userPwd = TextBox2.Text.Trim();
SqlConnection con = new SqlConnection("Server=.;Database=MyForms;User ID=sa;Password=123456");
con.Open();
SqlCommand cmd = new SqlCommand("select count(*) from users where userName='" + userName + "' and userPwd='" + userPwd + "'", con);
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count > 0)
{
System.Web.Security.FormsAuthentication.SetAuthCookie(this.TextBox1.Text, this.CheckBox1.Checked);
Response.Redirect("Default.aspx");
//上面两行,也可以换成下面一行,如通过验证则直接转向请求的页面,而不需要Responsel.Redirect("");
//System.Web.Security.FormsAuthentication.RedirectFromLoginPage(this.TextBox1.Text, false);
}
else
{
Response.Write("用户不合法");
}
}
}
Step 5:拖一个Button 到 Default.aspx 上,将其text 属性设为"登出",其事件代码如下:
Button 事件代码
protected void Button1_Click(object sender, EventArgs e)
{
System.Web.Security.FormsAuthentication.SignOut();
}
posted @ 2008-01-19 16:03 小罗 阅读(154) 评论(0)
编辑
SQL Server提供了一个特别的数据类型:image,它是一个包含binary数据的类型。下边这个例子就向你展示了如何将文本或照片放入到数据库中的办法。在这篇文章中我们要看到如何在SQL Server中存储和读取图片。
1、建立一个表:
在SQL SERVER中建立这样结构的一个表:
2、存储图片到SQL SERVER数据库中
为了能存储到表中,你首先要上传它们到你的WEB 服务器上,你可以开发一个web form,它用来将客户端中TextBox web control中的图片入到你的WEB服务器上来。将你的 encType 属性设置为:myltipart/formdata.
Stream imgdatastream = File1.PostedFile.InputStream;
int imgdatalen = File1.PostedFile.ContentLength;
string imgtype = File1.PostedFile.ContentType;
string imgtitle = TextBox1.Text;
byte[] imgdata = new byte[imgdatalen];
int n = imgdatastream.Read(imgdata,0,imgdatalen);
string connstr=((NameValueCollection)Context.GetConfig("appSettings"))["connstr"];
SqlConnection connection = new SqlConnection(connstr);
SqlCommand command = new SqlCommand
("Insert INTO ImageStore(imgtitle,imgtype,imgdata)
VALUES ( @imgtitle, @imgtype,@imgdata )", connection );
SqlParameter paramTitle = new SqlParameter
("@imgtitle", SqlDbType.VarChar,50 );
paramTitle.Value = imgtitle;
command.Parameters.Add( paramTitle);
SqlParameter paramData = new SqlParameter( "@imgdata", SqlDbType.Image );
paramData.Value = imgdata;
command.Parameters.Add( paramData );
SqlParameter paramType = new SqlParameter( "@imgtype", SqlDbType.VarChar,50 );
paramType.Value = imgtype;
command.Parameters.Add( paramType );
connection.Open();
int numRowsAffected = command.ExecuteNonQuery();
connection.Close();
3、从数据库中恢复读取
现在让我们来从SQL Server中读取我们放入的数据吧!我们将要输出图片到你的浏览器上,你也可以将它存放到你要的位置。
private void Page_Load(object sender, System.EventArgs e)
{
string imgid =Request.QueryString["imgid"];
string connstr=((NameValueCollection)
Context.GetConfig("appSettings"))["connstr"];
string sql="Select imgdata, imgtype FROM ImageStore Where id = " + imgid;
SqlConnection connection = new SqlConnection(connstr);
SqlCommand command = new SqlCommand(sql, connection);
connection.Open();
SqlDataReader dr = command.ExecuteReader();
if(dr.Read())
{
Response.ContentType = dr["imgtype"].ToString();
Response.BinaryWrite( (byte[]) dr["imgdata"] );
}
connection.Close();
}
要注意的是Response.BinaryWrite 而不是Response.Write.
下面给大家一个用于C# Winform的存入、读取程序。其中不同请大家自己比较!(为了方便起见,我将数据库字段简化为二个:imgtitle和imgdata。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.SqlClient;
namespace WindowsApplication21
{
///
/// Form1 的摘要说明。
///
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
///
/// 必需的设计器变量。
///
private System.ComponentModel.Container components = null;
private string ConnectionString = "Integrated Security=SSPI;Initial Catalog=;DataSource=localhost;";
private SqlConnection conn = null;
private SqlCommand cmd = null;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.PictureBox pic1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private string sql = null;
private System.Windows.Forms.Label label2;
private string nowId=null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
conn = new SqlConnection(ConnectionString);
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
///
/// 清理所有正在使用的资源。
///
protected override void Dispose( bool disposing )
{
if (conn.State == ConnectionState.Open)
conn.Close();
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
///
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.pic1 = new System.Windows.Forms.PictureBox();
this.button2 = new System.Windows.Forms.Button();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(0, 40);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(264, 48);
this.button1.TabIndex = 0;
this.button1.Text = "加入新的图片";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// pic1
//
this.pic1.Location = new System.Drawing.Point(280, 8);
this.pic1.Name = "pic1";
this.pic1.Size = new System.Drawing.Size(344, 264);
this.pic1.TabIndex = 3;
this.pic1.TabStop = false;
//
// button2
//
this.button2.Location = new System.Drawing.Point(0, 104);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(264, 40);
this.button2.TabIndex = 4;
this.button2.Text = "从数据库中恢复图像";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// openFileDialog1
//
this.openFileDialog1.Filter = ""图像文件(*.jpg,*.bmp,*.gif)|*.jpg|*.bmp|*.gif"";
//
// label2
//
this.label2.Location = new System.Drawing.Point(0, 152);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(264, 48);
this.label2.TabIndex = 5;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(632, 273);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.label2,
this.button2,
this.pic1,
this.button1});
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
posted @ 2008-01-19 16:00 小罗 阅读(238) 评论(0)
编辑
一、 错误(以外)的处理
程序健壮性最基本要求就是程序错误的处理与捕捉,在ASP.NET中,错误的处理有和其他编程语言一样的机制,可以使用Try…Catch…Finally等方式,这一点和ASP相比具有较大的进步。而且,使用这些错误处理方法,可以大大提高程序的可读性和程序调试速度,在这几个优势结合的情况下,我们更加应该注意这一点。
关于错误的处理,我们可以参考这篇文章(英文):
http://www.123aspx.com/redir.aspx?res=28336
二、 字符串的处理
网页设计中,字符串的处理几乎是最常见的了。使用ASP.NET以后,字符串的处理比ASP的速度快,而且,在ASP.NET中,专门增加一个字符串处理类StringBulider,使用这个类可以完成一些常见的字符串操作,而最主要的,使用StringBuilder可以大大提高字符串处理速度。
在ASP.NET中,最常见的就是使用“&”来连接两个字符串:
Dim myOutputString As String = "My name is"
Dim myInputString As String = " Alex"
myOutputString = myOutputString & myInputString
Response.Write(myoutputString)
现在,我们来看看StringBuilder的使用,在使用StringBuilder的时候,我们对字符串可以做一些基本的操作,比如Append、Replace、Insert、Remove等,现在我们来看具体举例。
(1)StringBuilder中Append的使用
Append和其他语言的Append一样,就是在字符串最后增加其他字符。
Dim sb as StringBuilder = New StringBuilder()
sb.append( "<table border='1' width='80%'>" )
For i = 0 To RowCount - 1
sb.Append("<tr>")
For k = 0 To ColCount - 1
sb.Append("<td>")
sb.Append( dt.Rows(i).Item(k, DataRowVersion.Current).toString())
sb.Append( "</td>" )
Next
sb.Append("<tr>")
Next
sb.Append( "</table>")
Dim strOutput as String = sb.ToString()
lblCompany.Text = strOutput
在以上的程序中,用Append方法实现了一个表格的输出,需要注意的一点是,StringBulider必须首先使用ToString()方法将其转化为String类型才可以直接输出。在以上的举例中,我们看到的全部是Append一个直接的字符串,其实,这个方法有一个很方便的功能,那就是可以直接Append其他类型的变量,比如可以直接Appemd一个Integer类型的数值,当然,我们输出以后自动转化为一个字符串:
Sub Page_Load(Source As object, E As EventArgs)
Dim sb As System.Text.StringBuilder
Dim varother As Integer
varother=9999
sb =new System.Text.StringBuilder()
sb.append("<font color='blue'>可以Append其他类型:</font>")
sb.append(varother)
Response.write(sb.toString())
End Sub
(2)字符串中其他方法的使用
我们还可以使用其他方法,我们来看看常见的:
Insert方法,可以在指定位置插入其他字符,使用方法:Insert(插入位置,插入字符);
Remove方法,可以在指定位置删除指定字数字符,使用方法:Remove(其实位置,字符数);
Replace方法,可以替换指定字符,使用方法:replace(被替换字符串,替换字符串)
字符串的具体介绍和使用方法可以参考以下文章(英文):
http://aspfree.com/aspnet/stringbuilder.aspx
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextStringBuilderClassTopic.asp
三、 数据库链接Connection和DataReader的关闭
在使用ASP编程的时候,我们就已经知道,在使用数据库连接以后,一定要将连接关闭,然后设置为NoThing。在Asp.NET中,我们仍然需要这样使用,不过,在ASP.NET中,由于使用了ADO.NET,所以,在一些相关的处理方面,实际还是有一些细微的区别,而这些区别,往往也就是我们设计的时候最需要注意的。现在,我们通过举例,来看看在常见的ADO.NET操作中,需要注意哪些问题。
(1)举例一
Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs"))
Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection)
Dim myDataReader As SqlDataReader
Try
myConnection.Open()
myDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
dropDownList1.DataSource = myDataReader
dropDownList1.DataBind()
Catch myException As Exception
Response.Write("An error has occurred: " & myException.ToString())
Finally
If Not myDataReader Is Nothing Then
'关闭DataReader
myDataReader.Close()
End If
End Try
在以上的举例中,我们注意到,这里只关闭了DataReader,并没有关闭Connection。为什么呢?仔细观察以上的ExecuteReader方法,原来,设置了ExecuteReader参数,当执行完ExecuteReader以后,会自动关闭Connection。所以,这样设置以后,就没有必要再手动关闭Connection了。
(2)举例二
Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs"))
Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection)
Try
myConnection.Open()
dropDownList1.DataSource = myCommand.ExecuteReader()
dropDownList1.DataBind()
Catch myException As Exception
Response.Write("An error has occurred: " & myException.ToString())
Finally
If Not myConnection Is Nothing AndAlso ((myConnection.State And ConnectionState.Open) = ConnectionState.Open) Then
myConnection.Close()
End If
End Try
在以上的举例中,我们发现,居然没有关闭DataReader。为什么呢?其实上面的代码中,没有直接生成DataReader对象,当然也就无从关闭了。需要注意一点的是,在关闭Connection之前,程序首先判断Connection是否已经打开,如果没有打开,也就没必要关闭了。
四、使用Web.Config/Maching.Config保存常用数据
一些数据我们需要时常使用,比如使用ADO.NET的时候,最常见的就是数据库连接语句,在ASP中,我们常常将这些信息保存在Application中。当然,在ASP.NET中,也可以这样,不过,ASP.NET已经提供一个配置文件WEB.Config,所以,我们最好将这些信息保存在WEB.Config中,当然,我们也可以保存在Machine.Config中,不过,这样的话,整个网站都必须使用,所以,一般我们都使用Web.Config。现在,我们来看具体这个文件的使用。
(1)Web.Config文件的设置
首先,我们来看Web.Config的设置,我们在这个文件中增加设置以下两个项目,设置如下:
<configuration>
<appsettings>
<add key="dsn" value="myserver"/>
<add key="someotherkey" value="somevalue"/>
</appsettings>
</configuration>
(2)变量的使用
以上XML文件设置了dsn和someotherkey两个变量,现在我们看看程序中怎样使用:
<html>
<script language="VB" runat=server>
Sub Page_Load(Sender as object, E as EventArgs)
Dim AppSettings as Hashtable = Context.GetConfig("appsettings")
DSN.Text = AppSettings("dsn")
SomeOther.Text = AppSettings("someotherkey")
End Sub
</script>
<body>
DSN Setting: <asp:label id="DSN" runat=server/> <br>
Some Other Setting: <asp:label id="SomeOther" runat=server/>
</body>
</html>
上面的程序我们看到,使用这样定义的变量很简单也很方便。
五、使用.NET的方式调试程序
ASP程序的调试一直是编写ASP最难的地方,这一点,ASP程序员大概都深有体会,因为大家都是使用Response.write来调试。而这样调试最大的缺点是,当我们调试完毕,必须一个个来删除或者注释掉这些信息,想一想,如果程序代码达到几百行或者页面很多的程序,这样的工作是多么枯燥,最怕一点,忘记将这些调试用的write删除,可能在用户使用的时候就会出现一些不雅的调试信息。
使用ASP.NET以后,我们可以直接定义Trace来实现程序的调试。以上提到的麻烦可以轻松解决,熟悉,Trace可以通过具体页面和在Web.Config配置文件中来定义实现,这样,当程序调试完毕以后,直接将Trace设置为Off就可以了,这样,程序就不会有调试功能了。
(1)页面调试的实现
在一个具体的页面需要实现调试功能的时候,我们可以这样设置:
<%@ Page Language="VB" Trace="True" %>
(2)定义WEB.Config实现
在WEB.CONFIG中,我们也可以实现程序调试的打开:
<configuration>
<system.web>
<trace enabled="true" requestLimit="10" localOnly="false"/>
</system.web>
</configuration>
使用以上的设置打开Trace以后,我们在具体的程序中就可以使用Trace来调试程序了,比如:
Trace.Write("This is some custom debugging information")
或者调试程序变量:
Trace.Write("This is is my variable and it's value is:" & myVariable.ToString())
以上设置我们可以看出,在ASP.NET中,程序调试功能已经很方便简单了
posted @ 2008-01-19 15:50 小罗 阅读(80) 评论(0)
编辑
上次做了个项目,涉及到数据库的还原和恢复,到网上找了一下,是利用SQLDMO实现的,只要添加SQLDMO引用就好了,然后利用下边的类的方法就可以实现了。
我把原作者的类扩充了一下,可以自动识别web.config里 的数据库连接字符串,可以通过变量设置还原恢复的信息。
需要注意的时还原,还原的时候问题最大了,有别的用户使用数据库的时候无法还原,解决办法就是在MASTER数据库中添加一个存储过程:
create proc killspid (@dbname varchar(20))
as
begin
declare @sql nvarchar(500)
declare @spid int
set @sql='declare getspid cursor for
select spid from sysprocesses where dbid=db_id('''+@dbname+''')'
exec (@sql)
open getspid
fetch next from getspid into @spid
while @@fetch_status<>-1
begin
exec('kill '+@spid)
fetch next from getspid into @spid
end
close getspid
deallocate getspid
end
GO
在还原之前先执行这个存储过程,需要传递dbname,就是你的数据库的名字。下边是类的原代码:(web.config里的数据库连接字符串是constr)
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
namespace web.base_class
{
/// <summary>
/// DbOper类,主要应用SQLDMO实现对Microsoft SQL Server数据库的备份和恢复
/// </summary>
public class DbOper
{
private string server;
private string uid;
private string pwd;
private string database;
private string conn;
/// <summary>
/// DbOper类的构造函数
/// </summary>
public DbOper()
{
conn=System.Configuration.ConfigurationSettings.AppSettings["constr"].ToString();
server=cut(conn,"server=",";");
uid=cut(conn,"uid=",";");
pwd=cut(conn,"pwd=",";");
database=cut(conn,"database=",";");
}
public string cut(string str,string bg,string ed)
{
string sub;
sub=str.Substring(str.IndexOf(bg)+bg.Length);
sub=sub.Substring(0,sub.IndexOf(";"));
return sub;
}
/// <summary>
/// 数据库备份
/// </summary>
public bool DbBackup(string url)
{
SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(server,uid, pwd);
oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
oBackup.Database = database;
oBackup.Files = url;//"d:\Northwind.bak";
oBackup.BackupSetName = database;
oBackup.BackupSetDescription = "数据库备份";
oBackup.Initialize = true;
oBackup.SQLBackup(oSQLServer);
return true;
}
catch
{
return false;
throw;
}
finally
{
oSQLServer.DisConnect();
}
}
/// <summary>
/// 数据库恢复
/// </summary>
public string DbRestore(string url)
{
if(exepro()!=true)//执行存储过程
{
return "操作失败";
}
else
{
SQLDMO.Restore orestore = new SQLDMO.RestoreClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(server, uid, pwd);
orestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
orestore.Database = database;
orestore.Files = url;//@"d:\Northwind.bak";
orestore.FileNumber = 1;
orestore.ReplaceDatabase = true;
orestore.SQLRestore(oSQLServer);
return "ok";
}
catch(Exception e)
{
return "恢复数据库失败";
throw;
}
finally
{
oSQLServer.DisConnect();
}
}
}
private bool exepro()
{
SqlConnection conn1 = new SqlConnection("server="+server+";uid="+uid+";pwd="+pwd+";database=master");
SqlCommand cmd = new SqlCommand("killspid",conn1);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@dbname","port");
try
{
conn1.Open();
cmd.ExecuteNonQuery();
return true;
}
catch(Exception ex)
{
return false;
}
finally
{
conn1.Close();
}
}
}
}
posted @ 2008-01-19 15:48 小罗 阅读(69) 评论(0)
编辑
在一个ASP.NET移动页面中使用DeviceSpecific/Choice构造时,你必须定义设备筛选器来测试 MobileCapabilities对象的属性。你可以在应用程序的Web.Config文件的<deviceFilters>节点中定义设备筛选器, 其中每个<filter>元素就是一个设备筛选器。下面是定义设备筛选器的语法:
<system.web>
<deviceFilters>
<filter
name="filterName"
compare="capabilityName"
argument="comparisonString"/>
<filter
name="filterName"
type="className"
method="methodName"/>
</deviceFilters>
</system.web>
如上述代码所示,存在两个<filter>元素。它分别代表两种不同类型的筛选器,分别为基于比较的筛选器和基于鉴别委托的筛选器。语法指定了这两种筛 选器类型。第一种称为基于比较的筛选器,可在运行时将开发人员指定的值与设备功能的当前值进行比较。当希望确定设备是否支持某特定功能时,可使用此类筛选 器。它的各个属性为:
属性 说明
name 必需的String属性,指定设备筛选器的名称。注意,在设置该属性时要注意它是区分大小写的。例如,isHTML和IsHTML代表不同的设备筛选器。
compare 它包含设备筛选器计算的属性。
argument 指定该功能应与之比较的参数。如果未提供任何参数,则将 null 用于比较。
下面来定义一个简单的基于比较的筛选器,你完全可以在一个<deviceFilters>元素中定义基于比较的筛选器,而无需额外的代码。例如,我们可 以添加一个用来测试某个移动设备是否支持HTML 3.2的设备筛选器,你仅需在Web.Config配置文件中添加如下的代码:
<system.web>
<deviceFilters>
<filter name="isHTML32" compare="PreferredRenderingType" argument="html32">
</filter>
</deviceFilters>
</system.web>
上面的代码定义了一个名为isHTML32的筛选器,它用来测试MobileCapabilities对象的 PreferredRenderingType属性是否等于html32。除了在DeviceSpecific/Choice构造中使用上面的筛选器外, 你还可以通过使用MobileCapabilities对象的HasCapability方法来评估设备功能,此方法供ASP.NET内部使用,用来实现 用控件语法表达的各种设备选择条件。如下面的代码所示,它也是用来查看该移动设备是否支持HTML3.2标记语言,如果设备具有指定的功能,则返回值为 true,否则为false。注意,如果是基于比较的筛选器,HasCapability方法的第二个参数为null。
MobileCapablities cap = (MobileCapabilities)Request.Browser;
if ((cap.HasCapability ("isHTML32", null))
{
// Do something.
}
提 示:当你使用Visual Studio创建一个ASP.NET Web移动应用程序时,在添加的移动Web.Config配置文件中将包含大量的基于比较的筛选器。这些筛选器包括isWML11、isHTML32、 isCHTML10。你可以打开该配置文件,查看所有的可用设备筛选器。
第二类设备筛选器称为基于鉴别委托的筛选器。当需要比基于比较的筛选器更为复杂的设备筛选功能时,可以通过提供方法的类名称和方法名称,指定基于鉴别委托的筛选器。在运行时,调用提供的方法来确定设备筛选器的计算结果是否为true。该筛选器的属性为:
属性 说明
name 筛选器的名称
type 它是提供鉴别委托的类类型。名称必须符合指定完全限定类型名的Microsoft .NET标准。ASP.NET在指定的程序集中搜索该类型。
method 它是类type上方法的名称,该方法根据传递给它的MobileCapabilities实例返回一个布尔值指示当前的设备是否满足此筛选器。
现在我们来定义一个基于鉴别委托的筛选器,首先我们需要创建一个类库项目,编写和该筛选器相关的类及方法,经过编译后,再在ASP.NET Web移动应用程序中引用包含该类的程序集,具体的实现将在后面用实例进行详细的介绍。下面是类中的静态方法的具体形式(第二个参数是可选的,你可以将该 参数作为额外的输入信息添加到上面的静态方法中):
public static bool MethodName
(System.Web.Mobile.MobileCapabilities capabilities, String param)
在Web.Config配置文件中,你可以采用<filter>元素的第二种形式定义基于鉴别委托的筛选器。例如,你创建了一个名为 isMMEonSony的筛选器,该筛选器使用了MyClass类中的一个名为MMEandSony的静态方法,而且该类的命名空间是 MyEvaluators.dll程序集里的MyNameSpace。因此我们需要在移动Web.Config配置文件中编写如下的代码:
<system.web>
<deviceFilters>
<filter name="isMMEonSony"
type="MyNameSpace.MyClass, MyEvaluators.dll"
method="MMEandSony">
</filter>
</deviceFilters>
</system.web>
在上述配置中我们设置type属性为该类的完整名称:命名空间.类名,程序集。而method属性的属性值为运行时调用的实际的方法名。
在DeviceSpecific/Choice构造中使用一个基于鉴别委托的筛选器和在DeviceSpecific/Choice构造中使用一个基于比较的筛选器没有什么太大的区别,下面是使用基于鉴别委托的筛选器的代码片断:
<mobile:Form id="Form1" runat="server">
<mobile:Label id="Label1" runat="server" Text="Client is NOT MME on Sony">
<DeviceSpecific>
<Choice Text="Client is MME on Sony" Filter="isMMEonSony">
</Choice>
</DeviceSpecific>
</mobile:Label>
</mobile:Form>
除了上面的方法外,你还可以在代码中使用MobileCapabilities.HasCapability方法来查看移动设备是否具备 isMMEonSony基于鉴别委托的筛选器的功能,如果设备具有指定的功能,则返回值为true,否则为false。在基于鉴别委托的筛选器这种情形 下,HasCapability方法的第二个参数是可选的,你可以为该参数设置一个有意义的String值。
使用第二个参数的好处就 是你可以传递一些MobileCapabilities对象无法获取的移动设备信息到HasCapability方法中,例如我们知道HTTP文件头会传 送一些和移动设备相关的信息,我们可以使用System.Web.HttpRequest对象的属性获取移动设备的一些由 MobileCapabilities对象无法获取的其它信息。下面是具体的实现代码:
if (((MobileCapabilities)Request.Browser).HasCapability(
"isMMEonSony",
Request.UserLanguages[0]))
{
// Do something.
}
posted @ 2008-01-19 15:43 小罗 阅读(293) 评论(0)
编辑
win2003 server下的IIS6默认设置下对每个运行在默认应用池中的工作者进程都会经过20多个小时后自动回收该进程,造成保存在该进程中的session丢失。
因为Session,Application等数据默认保存在运行该Web应用程序的工作者进程中,如果回收工作者进程,则会造成丢失。
解决办法:
修改配置,设置为不定时自动回收该工作者进程,比如设置为当超出占用现有物理内存60%后自动回收
该进程。通过使用默认应用程序池,可以确保多个应用程序间互相隔离,保证由于一个应用程序的崩溃不会影响另外的Web应用程序。还可以使一个独立的应用程序运行在一个指定的用户帐号特权之下。
如果使用StateServer方式或者Sql Server数据库方式来保存Session,则不受该设置的影响。
可能的原因2:
系统要运行在负载平衡的 Web 场环境中,而系统配置文件web.config中的Session状态却设置为InProc(即在本地存储会话状态),导至在用户访问量大时,Session常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡IP来访问WEB应用系统,某段时候在某台服务器保存了Session的会话状态,但在其它的WEB前端服务器中却没有保存Session的会话状态,而随着并发量的增大,负载平衡会当作路由随时访问空闲的服务器,结果空闲的服务器并没有之前保存的Session会话状态。
解决办法:
1.当您在负载平衡的 Web 场环境中运行 ASP.NET Web 应用程序时,一定要使用 SqlServer 或 StateServer 会话状态模式,在项目中我们基于性能考虑并没有选择SqlServer模式来存储Session状态,而是选择一台SessionStateServer 服务器来用户的Session会话状态。我们要在系统配置文件web.config中设置如下:
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />
还要添加一项
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/>
2. 我们同时还要在SessionStateServer 服务器中启动ASP.NET State Service服务,具体设置:控制面板>>管理工具>>服务>>ASP.NET State Service,把它设为自动启动即可。
3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置
要在 Web 场中的不同 Web 服务器间维护会话状态,Microsoft“Internet 信息服务”(IIS) 配置数据库中 Web 站点的应用程序路径(例如,\LM\W3SVC\2)与 Web 场中所有 Web 服务器必须相同。大小写也必须相同,因为应用程序路径是区分大小写的。在一台 Web 服务器上,承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2(其中应用程序路径是 \LM\W3SVC\2)。在另一台 Web 服务器上,Web 站点的实例 ID 可能是 3(其中应用程序路径是 \LM\W3SVC\3)。因此,Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使Web 场Web 站点的实例 ID 相同即可。你可以在IIS中把某一个WEB配置信息保存为一个文件,其他Web 服务器的IIS配置可以来自这一个文件。您如果想知道具体的设置请访问Microsoft Support网站:
posted @ 2008-01-19 15:41 小罗 阅读(186) 评论(0)
编辑
如果你发现session突然无理由的丢失,而当你认真的检查代码并且排除其它常规可能丢失
的可能性时,你可能会像我一样,几乎要接近崩溃~!
后来发现问题出在我用代码创建一个临时目录然后删除临时目录的删除操作上。
现在和大家分享下:希望对碰到类似钉子的朋友有用。。
说白了session丢失实质就是:应用程序重起!
应用程序什么时候自动重起呢?
请参考:Anand在dotnetindia.com发表的文章
原文引用
{
Why ASP.NET Restarts?
Found this link from one of the blogs I was browsing today. This is ASP.NET Forum post by Patrick Y. Ng of MS.
This talks about both 1.0 and 1.1
This behaviour has been bugging lots of people. ASP.Net will restart its application for various reasons. All these reasons are legitimate, but the side effect is that the application will reset all its cache, application state, and InProc session states.
You can detect the restart of application and worker process by using the performance monitor. The counters to monitor are "ASP.NET\Application Restarts" and "ASP.NET\Worker Process Restarts".
For worker process restart, ASP.NET will write an entry in the eventlog to explain why (logLevel in controls how often eventlog is written).
For application restart, however, in v1 and v1.1 there is no easy way for a customer to figure out why a restart happened.
So by listing all reasons for app restart, I hope I can help some customers to understand and avoid the restart.
For v1
------
'http://www.knowsky.com
{
Things that causes application restart:
- The max compilation limit is reached (look for numRecompilesBeforeApprestart in machine.config)
- Physical application path of the web application has changed.
- Change in global.asax or one of the included files
- Change in machine.config
- Change in web.config in the app root
- Change inside bin directory or its subdirs
- A directory is renamed to bin, or bin is created
- Overwhelming change notifications – too many files are changed too fast in one of content directories – could happen if, for example, files are generated on the fly per request
- Change in the code-access security policy file
}
- The settings of various attributes in in machine.config affect the restart/shutdown of the worker process itself. However, if you use Windows 2003, and (by default) you are NOT using IIS5 isolation mode, is ignored. Instead, the settings in "Application Pools" in IIS manager is used.
For v1.1
--------
The list for v1.1 is the same as v1, with the following new conditions:
{
- User code called HttpRuntime.UnloadAppDomain
- Any directory under the web application folder is renamed
}
IIS 6.0
--------
If you're using IIS 6.0, and you're not using IIS 5 compatible mode, then aspnet_wp.exe will be replaced by w3svc.exe. You may want to go to IIS Manager, go to Application Pools/DefaultAppPool, and see if any of the parameters on the Recycling and Performance tabs are causing the IIS worker process (w3svc.exe) to shutdown.
}
也就是说 asp.net 会监视应用程序目录,一但有被监视
的动作发生(比如:修改了config、重命名目录等)应用程序就会自动重起
当然这时你的session一定丢失了。
如果避免不了这种操作(如:重命名目录);这里我们可以用cookie存信息或存到数据库去;
注意:除了以上列出的英文条件外。目录的删除操作一定丢失session。asp.net的内部机制对待目录有点像个守财奴,它死守着目录,你创建它不会管(往里加),一但创建他就会监视该目录,若你要删除或重命名它的(动它的目录),它就发生重起了。
posted @ 2008-01-19 15:40 小罗 阅读(80) 评论(0)
编辑
using System.IO;
1.文件上传
----------
如下要点:
HTML部分:
<form id="form1" runat="server" method="post" enctype="multipart/form-data">
<input id="FileUpLoad" type="file" runat="server"/><br />
后台CS部分 按钮事件
//string strFileFullName = System.IO.Path.GetFileName(this.FileUpLoad.PostedFile.FileName);
//this.FileUpLoad.PostedFile.SaveAs(Server.MapPath("./xmlzip/") + strFileFullName);
2.文件下载
----------
ListBox的SelectedIndexChanged事件 设定相关下载连接
protected void lst_DownLoadFileList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
string strJS = "window.open('xmlzip/";
strJS += this.lst_DownLoadFileList.SelectedItem.Text.Trim();
strJS += "'); return false; ";
this.imgbtn_DownLoadFile.Attributes.Add("onclick", strJS);
}
catch (Exception ex)
{
ex.ToString();
}
}
或者也可以通过 改变Label的Text值 来实现点击后实现文件下载的超级连接
this.Label1.Text = "<a href=\"xmlzip/a.rar\">a.rar</a>"
3.文件删除
---------
string strFilePath = Server.MapPath("../CountryFlowMgr/xmlzip/"+this.lst_DownLoadFileList.SelectedItem.Text.Trim());
if (File.Exists(strFilePath))
{
File.Delete(strFilePath);
if (File.Exists(strFilePath))
{
Response.Write("ok");
}
else
{
Response.Write("ok");
}
}
4.得到文件夹下的文件列表
-----------
#region 得到当前可用的文件列表
/// <summary>
/// 得到当前可用的文件列表
/// </summary>
/// <param name="IsAlert">是否需要弹出提示信息</param>
private void fn_getCurrFileList(bool IsAlert)
{
try
{
//查找xmlzip文件夹下 属于其本身UnitCoding的相关zip文件
string strXmlZipDirectory = Server.MapPath("../xmlzip/");
if (Directory.Exists(strXmlZipDirectory))
{
//DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory);
DirectoryInfo di = new DirectoryInfo(strXmlZipDirectory);
FileInfo[] FI = di.GetFiles("*.zip");//只查.zip文件
if (FI.Length > 0)
{
lst_DownLoadFileList.Items.Clear();
foreach (FileInfo tmpFI in FI)
{
ListItem tmpItem = new ListItem();
tmpItem.Text = tmpFI.Name;
lst_DownLoadFileList.Items.Add(tmpItem);
}
lst_DownLoadFileList.SelectedIndex = 0;
}
else
{
if (IsAlert)
{
Response.write("查无可以下载的文件!");
}
}
}
}
catch (Exception ex)
{
ex.ToString();
}
}
#endregion
更多更详细的以后再做补充
posted @ 2008-01-19 15:36 小罗 阅读(307) 评论(0)
编辑
1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键
<table border oncontextmenu=return(false)><td>no</table> 可用于Table
2. <body onselectstart="return false"> 取消选取、防止复制
3. onpaste="return false" 不准粘贴
4. oncopy="return false;" oncut="return false;" 防止复制
5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标
6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夹中显示出你的图标
7. <input style="ime-mode:disabled"> 关闭输入法
8. 永远都会带着框架
<script language="JavaScript"><!--
if (window == top)top.location.href = "frames.htm"; //frames.htm为框架网页
// --></script>
9. 防止被人frame
<SCRIPT LANGUAGE=JAVASCRIPT><!--
if (top.location != self.location)top.location=self.location;
// --></SCRIPT>
10. 网页将不能被另存为
<noscript><iframe src="/blog/*.html>";</iframe></noscript>
11. <input type=button value=查看网页源代码
onclick="window.location = "view-source:"+ "http://www.williamlong.info"">
12.删除时确认
<a href="javascript:if(confirm("确实要删除吗?"))location="boos.asp?&areyou=删除&page=1"">删除</a>
13. 取得控件的绝对位置
//Javascript
<script language="Javascript">
function getIE(e){
var t=e.offsetTop;
var l=e.offsetLeft;
while(e=e.offsetParent)
alert("top="+t+"/nleft="+l);
}
</script>
//VBScript
<script language="VBScript"><!--
function getIE()
dim t,l,a,b
set a=document.all.img1
t=document.all.img1.offsetTop
l=document.all.img1.offsetLeft
while a.tagName<>"BODY"
set a = a.offsetParent
t=t+a.offsetTop
l=l+a.offsetLeft
wend
msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置"
end function
--></script>
14. 光标是停在文本框文字的最后
<script language="javascript">
function cc()
{
var e = event.srcElement;
var r =e.createTextRange();
r.moveStart("character",e.value.length);
r.collapse(true);
r.select();
}
</script>
<input type=text name=text1 value="123" onfocus="cc()">
15. 判断上一页的来源
javascript:
document.referrer
16. 最小化、最大化、关闭窗口
<object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Minimize"></object>
<object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">
<param name="Command" value="Maximize"></object>
<OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
<PARAM NAME="Command" VALUE="Close"></OBJECT>
<input type=button value=最小化 onclick=hh1.Click()>
<input type=button value=最大化 onclick=hh2.Click()>
<input type=button value=关闭 onclick=hh3.Click()>
本例适用于IE
17.屏蔽功能键Shift,Alt,Ctrl
<script>
function look(){
if(event.shiftKey)
alert("禁止按Shift键!"); //可以换成ALT CTRL
}
document.onkeydown=look;
</script>
18. 网页不会被缓存
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
或者<META HTTP-EQUIV="expires" CONTENT="0">
19.怎样让表单没有凹凸感?
<input type=text style="border:1 solid #000000">
或
<input type=text style="border-left:none; border-right:none; border-top:none; border-bottom:
1 solid #000000"></textarea>
20.<div><span>&<layer>的区别?
<div>(division)用来定义大段的页面元素,会产生转行
<span>用来定义同一行内的元素,跟<div>的唯一区别是不产生转行
<layer>是ns的标记,ie不支持,相当于<div>
21.让弹出窗口总是在最上面:
<body onblur="this.focus();">
22.不要滚动条?
让竖条没有:
<body style="overflow:scroll;overflow-y:hidden">
</body>
让横条没有:
<body style="overflow:scroll;overflow-x:hidden">
</body>
两个都去掉?更简单了
<body scroll="no">
</body>
23.怎样去掉图片链接点击后,图片周围的虚线?
<a href="#" onFocus="this.blur()"><img src="/blog/logo.jpg" border=0></a>
24.电子邮件处理提交表单
<form name="form1" method="post" action="mailto:****@***.com" enctype="text/plain">
<input type=submit>
</form>
posted @ 2008-01-19 15:34 小罗 阅读(40) 评论(0)
编辑
刚才“不小心”检查了一下ASP.NET生成的代码,惊讶地发现ASP.NET输出的代码居然如此地不紧凑,在标签之间有无数的空格和制表符(TAB),特别是用了嵌套表格之后,那景象真是惨不忍睹啊,有图为证:

照理说在ASP.NET生成的代码中添加这么多无用的空格/tab可能是为了使生成的HTML代码更具可读性,但是由此带来的问题就是使输出的代码变大了,在带宽有限的今天简直就是一种犯罪,浪费用户的钱财,影响用户的体验嘛!而且ASP.NET属于服务器端编程,不可能会直接编辑最终生成的HTML代码,就算把所有的空格/Tab都去了,也不会带来任何不好的影响的吧!?
基于以上考虑,祭出Reflector,果然发现HtmlTextWriter中有Indent属性控制着缩进大小,而且幸运的是该属性还是public类型的,真是天助我也,花了几分钟时间,捣鼓出如下代码:
1 public class FilterHtmlTextWriter : HtmlTextWriter
2 {
3 public FilterHtmlTextWriter(TextWriter writer, string tabString)
4 : base(writer, tabString)
5 {
6 }
7
8 public new int Indent
9 {
10 get { return 0; } // 始终返回0
11 set { base.Indent = 0; } // 始终置0
12 }
13 }
然后重载页面的Render方法(如果所有页面有公共的基类的话就更好了),加入一行代码,如下:
1 public partial class _Default : System.Web.UI.Page
2 {
3 protected override void Render(HtmlTextWriter writer)
4 {
5 // 替换writer为我们自定义的类
6 writer = new FilterHtmlTextWriter(writer.InnerWriter, "");
7 base.Render(writer);
8 }
9 //
10 }
至此大功告成,让我们重新看看页面的输出,哇塞,讨厌的空格果然变少了@_@,如下图所示:
posted @ 2008-01-19 15:31 小罗 阅读(123) 评论(0)
编辑
以前用ASP,PHP,JSP编写网站代码的时候,站点安全性总是一件头疼的事情,虽然我们编写了用户登录,注册,验证页面,但是效果总是不理想。有时候我们不得不用大量的session变量来存放相关信息,处处设防。而在.NET环境下,这个问题处理起来就非常容易了。关键是要充分理解web.config文件。首先,介绍一下web.config文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<!-- 动态调试编译
设置 compilation debug="true" 以将调试符号(.pdb 信息)
插入到编译页中。因为这将创建执行起来
较慢的大文件,所以应该只在调试时将该值设置为 true,而所有其他时候都设置为
false。有关更多信息,请参考有关
调试 ASP.NET 文件的文档。
-->
<compilation defaultLanguage="vb" debug="true" />
<!-- 自定义错误信息
设置 customErrors mode="On" 或 "RemoteOnly" 以启用自定义错误信息,或设置为 "Off" 以禁用自定义错误信息。
为每个要处理的错误添加 <error> 标记。
-->
<customErrors mode="RemoteOnly" />
<!-- 身份验证
此节设置应用程序的身份验证策略。可能的模式是 \“Windows\”、
\“Forms\”、\“Passport\”和 \“None\”
-->
<authentication mode="Windows" />
<!-- 授权
此节设置应用程序的授权策略。可以允许或拒绝用户或角色访问
应用程序资源。通配符:"*" 表示任何人,"?" 表示匿名
(未授权的)用户。
-->
<authorization>
<allow users="*" /> <!-- 允许所有用户 -->
<!-- <allow users="[逗号分隔的用户列表]"
roles="[逗号分隔的角色列表]"/>
<deny users="[逗号分隔的用户列表]"
roles="[逗号分隔的角色列表]"/>
-->
</authorization>
<!-- 应用程序级别跟踪记录
应用程序级别跟踪在应用程序内为每一页启用跟踪日志输出。
设置 trace enabled="true" 以启用应用程序跟踪记录。如果 pageOutput="true",则
跟踪信息将显示在每一页的底部。否则,可以通过从 Web 应用程序
根浏览 "trace.axd" 页来查看
应用程序跟踪日志。
-->
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
<!-- 会话状态设置
默认情况下,ASP.NET 使用 cookie 标识哪些请求属于特定的会话。
如果 cookie 不可用,则可以通过将会话标识符添加到 URL 来跟踪会话。
若要禁用 cookie,请设置 sessionState cookieless="true"。
-->
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="false"
timeout="20"
/>
<!-- 全球化
此节设置应用程序的全球化设置。
-->
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
</system.web>
</configuration>
好了,相信看过上面的介绍以后,对web.config文件一定非常了解了吧。下面我们就切入主题。为了防止用户没有经过验证就访问站点,我们的处理方法是当用户没有通过验证的时候点击任何页面将会直接跳到Login.aspx页面,具体代码如下:
<authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="login.aspx"
protection="All" path="/" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
但是这样会产生一个问题,那就是如果我的站点有一些信息是可以让任意用户随意访问的,比如站点简介,使用说明等。如果按照上面的处理方法岂不让用户觉得很麻烦,呵呵,不急,在ASP.NET中自然有相应的解决办法。下面的代码可以实现匿名用户访问Test.aspx页面:
<location path="test.aspx">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
解决了上面两个问题,相信大家心里一定有底了吧。下面就开始实现login.aspx页面。利用C#和SQL Server2000,创建一个webform页面,加入相应的控件。具体代码如下:
<%@ Page language="c#" Codebehind="login.aspx.cs"
AutoEventWireup="false" Inherits="secure.login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>Secure Site</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="javascript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="login" method="post" runat="server">
<table cellSpacing="0" cellPadding="0" border="0">
<tr>
<td vAlign="top" align="left">
<asp:label id="Message" Runat="server" ForeColor="#ff0000">
</asp:label>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<b>E-mail:</b>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:textbox id="username" Runat="server" Width="120">
</asp:textbox>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<b>Password:</b>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:textbox id="password" Runat="server"
Width="120" TextMode="Password">
</asp:textbox>
</td>
</tr>
<tr>
<td vAlign="top" align="left">
<asp:checkbox id="saveLogin" Runat="server"
Text="<b>Save my login</b>">
</asp:checkbox>
</td>
</tr>
<tr>
<td vAlign="top" align="right">
<asp:imagebutton id="btnLogin" Runat="server"
ImageUrl="/images/w2k/login/btnLogin.gif">
</asp:imagebutton>
</td>
</tr>
</table>
</form>
</body>
</HTML>
界面做好之后,就开始编写提交按钮事件,首先需要注册该事件,代码如下:
private void InitializeComponent()
{
this.btnLogin.Click += new System.Web.UI.ImageClickEventHandler(this.btnLogin_Click);
.
.
.
}
事件注册好之后,自然就是编写事件处理函数了:
private void btnLogin_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
CCommonDB sql = new CCommonDB();
string redirect = "";
if((redirect = sql.AuthenticateUser(this.Session, this.Response,
username.Text, password.Text, saveLogin.Checked)) != string.Empty)
{
// Redirect the user
Response.Redirect(redirect);
}
else
{
Message.Text = "Login Failed!";
}
}
读者看完上面的代码之后一定想问CCommonDB是哪里来的东东,这是我编写的一个类,用来处理用户登录信息的,如果成功则把相关信息写入session、Cookie和SQL数据库,同时跳到default.aspx页面。具体如下:
CCommonDB.cs
namespace secure.Components
{
public class CCommonDB : CSql
{
public CCommonDB() : base() { }
public string AuthenticateUser(
System.Web.SessionState.HttpSessionState objSession, // Session Variable
System.Web.HttpResponse objResponse, // Response Variable
string email, // Login
string password, // Password
bool bPersist // Persist login
)
{
int nLoginID = 0;
int nLoginType = 0;
// Log the user in
Login(email, password, ref nLoginID, ref nLoginType);
if(nLoginID != 0) // Success
{
// Log the user in
System.Web.Security.FormsAuthentication.SetAuthCookie(nLoginID.ToString(), bPersist);
// Set the session varaibles
objSession["loginID"] = nLoginID.ToString();
objSession["loginType"] = nLoginType.ToString();
// Set cookie information incase they made it persistant
System.Web.HttpCookie wrapperCookie = new System.Web.HttpCookie("wrapper");
wrapperCookie.Value = objSession["wrapper"].ToString();
wrapperCookie.Expires = DateTime.Now.AddDays(30);
System.Web.HttpCookie lgnTypeCookie = new System.Web.HttpCookie("loginType");
lgnTypeCookie.Value = objSession["loginType"].ToString();
lgnTypeCookie.Expires = DateTime.Now.AddDays(30);
// Add the cookie to the response
objResponse.Cookies.Add(wrapperCookie);
objResponse.Cookies.Add(lgnTypeCookie);
return "/candidate/default.aspx";
}
case 1: // Admin Login
{
return "/admin/default.aspx";
}
case 2: // Reporting Login
{
return "/reports/default.aspx";
}
default:
{
return string.Empty;
}
}
}
else
{
return string.Empty;
}
}
/// <summary>
/// Verifies the login and password that were given
/// </summary>
/// <param name="email">the login</param>
/// <param name="password">the password</param>
/// <param name="nLoginID">returns the login id</param>
/// <param name="nLoginType">returns the login type</param>
public void Login(string email, string password, ref int nLoginID, ref int nLoginType)
{
ResetSql();
DataSet ds = new DataSet();
// Set our parameters
SqlParameter paramLogin = new SqlParameter("@username", SqlDbType.VarChar, 100);
paramLogin.Value = email;
SqlParameter paramPassword = new SqlParameter("@password", SqlDbType.VarChar, 20);
paramPassword.Value = password;
Command.CommandType = CommandType.StoredProcedure;
Command.CommandText = "glbl_Login";
Command.Parameters.Add(paramLogin);
Command.Parameters.Add(paramPassword);
Adapter.TableMappings.Add("Table", "Login");
Adapter.SelectCommand = Command;
Adapter.Fill(ds);
if(ds.Tables.Count != 0)
{
DataRow row = ds.Tables[0].Rows[0];
// Get the login id and the login type
nLoginID = Convert.ToInt32(row["Login_ID"].ToString());
nLoginType = Convert.ToInt32(row["Login_Type"].ToString());
}
else
{
nLoginID = 0;
nLoginType = 0;
}
}
}
abstract public class CSql
{
private SqlConnection sqlConnection; // Connection string
private SqlCommand sqlCommand; // Command
private SqlDataAdapter sqlDataAdapter; // Data Adapter
private DataSet sqlDataSet; // Data Set
public CSql()
{
sqlConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
sqlCommand = new SqlCommand();
sqlDataAdapter = new SqlDataAdapter();
sqlDataSet = new DataSet();
sqlCommand.Connection = sqlConnection;
}
/// <summary>
/// Access to our sql command
/// </summary>
protected SqlCommand Command
{
get { return sqlCommand; }
}
/// <summary>
/// Access to our data adapter
/// </summary>
protected SqlDataAdapter Adapter
{
get { return sqlDataAdapter; }
}
/// <summary>
/// Makes sure that everything is clear and ready for a new query
/// </summary>
protected void ResetSql()
{
if(sqlCommand != null)
{
sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
}
if(sqlDataAdapter != null)
sqlDataAdapter = new SqlDataAdapter();
if(sqlDataSet != null)
sqlDataSet = new DataSet();
}
/// <summary>
/// Runs our command and returns the dataset
/// </summary>
/// <returns>the data set</returns>
protected DataSet RunQuery()
{
sqlDataAdapter.SelectCommand = Command;
sqlConnection.Open();
sqlConnection.Close();
sqlDataAdapter.Fill(sqlDataSet);
return sqlDataSet;
}
}
}
posted @ 2008-01-19 15:30 小罗 阅读(45) 评论(0)
编辑
ASP.NET 提供两个用于管理可视元素和代码的模型,即单文件页模型和代码隐藏页模型。具体内容可以参考MSDN(ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_aspnetcon/html/81b13e7a-b95b-4285-906f-d2dd77411417.htm)。
在ASP.NET Forums的页面中使用了代码隐藏页模型,但是与典型的代码隐藏页模型又稍有区别。
Default.aspx的内容如下:
<%@ Page Language="C#" %>
<%@ Import Namespace="AspNetForums.Components" %>
<%@ Register TagPrefix="Forums" Namespace="AspNetForums.Controls" Assembly="AspNetForums.Controls" %>
<%@ Register TagPrefix="mp" Namespace="MetaBuilders.WebControls.MasterPages" Assembly="MetaBuilders.WebControls.MasterPages" %>
<mp:ContentContainer runat="server" id="MPContainer" MasterPageFile="~/Themes/MasterPage.ascx">
<mp:Content id="HeadTag" runat="server">
<meta http-equiv="Refresh" content="300" />
</mp:Content>
<mp:Content id="MainContent" runat="server">
<Forums:ForumGroupView runat="server" />
</mp:Content>
</mp:ContentContainer>
首先让我们先熟悉一下Asp.Net的指令语法:指定当页和用户控件编译器处理 ASP.NET Web 窗体页 (.aspx) 和用户控件 (.ascx) 文件时所使用的设置。
ASP.NET 页框架支持以下指令:
@ Page 定义 ASP.NET 页分析器和编译器使用的特定于页的属性。只能包含在 .aspx 文件中。
@ Control 定义 ASP.NET 页分析器和编译器使用的控件特定属性。只能包含在 .ascx 文件(用户控件)中。
@ Import 将命名空间显式导入页或用户控件中。
@ Register 将别名与命名空间及类名关联起来,从而允许用户控件和自定义服务器控件在被包括到请求的页或用户控件时呈现。
@ Assembly 在编译过程中将程序集链接到当前页,以使程序集的所有类和接口都可用在该页上。
根据指令语法语法我们解读一下default.aspx:
<%@ Page Language="C#" %>
http://www.knowsky.com指定在对页中的所有内联呈现(<% %> 和 <%= %>)和代码声明块进行编译时使用的语言为C#
<%@ Import Namespace="AspNetForums.Components" %>
将命名空间显式导入到 ASP.NET网页中,同时使导入的命名空间的所有类和接口可用于文件。
<%@ Register TagPrefix="Forums" Namespace="AspNetForums.Controls" Assembly="AspNetForums.Controls" %>
创建标记前缀Forums,与程序集AspNetForums.Controls中的命名空间AspNetForums.Controls相关联。
<%@ Register TagPrefix="mp" Namespace="MetaBuilders.WebControls.MasterPages" Assembly="MetaBuilders.WebControls.MasterPages" %> (略)
继续往下看页面部分,其中主要是MetaBuilders的Master Pages 控件的用法,具体用法可参考venjiang大哥的文章(了解Master Pages库),类似Asp.Net 2.0中的MasterPage
<mp:ContentContainer runat="server" id="MPContainer" MasterPageFile="~/Themes/MasterPage.ascx">
<mp:Content id="HeadTag" runat="server">
<meta http-equiv="Refresh" content="300" />
</mp:Content>
<mp:Content id="MainContent" runat="server">
<Forums:ForumGroupView runat="server" />
</mp:Content>
</mp:ContentContainer>
其中mp:ContentContainer中的MasterPageFile指定了"母版页"的位置,mp:Content通过id与"母版页"中的mp:region相对应,最终的效果是在加载Default.aspx的时候先加载母版页,然后Default.aspx中的mp:Content添加到母版页中对应的mp:region位置,形成最终的效果。
<meta http-equiv="Refresh" content="300" />页面每300秒刷新一次
<Forums:ForumGroupView runat="server" />
表示在此位置上是Forums:ForumGroupView控件,根据页面指令我们得知对应的控件为AspNetForums.Controls.ForumGroupView,
namespace AspNetForums.Controls
{
/**//// <summary>
/// 论坛组列表服务器控件
/// </summary>
public class ForumGroupView : SkinnedForumWebControl
{
}
}
ForumGroupView继承自SkinnedForumWebControl,并实现抽象方法InitializeSkin,实现了代码分离和换皮肤。继续向下查看ForumGroupView的皮肤文件名View-ForumGroupView.ascx:
<!--广告-->
<Forums:Ads Zone="GoogleAdsense" runat="server" />
<!-- 用户登录消息及注册 -->
<% if ( Users.GetUser().IsAnonymous ) { %>
<table width="100%" cellspacing="0" cellpadding="5" border="0">
<tr>
<td>
<!-- ForumGroupView.Header.End -->
<Forums:Login SkinFilename="Skin-LoginSmall.ascx" runat="server" ID="Login1" />
<!-- ForumGroupView.MainCentent.Start -->
</td>
</tr>
</table>
<% } %>
……
然后下一个嵌套的过程又开始了。
写此篇文章,大量参考了venjiang,宝玉,ugoer等诸位大哥的文章,在次对他们表示中心的感谢,首次发文章,文笔粗糙,狗尾续貂还请各位不吝指教。
posted @ 2008-01-19 15:28 小罗 阅读(65) 评论(0)
编辑
自己做的一个项目中所运用到的技术:|
1. 日历控件(带时分秒)
2. GridView 批量删除,自定义分页,定位页码
3. GridView 修改
4. GridView 鼠标经过改变行的颜色
效果如下:
HTML:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="StfCmpManager.aspx.cs" Inherits="StfCmpManager" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>合作商信息维护</title>
<script language="javascript" type="text/javascript">
// 判断多选是否与选中项(没有选中的返回false)
function slcNo_click()
...{
if (document.form1.checkboxname.length)
...{
for (var i=0;i<document.form1.checkboxname.length;i++)
...{
if(document.form1.checkboxname[i].checked)
...{
return true;
}
}
}
else
...{
if(document.form1.checkboxname.checked)
...{
return true;
}
}
alert("请选择后再操作!");
return false;
}
// 鼠标经过改变行的颜色
if (!objbeforeItem)
...{
var objbeforeItem=null;
var objbeforeItembackgroundColor=null;
}
function ItemOver(obj)
...{
if(objbeforeItem)
...{
objbeforeItem.style.backgroundColor = objbeforeItembackgroundColor;
}
objbeforeItembackgroundColor = obj.style.backgroundColor;
objbeforeItem = obj;
obj.style.backgroundColor = "#B9D1F3";
}
//
// 多选的全选与取消
function checkJs(boolvalue)
...{
if(document.all.checkboxname.length>1)
...{
for(var i=0;i<document.all.checkboxname.length;i++)
...{
document.all.checkboxname[i].checked = boolvalue;
}
}
else
document.all.checkboxname.checked = boolvalue;
}
//
// 只有全部选中时“全选”选中
function SingleCheckJs()
...{
var flag1=false;
var flag2=false;
if (document.form1.checkboxname.length)
...{
for (var i=0;i<document.form1.checkboxname.length;i++)
...{
if(document.form1.checkboxname[i].checked)
flag1 = true;
else
flag2 = true;
}
}
else
...{
if(document.form1.checkboxname.checked)
flag1 = true;
else
flag2 = true;
}
if(flag1==true&&flag2==false)
document.getElementById("chk").checked = true;
else
document.getElementById("chk").checked = false;
}
</script>
<script type="text/javascript" language="javascript" src="Selecttime/calendar.js"></script>
</head>
<body>
<form id="form1" runat="server">
<table id="Table10" cellSpacing="0" cellPadding="0" border="0" Style="z-index: 103;
left: 21px; position: absolute; top: 20px; width: 90%;">
<tr>
<td bgColor="#fafafa">
<FIELDSET style="BORDER-RIGHT: #cccccc 1px solid; BORDER-TOP: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 45px"><LEGEND><FONT face="宋体" size="2">合作商查询</FONT></LEGEND>
<table id="Table1" height="40" cellSpacing="0" cellPadding="0" width="100%" align="center"
border="0">
<tr>
<td height="30"><FONT face="宋体"> </FONT><FONT face="宋体"> 合作商名称
<asp:textbox id="TStfName" runat="server" BorderStyle="Groove" Width="144px"></asp:textbox> </FONT></td>
</tr>
<tr>
<td style="height: 30px"> <FONT face="宋体"> 添加时间 </FONT>
<asp:textbox id="StartTime" onfocus="setday(this)" runat="server" Width="159px"></asp:textbox> 到
<asp:textbox id="EndTime" onfocus="setday(this)" runat="server" Width="160px"></asp:textbox> <FONT face="Times New Roman"> </FONT></td>
</tr>
<TR>
<TD height="30"><FONT face="宋体"> <FONT face="宋体">
<asp:button id="SelectClient" runat="server" Text="搜 索" onclick="SelectClient_Click"></asp:button> </FONT></FONT></TD>
</TR>
</table>
</FIELDSET>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" border="0" Style="z-index: 103;
left: 21px; position: absolute; top: 140px; width: 90%;">
<tr bgColor="#6B696B">
<td align="center" style="width: 85%">
<asp:GridView ID="GridView1" runat="server" Width="100%" CellPadding="4" ForeColor="#333333"
AutoGenerateColumns="False" AllowPaging="True" BorderColor="Silver"
BorderStyle="Solid" BorderWidth="1px" OnRowDataBound="GridView1_RowDataBound"
ShowFooter="false" EmptyDataText="没有数据记录!!" AllowSorting="True" OnSorting="GridView1_Sorting">
<Columns>
<asp:BoundField HeaderText="编号" DataField="id" Visible="False" />
<asp:TemplateField HeaderText="<input type='checkbox' id='chk' name='chk' onclick='checkJs(this.checked);' />全选">
<ItemTemplate>
<input type="checkbox" id="checkboxname" name="checkboxname" value='<%# DataBinder.Eval(Container.DataItem, "StfId")%>' onclick='SingleCheckJs();' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="序号">
<ItemTemplate>
<%# (Container.DataItemIndex+1).ToString()%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="充值">
<ItemTemplate>
<%#GetClientVisitInfoShowCmpMoney(DataBinder.Eval(Container.DataItem,"StfId"),DataBinder.Eval(Container.DataItem,"StfName"))%>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="公司名称" DataField="StfCmpName" SortExpression="StfCmpName"/>
<asp:BoundField HeaderText="登陆名" DataField="StfName" SortExpression="StfName" />
<asp:BoundField HeaderText="帐户金额" DataField="StfCmpMoney" SortExpression="StfCmpMoney" />
<asp:BoundField HeaderText="帐户Q币" DataField ="StfQbmoney" SortExpression="StfQbmoney" />
<asp:BoundField HeaderText="合作日期" DataField="StfRegisterTime" HtmlEncode="False" SortExpression="StfRegisterTime" />
<asp:TemplateField HeaderText="操作" >
<ItemTemplate>
<%#GetClientVisitInfoShowAnchorStr(DataBinder.Eval(Container.DataItem,"StfId"),DataBinder.Eval(Container.DataItem,"StfName"))%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<EditRowStyle BackColor="#999999" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<PagerSettings Visible="False" />
<HeaderStyle Font-Bold="False" Font-Italic="False" />
</asp:GridView>
</td>
</tr>
<tr>
<td align="center" style="height: 25px; width: 569px;">
<asp:LinkButton ID="btnFirst" CommandArgument="first" OnClick="PagerButtonClick"
runat="server">首 页</asp:LinkButton> <asp:LinkButton ID="btnPrev" CommandArgument="prev" OnClick="PagerButtonClick" runat="server">上一页</asp:LinkButton>
<asp:LinkButton ID="btnNext" CommandArgument="next" OnClick="PagerButtonClick" runat="server">下一页</asp:LinkButton>
<asp:LinkButton ID="btnLast" CommandArgument="last" OnClick="PagerButtonClick" runat="server">尾 页</asp:LinkButton>
<asp:Label ID="LblCurrentIndex" runat="server"></asp:Label>
<asp:Label ID="LblPageCount" runat="server"></asp:Label>
<asp:Label ID="LblRecordCount" runat="server"></asp:Label>
跳转到第<asp:DropDownList ID="ddlCurrentPage" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>页</td> <tr>
<td style="width: 569px">
操作:
<asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="删除合作商" />
</td>
</tr>
</table>
</form>
</body>
</html>
CS:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
public partial class StfCmpManager : System.Web.UI.Page
...{
protected void Page_Load(object sender, System.EventArgs e)
...{
string StfRight = "";
// 在此处放置用户代码以初始化页面
http://www.knowsky.com
if (Session["UserId"] == null)
...{
Response.Write("<script language='javascript'>alert('工作超时,请重新登录。');top.window.location='default.aspx';</script>");
return;
}
else
...{
StfRight = Session["UserRight"].ToString().Trim();
if (!this.IsPostBack)
...{
if (StfRight != "7" && StfRight != "8")
...{
Response.Write("<script language='javascript'>alert('你没有权限察看此页。');top.window.location='default.aspx';</script>");
return;
}
GridViewBind("");
}
}
}
private void GridViewBind(string Sqlsort)
...{
string where = string.Empty;
where = "and a.StfRight='6' and a.StfId=b.Stfid";
if (TStfName.Text.Trim() != "")
...{
where += " and a.StfCmpName like '%" + TStfName.Text.Trim() + "%'";
}
if (StartTime.Text.Trim() != "")
...{
where += " and a.StfRegistertime >= '" + StartTime.Text + "'";
}
if (EndTime.Text.Trim() != "")
...{
where += " and a.StfRegistertime <= '" + EndTime.Text + "'";
}
if (where != string.Empty)
...{
where = "Where " + where.Substring(4);
}
string connStr = ConfigurationManager.AppSettings.Get("DataConnectionString");
string SqlStr = "Select a.StfId as StfId,a.StfName as StfName,a.StfRealName as StfRealName,a.StfCmpName as StfCmpName,b.StfCmpMoney as StfCmpMoney,b.StfQbmoney as StfQbmoney,a.StfRegistertime as StfRegistertime From TStafferInfo a,TCmpMoney b " + where + Sqlsort;
//Response.Write(SqlStr);
//Response.End();
DataSet ds = new DataSet();
try
...{
SqlConnection conn = new SqlConnection(connStr);
if (conn.State.ToString() == "Closed") conn.Open();
SqlDataAdapter da = new SqlDataAdapter(SqlStr, conn);
da.Fill(ds, "TStafferInfo");
if (conn.State.ToString() == "Open") conn.Close();
GridView1.DataSource = ds.Tables[0].DefaultView;
GridView1.DataBind();
LblCurrentIndex.Text = "第 " + (GridView1.PageIndex + 1).ToString() + " 页";
LblPageCount.Text = "共 " + GridView1.PageCount.ToString() + " 页";
LblRecordCount.Text = "总共 " + ds.Tables[0].Rows.Count.ToString() + " 条";
if (ds.Tables[0].Rows.Count == 0)
...{
btnFirst.Visible = false;
btnPrev.Visible = false;
btnNext.Visible = false;
btnLast.Visible = false;
LblCurrentIndex.Visible = false;
LblPageCount.Visible = false;
LblRecordCount.Visible = false;
}
else if (GridView1.PageCount == 1)
...{
btnFirst.Visible = false;
btnPrev.Visible = false;
btnNext.Visible = false;
btnLast.Visible = false;
}
// 计算生成分页页码,分别为:"首 页" "上一页" "下一页" "尾 页"
btnFirst.CommandName = "1";
btnPrev.CommandName = (GridView1.PageIndex == 0 ? "1" : GridView1.PageIndex.ToString());
btnNext.CommandName = (GridView1.PageCount == 1 ? GridView1.PageCount.ToString() : (GridView1.PageIndex + 2).ToString());
btnLast.CommandName = GridView1.PageCount.ToString();
//
this.ddlCurrentPage.Items.Clear();
for (int i = 1; i <= this.GridView1.PageCount; i++)
...{
this.ddlCurrentPage.Items.Add(i.ToString());
}
this.ddlCurrentPage.SelectedIndex = this.GridView1.PageIndex;
}
catch (Exception ex)
...{
Response.Write("数据库错误,错误原因:" + ex.Message);
Response.End();
}
}
protected void PagerButtonClick(object sender, EventArgs e)
...{
GridView1.PageIndex = Convert.ToInt32(((LinkButton)sender).CommandName) - 1;
GridViewBind("");
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
...{
e.Row.Attributes["onmouseover"] = "ItemOver(this)";
}
protected void Button1_Click(object sender, EventArgs e)
...{
Response.Write(Request.Form.Get("RadioName"));
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
...{
string sql = "";
if (ViewState["DataConnectionString"] == null || ViewState["DataConnectionString"].ToString().CompareTo("") == 0)
...{
ViewState["DataConnectionString"] = " desc";
}
else
ViewState["DataConnectionString"] = "";
sql = " order by " + e.SortExpression + ViewState["DataConnectionString"];
GridViewBind(sql);
//DataFormatString="{0:yyyy年MM月dd日 hh时mm分ss秒}"
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
...{
this.GridView1.PageIndex = this.ddlCurrentPage.SelectedIndex;
GridViewBind("");
}
private bool CheckAddClientInfoForm()
...{
int Tag = 0;
if (Tag == 1)
...{
Response.Write("<script>alert('请将带*项填写!')</script>");
return false;
}
if (Tag == 2)
...{
Response.Write("<script>alert('两次输入密码不同')</script>");
return false;
}
else
...{
return true;
}
}
public string GetClientVisitInfoShowAnchorStr(object StfId, object StfName)
...{
string AnchorStr = "<a href='#'><Div onclick='javascript:window.open("TManageModify.aspx?StfId=" + StfId + "&StfName=" + StfName + "","","height=280,Width=600,scrollbars=yes,resizable=yes,status=no")'>修改</Div></a>";
return AnchorStr;
}
public string GetClientVisitInfoShowCmpMoney(object StfId, object StfName)
...{
string AnchorStr = "<a href='#'><Div onclick='javascript:window.open("StfCmpMoneyInfo.aspx?StfId=" + StfId + "&StfName=" + StfName + "","","height=250,Width=500,scrollbars=yes,resizable=yes,status=no")'>充值</Div></a>";
return AnchorStr;
}
protected void Button3_Click(object sender, EventArgs e)
...{
string str = "";
string[] ckb = null;
str = Request.Form.Get("checkboxname");
ckb = str.Split(new char[] ...{ ',' });
for (int i = 0; i < ckb.Length; i++)
...{ //帐户和信息同时删除
string StrSql = " Delete TStafferInfo where StfId ='" + ckb[i] + "'";
String StrSql_d = " Delete TCmpMoneyInfo where StfId ='" + ckb[i] + "'";
SqlConnection Conn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings.Get("DataConnectionString"));
SqlCommand Cmd = new System.Data.SqlClient.SqlCommand(StrSql, Conn);
SqlCommand Cmd_d = new System.Data.SqlClient.SqlCommand(StrSql_d, Conn);
Conn.Open();
SqlTransaction Trans = Conn.BeginTransaction();
try
...{
Cmd.Transaction = Trans;
Cmd_d.Transaction = Trans;
Cmd.ExecuteNonQuery();
Cmd_d.ExecuteNonQuery();
Trans.Commit();
}
catch (Exception Err)
...{
Trans.Rollback();
Response.Write(Err.Message);
}
}
Response.Write("<script>window.close();alert('操作员删除成功!');</script>");
GridViewBind("");
}
protected void SelectClient_Click(object sender, EventArgs e)
...{
GridViewBind("");
}
}
posted @ 2008-01-19 15:25 小罗 阅读(214) 评论(0)
编辑
浏览器的会话使用存储在 SessionID 属性中的唯一标识符进行标识。会话 ID 使 ASP.NET 应用程序能够将特定的浏览器与 Web 服务器上相关的会话数据和信息相关联。会话 ID 的值在浏览器和 Web 服务器间通过 Cookie 进行传输,如果指定了无 Cookie 会话,则通过 URL 进行传输。
ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 Cookie 会话状态。例如,下面的 URL 已被 ASP.NET 修改,以包含唯一的会话 ID lit3py55t21z5v55vlm25s55:
http://www.example.com/s(lit3py55t21z5v55vlm25s55)/orderform.aspx
如果一个包含无 Cookie SessionID 的链接被多个浏览器共享时(可能通过搜索引擎或其他程序),此行为可能导致对会话数据的意外共享。可以通过禁用会话标识符的回收来降低多个客户端共享会话数据的可能性。为此,将 sessionState 配置元素的 regenerateExpiredSessionId 属性设置为 true。这样,在使用已过期的会话 ID 发起无 Cookie 会话请求时,将生成一个新的会话 ID。
——摘自 MSDN
.NET2.0中我们已可以通过重写SessionIDManager 类来改变SessionID 的生成机制和验证方法来防止会话数据的意外共享(即出现多个浏览器被识别为同一个会话,共用一个Session),可在.NET1.1中却没有相关的类让我们改变SessionID 的生成机制(封装死了),但受一篇文章的启发,我们可以在SessionID 生成之后对它进行处理。文章是老外写的,由于本人阅读能力有限,偶可没时间去看一大版唧唧歪歪的鹰文,直接下了代码来看。还好代码不算多,思路也很清晰,大概了解了他实现重写SessionID的原理,我改了下在无Cookie 会话中完美实现了。
相关代码
using System;
using System.Web;
using System.Web.SessionState;
using System.Web.Security;
using System.Configuration;
using System.Security.Cryptography;
using System.Runtime.Serialization;
using System.Globalization;
using System.Text;
public class SecureSessionModule : IHttpModule
{
private static string _ValidationKey = null;
public void Init (HttpApplication app)
{
if (_ValidationKey == null)
_ValidationKey = GetValidationKey ();
app.AcquireRequestState+=new EventHandler(app_AcquireRequestState);
}
void app_AcquireRequestState (Object sender, EventArgs e)
{
_ValidationKey=GetValidationKey();//每天生成一个KEY提高安全性
HttpContext current = ((HttpApplication) sender).Context;
//将处理后的SessionID存在Session["ASP.NET_SessionID"]中
string sessionid = GetSession (current, "ASP.NET_SessionID");
if (sessionid != null)
{
if (sessionid.Length <= 24)
RedirectUrl(current);
string id = sessionid.Substring (0, 24);
string mac1 = sessionid.Substring (24);
string mac2 = GetSessionIDMac (id, current.Request.UserHostAddress, current.Request.UserAgent, _ValidationKey);
// 用户客户端信息发生的变化,比对失败
if (String.CompareOrdinal(mac1, mac2) != 0)
{
RedirectUrl(current);
}
}
else
{
RedirectUrl(current);
}
}
private void RedirectUrl(HttpContext current)
{
//重定向页面以重新生成新的SessionID
current.Response.Redirect(current.Request.Url.ToString(),true);
}
private string GetValidationKey ()
{
string key = DateTime.Now.ToShortDateString();
return key;
}
private string GetSession (HttpContext current, string name)
{
object id = FindSession(current.Session,name);
if (id == null)
{
// 将用户客户端信息加密存储在Session中以便比对
id= current.Session.SessionID+GetSessionIDMac (current.Session.SessionID, current.Request.UserHostAddress,
current.Request.UserAgent, _ValidationKey);
current.Session[name] = id;
}
return id.ToString();
}
private object FindSession (HttpSessionState session, string name)
{
return session[name];
}
private string GetSessionIDMac (string id, string ip, string agent, string key)
{
StringBuilder builder = new StringBuilder (id, 512);
builder.Append (ip);
builder.Append (agent);
using (HMACSHA1 hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (key)))
{
return Convert.ToBase64String (hmac.ComputeHash (
Encoding.UTF8.GetBytes (builder.ToString ())));
}
}
public void Dispose () {}
}相关配置如下:
<configuration>
<system.web>
<httpModules>
<add name="SecureSession" type="SecureSessionModule,SecureSessionModule" />
</httpModules>
</system.web>
</configuration>
大家看了代码后就会知道,它实现的原理主要是因为不可能有相同IP电脑客户端同时访问一台服务器,当出现SessionID相同但他们客户端信息不同时就自动将后一个访问的客户端重定向以新建一个会话。
遗憾的是在WAP上应用时就有问题了,由于客户端信息没IP唯一标识(移动不给手机号信息了),所以如果相同型号的手机访问时就无法区分,不知哪位高人有没更好的解决办法,还望不吝赐教
posted @ 2008-01-19 15:20 小罗 阅读(195) 评论(0)
编辑
现在很多网站特别是资讯类的都把内容生成静态页(htm\html\shtml等),这类总结了一下两种生成静态页的方法并做了一个Demo文件供大家下载。
分别是通过模板(比较常用)和根据url生成(不到万部则以不用,因为这中方式只能获取html的部分):
Asp.net生成静态文件(根据时间自动命名保持,默认扩展名是htm可以自行修改)。
通过收入内容替换模板或者url地址两种方式进行静态文件的生成
templete.htm为模板文件,htm为生成后的静态文件保存位置
这类粘贴出.cs文件
1 //51aspx.com生成静态页演示文件,转载请保留该信息
2 public partial class _Default : System.Web.UI.Page
3 {
4 protected void Page_Load(object sender, EventArgs e)
5 {
6
7 }
8
9 //根据模板生成,保持在html文件夹中(部分源码搜集于网络)
10 protected void Button1_Click(object sender, EventArgs e)
11 {
12 //源码是替换掉模板中的特征字符
13
14 string mbPath =Server.MapPath("template.htm");
15 Encoding code = Encoding.GetEncoding("gb2312");
16 StreamReader sr = null;
17 StreamWriter sw = null;
18 string str = null;
19
20 //读取
21 try
22 {
23 sr = new StreamReader(mbPath, code);
24 str = sr.ReadToEnd();
25
26 }
27 catch (Exception ex)
28 {
29 throw ex;
30 }
31 finally
32 {
33 sr.Close();
34 }
35
36 //根据时间自动重命名,扩展名也可以自行修改
37 string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".htm";
38 str = str.Replace("$title$", txtTitle.Text);//替换Title
39 str = str.Replace("$content$", txtContent.Text);//替换content
40
41 //生成静态文件
42 try
43 {
44 sw = new StreamWriter(Server.MapPath("htm/") + fileName, false, code);
45 sw.Write(str);
46 sw.Flush();
47
48 }
49 catch (Exception ex)
50 {
51 throw ex;
52 }
53 finally
54 {
55 sw.Close();
56 Response.Write("恭喜<a href=htm/"+fileName+" target=_blank>"+fileName+"</a>已经生成,保存在htm文件夹下!");
57 }
58
59
60 }
61
62
63 //根据Url地址生成静态页保持
64 protected void Button2_Click(object sender, EventArgs e)
65 {
66 Encoding code = Encoding.GetEncoding("utf-8");
67 StreamReader sr = null;
68 StreamWriter sw = null;
69 string str = null;
70
71 //读取远程路径
72 WebRequest temp = WebRequest.Create(txtUrl.Text.Trim());
73 WebResponse myTemp = temp.GetResponse();
74 sr = new StreamReader(myTemp.GetResponseStream(), code);
75 //读取
76 try
77 {
78 sr = new StreamReader(myTemp.GetResponseStream(), code);
79 str = sr.ReadToEnd();
80
81 }
82 catch (Exception ex)
83 {
84 throw ex;
85 }
86 finally
87 {
88 sr.Close();
89 }
90 string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".htm";
91
92 //写入
93 try
94 {
95 sw = new StreamWriter(Server.MapPath("htm/") + fileName, false, code);
96 sw.Write(str);
97 sw.Flush();
98
99 }
100 catch (Exception ex)
101 {
102 throw ex;
103 }
104 finally
105 {
106 sw.Close();
107 Response.Write("恭喜<a href=htm/" + fileName + " target=_blank>" + fileName + "</a>已经生成,保存在htm文件夹下!");
108 }
109
110 }
111 }
posted @ 2008-01-19 15:19 小罗 阅读(72) 评论(0)
编辑
任何数据驱动型的应用程序都有一个普遍的需求,那就是报表。 但是,在ASP.NET 1.x中并没有给我们提供这个非常重要的特性。 然而很幸运的是,伴随着.NET 2.0而来的ReportViewer控件可以满足你对报表的一些基本需求。 我将会在本文中向你演示如何使用这个控件。 ReportViewer控件既可以在web程序中使用,也可以在windows程序中使用。 在这里,我将只介绍如何在web程序中使用它。
报表示例
我们假设要生成一个如下所示的顾客信息列表:
上面的报表是一个非常简单的以国家分组的顾客信息列表。 报表的数据是从Northwind数据库的Customers表里获取的。 默认情况下,它会显示所有的顾客信息。 但是,你也可以让它显示属于你指定的某个国家的顾客信息。
该报表是使用ReportViewer控件设计的,它可以从强类型的DataSet中或者自定义的对象集合中获取数据。 在实际的程序开发中,我们往往会使用3层架构,数据的获取经常会是从业务层取得的DataSet或一个泛型集合。 在这里,我打算使用一个泛型集合作为数据源,而不是强类型的DataSet。
创建类库
首先,打开Visual Studio,然后创建一个名为ReportViewerLib的类库项目。 添加一个如下所示的名为Customer的类:
using System;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Collections.Generic;
namespace ReportViewerLib
{
public class Customer
{
public string strCustomerID;
public string strCompanyName;
public string strContactName;
public string strCountry;
public string CustomerID
{
get
{
return strCustomerID;
}
set
{
strCustomerID = value;
}
}
public string CompanyName
{
get
{
return strCompanyName;
}
set
{
strCompanyName= value;
}
}
public string ContactName
{
get
{
return strContactName;
}
set
{
strContactName= value;
}
}
public string Country
{
get
{
return strCountry;
}
set
{
strCountry= value;
}
}
public static List GetCustomersForCountry(string country)
{
SqlConnection cnn=new SqlConnection(
ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
SqlCommand cmd=new SqlCommand();
cmd.Connection=cnn;
cmd.CommandText="select
CustomerID,CompanyName,ContactName,Country
from customers where country=@country";
SqlParameter p=new SqlParameter
("@country",country);
cmd.Parameters.Add(p);
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
List list = new List();
while (reader.Read())
{
Customer c = new Customer();
c.CustomerID = reader.GetString(0);
c.CompanyName = reader.GetString(1);
c.ContactName = reader.GetString(2);
c.Country = reader.GetString(3);
list.Add(c);
}
cnn.Close();
return list;
}
public static List GetAllCustomers()
{
SqlConnection cnn = new SqlConnection(
ConfigurationManager.ConnectionStrings
["NorthwindConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = "select
CustomerID,CompanyName,ContactName,Country from customers";
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
List list = new List();
while (reader.Read())
{
Customer c = new Customer();
c.CustomerID = reader.GetString(0);
c.CompanyName = reader.GetString(1);
c.ContactName = reader.GetString(2);
c.Country = reader.GetString(3);
list.Add(c);
}
cnn.Close();
return list;
}
}
}
|
Customer类定义了四个公共属性,即CustomerID、CompanyName、ContactName和Country。 在之后,是这个类包含的两个静态方法 – GetCustomersForContry()和GetAllCustomers()。 这两个方法都是比较简单的,一个是返回属于某一个国家的所有顾客信息,另一个是返回全部顾客信息。 首先打开Northwind数据库的连接,然后通过SqlCommand对象执行Select查询。 之后,用SqlDataReader对象来获取数据。 遍历这个SqlDataReader对象,在其内每次都创建一个Customer对象,然后设置它的各个属性,最后把其添加到Customer对象的泛型集合中。 在类的结尾处就是把这个Customer对象的泛型集合返回给调用者。
创建数据源
设计报表的时候,需要在你的项目中为其指定一个数据源。 在你的项目中添加一个数据源可以这样做,选择“数据”菜单 -> 添加新数据源。 然后将会出现如下图所示的对话框:
你的数据源可以是数据库、web service或者是一个对象。 本例中我们选择的是对象。 然后单击“下一步”按钮,会弹出让我们选择数据源的界面。 我们选择的是Customer类(如下图所示)。
单击“完成”按钮后就完成了数据源配置向导。 这样,你就在你的类库中添加了一个新的数据源。 如果要查看数据源的话可以这么做,选择“数据”菜单 -> 显示数据源,就会出现如下图所示的界面:
设计报表
接下来添加一个报表。 右键单击项目,选择“添加新项”。 在对话框里选择“报表”,并单击“添加”按钮(如下图所示)。 这样,我们就添加了一个名为“Report1.rdlc”的文件。 .rdlc文件是一个报表文件,它保存的是报表布局和数据映射。
一旦你打开了Report1.rdlc文件,Visual Studio的工具箱里就会显示出一套与报表相关的控件(如下所示)。
这些控件中,“文本框”控件和“表”控件是非常常用的。 “文本框”控件用于显示一段静态文本或者是一个表达式。 “表”控件用于显示表格数据,其生成的结果会显示在你的报表的“主体”中。
设计出的报表如下图所示:
在报表的“页眉”部分的头部,有一个文本框,其Value属性的值为“Customer Listing”。 在这个文本框的下面还有另一个文本框,其Value属性的值为“=Parameters!SubTitle.Value”。它的意思就是指明文本框的值来自名为SubTitle的参数。 我们如何来定义参数呢? 这需要在报表的ReportParameters属性中添加参数。 打开的报表参数对话框如下图所示:
请注意:参数的设置是在我们的.NET代码中完成的。
如果要在报表上显示日期的话,只要设置相关的文本框的Value属性为“=FormatDateTime(ToDay(),DateFormat.ShortDate)”即可。 报表的一大优势就是有很多的内置函数,如ToDay()和FormatDateTime之类的。 本例中,我们使用FormatDateTime()函数来以ShortDate的格式显示当前的日期(ToDay())。
现在,从工具箱里拖拽一个“表”控件到你的报表上。 默认情况下,“表”控件有3行3列,3行分别是:表头、详细信息和表尾。 当然,你也可以为“表”控件添加行和列。 从数据源窗口中拖拽CustomerID、CompanyName、ContactName和Country属性到你的“表”控件的详细信息行上。 这样,系统将会自动地添加文本框,并设置其属性为=Fields!CustomerID.Value、=Fields!CompanyName.Value之类的。 此时,列头也会被自动地添加。 当然,你也可以根据你的需求做你需要的修改。
接下来,我们要按顾客所属的国家对记录进行分组。 右键单击详细信息行的边框,选择插入组(如下图所示)。
然后将会出现如下图所示的对话框:
在“排序”选项卡中选择“=Fields!Country.Value”作为表达式,选择“Ascending”作为排序方向。
就是这些东西,很简单吧。 这样,我们就完成了报表的设计。
显示报表
新建一个名为“ReportViewerDemo”的web站点。 添加ReportViewerLib程序集的引用,这样该程序集就会拷贝到你的web站点的BIN目录下。 之后,把Report1.rdlc文件添加到你的web站点中。 在工具箱的“数据”选项卡中拖拽一个ReportViewer控件到你的Default.aspx页上, 打开ReportViewer控件的智能标记面板,在“选择报表”的下拉框中选择Report1.rdlc,如下图所示:
选择好报表文件后,系统会自动地添加一个TypeName属性为Customer的对象数据源控件。 你可以在对象数据源控件的配置向导中验证一下。
接下来,拖拽一个DropDownList控件到页的头部,并为其设置4个选项 – All、USA、UK和Brazil。 同时设置它的AutoPostBack属性为True。 然后,打开数据源控件的配置向导,设置“Select”操作为SelectCustomersForCountry()方法。
设置SelectCustomersForCountry()方法的country参数为DropDownList1的SelectedValue。
默认情况下,将在报表中显示所有顾客信息。 当你在DropDownList选择了一个国家的时候,报表中就会显示属于你所选择的国家的顾客信息。 要完成这样的功能,我们只需要处理DropDownList的SelectedIndexChanged事件。
protected void DropDownList1_SelectedIndexChanged
(object sender, EventArgs e)
{
if (DropDownList1.SelectedValue == "All")
{
ObjectDataSource1.SelectMethod = "GetAllCustomers";
ObjectDataSource1.SelectParameters.Clear();
ReportParameter param = new ReportParameter
("SubTitle", "List of all the customers");
ReportParameter[] p ={ param };
ReportViewer1.LocalReport.SetParameters(p);
}
else
{
ObjectDataSource1.SelectMethod = "GetCustomersForCountry";
ObjectDataSource1.SelectParameters[0].DefaultValue
= DropDownList1.SelectedValue;
ReportParameter param = new ReportParameter
("SubTitle", "List of customers for a country");
ReportParameter[] p ={ param };
ReportViewer1.LocalReport.SetParameters(p);
}
} |
这段代码首先检查DropDownList控件的SelectedValue属性。 如果是“All”的话就设置数据源控件的SelectMethod属性为GetAllCustomers。 另外,我们还需要清空SelectParameters集合,因为GetAllCustomers()方法不需要任何参数。 接下来,我们创建一个ReportParameter类的实例,并在其构造函数中设置报表的参数名和参数值。 回忆一下我们在设计报表时定义的参数。 然后再创建一个ReportParameter数组。 调用SetParameters()方法,并用这个数组作为其参数。 “else”代码块也是非常地简单,就是使用的方法变成了GetCustomersForCountry()而已。
就是这些东西,很简单吧。 报表已经搞定了。 你可以运行一下Default.aspx页看看效果。 注意,ReportViewer控件已经内置了导出特性,它允许你把报表导出为Excel或PDF格式。 ReportViewer控件还很多的属性,你可以自己摸索一下。
总结
ASP.NET的ReportViewer控件提供了很多报表的基本功能。 在本文中,我们使用了对象数据源控件来开发一个报表。 我们创建了一个类库和一个数据源。 最后使用ReportViewer控件来显示报表。
posted @ 2008-01-19 15:18 小罗 阅读(259) 评论(0)
编辑
using System.Data;
using System.Data.SqlClient;
public DataTable RetrieveRowsWithDataTable()
{
using ( SqlConnection conn = new SqlConnection(connectionString) )
{ conn.Open();
SqlCommand cmd = new SqlCommand("DATRetrieveProducts", conn);
cmd.CommandType = CommandType.StoredProcedure; SqlDataAdapter adapter = new SqlDataAdapter( cmd );
DataTable dataTable = new DataTable("Products");
adapter .Fill(dataTable); return dataTable;
}
}
使用 SqlAdapter 生成 DataSet 或 DataTable
1.创建一个 SqlCommand 对象以调用该存储过程,并将其与一个 SqlConnection 对象(显示)或连接字符串(不显示)相关联。
2.创建一个新的 SqlDataAdapter 对象并将其与 SqlCommand 对象相关联。
3.创建一个 DataTable(也可以创建一个 DataSet)对象。使用构造函数参数来命名 DataTable。
4.调用 SqlDataAdapter 对象的 Fill 方法,用检索到的行填充 DataSet 或 DataTable。
如何使用 SqlDataReader 来检索多个行
以下代码片段阐明了可检索多个行的 SqlDataReader方法。
using System.IO;
using System.Data;
using System.Data.SqlClient;
public SqlDataReader RetrieveRowsWithDataReader()
{ SqlConnection conn = new SqlConnection( "server=(local);
Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("DATRetrieveProducts", conn );
cmd.CommandType = CommandType.StoredProcedure;
try
{
conn.Open();
// Generate the reader. CommandBehavior.CloseConnection causes the // the connection to be closed when the reader object is closed
return( cmd.ExecuteReader( CommandBehavior.CloseConnection ) );
}
catch
{
conn.Close();
throw;
}
} // Display the product list using the console
private void DisplayProducts()
{
SqlDataReader reader = RetrieveRowsWithDataReader();
try
{
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}", reader.GetInt32(0).ToString(), reader.GetString(1) );
}
}
finally
{
reader.Close(); // Also closes the connection due to the // CommandBehavior enum used when generating the reader
}
}
使用 SqlDataReader 检索行
1.创建一个用来执行存储过程的 SqlCommand 对象,并将其与一个 SqlConnection对象相关联。
2.打开连接。
3.通过调用 SqlCommand 对象的 ExecuteReader方法创建一个 SqlDataReader对象。
4.要从流中读取数据,请调用 SqlDataReader对象的 Read方法来检索行,并使用类型化访问器方法(如 GetInt32和 GetString方法)来检索列值。
5.使用完读取器后,请调用其 Close方法。
如何使用 XmlReader 检索多个行
可以使用 SqlCommand对象来生成 XmlReader对象,后者可提供对 XML 数据的基于流的只进访问。命令(通常为存储过程)必须产生基于 XML 的结果集,对于 SQL Server 2000 而言,该结果集通常包含一个带有有效 FOR XML子句的 Select语句。以下代码片段阐明了该方法:
public void RetrieveAndDisplayRowsWithXmlReader()
{
using( SqlConnection conn = new SqlConnection(connectionString) )
{;
SqlCommand cmd = new SqlCommand("DATRetrieveProductsXML", conn );
cmd.CommandType = CommandType.StoredProcedure;
try
{
conn.Open();
XmlTextReader xreader = (XmlTextReader)cmd.ExecuteXmlReader();
while ( xreader.Read() )
{
if ( xreader.Name == "PRODUCTS" )
{
string strOutput = xreader.GetAttribute("ProductID");
strOutput += " "; strOutput += xreader.GetAttribute("ProductName");
Console.WriteLine( strOutput );
}
}
xreader.Close();
// XmlTextReader does not support IDisposable so it can't be // used within a using keyword } }
上述代码使用了以下存储过程:
Create PROCEDURE DATRetrieveProductsXML AS Select * FROM PRODUCTS FOR XML AUTO GO
使用 XmlReader 检索 XML 数据
1.创建一个 SqlCommand 对象来调用可生成 XML 结果集的存储过程(例如,在 Select语句中使用 FOR XML子句)。将该 SqlCommand对象与某个连接相关联。
2.调用 SqlCommand 对象的 ExecuteXmlReader方法,并且将结果分配给只进 XmlTextReader对象。当您不需要对返回的数据进行任何基于 XML 的验证时,这是应该使用的最快类型的 XmlReader对象。
3.使用 XmlTextReader 对象的 Read方法来读取数据。
如何使用存储过程输出参数来检索单个行
借助于命名的输出参数,可以调用在单个行内返回检索到的数据项的存储过程。以下代码片段使用存储过程来检索 Northwind 数据库的 Products 表中包含的特定产品的产品名称和单价。
void GetProductDetails( int ProductID, out string ProductName, out decimal UnitPrice )
{
using( SqlConnection conn = new SqlConnection( "server=(local);Integrated Security=SSPI;database=Northwind") )
{ // Set up the command object used to execute the stored proc
SqlCommand cmd = new SqlCommand( "DATGetProductDetailsSPOutput", conn )
cmd.CommandType = CommandType.StoredProcedure;
// Establish stored proc parameters.
// @ProductID int INPUT
// @ProductName nvarchar(40) OUTPUT
// @UnitPrice money OUTPUT
// Must explicitly set the direction of output parameters
SqlParameter paramProdID = cmd.Parameters.Add( "@ProductID", ProductID );
paramProdID.Direction = ParameterDirection.Input; SqlParameter paramProdName = cmd.Parameters.Add( "@ProductName", SqlDbType.VarChar, 40 );
paramProdName.Direction = ParameterDirection.Output; SqlParameter paramUnitPrice = cmd.Parameters.Add( "@UnitPrice", SqlDbType.Money );
paramUnitPrice.Direction = ParameterDirection.Output; conn.Open();
// Use ExecuteNonQuery to run the command.
// Although no rows are returned any mapped output parameters
// (and potentially return values) are populated cmd.ExecuteNonQuery( );
// Return output parameters from stored proc ProductName = paramProdName.Value.ToString();
UnitPrice = (decimal)paramUnitPrice.Value;
}
}
使用存储过程输出参数来检索单个行
1.创建一个 SqlCommand 对象并将其与一个 SqlConnection对象相关联。
2.通过调用 SqlCommand 的 Parameters集合的 Add方法来设置存储过程参数。默认情况下,参数都被假设为输入参数,因此必须显式设置任何输出参数的方向。
注一种良好的习惯做法是显式设置所有参数(包括输入参数)的方向。
3.打开连接。
4.调用 SqlCommand 对象的 ExecuteNonQuery方法。这将填充输出参数(并可能填充返回值)。
5.通过使用 Value 属性,从适当的 SqlParameter对象中检索输出参数。
6.关闭连接。
上述代码片段调用了以下存储过程。
Create PROCEDURE DATGetProductDetailsSPOutput
@ProductID int,
@ProductName nvarchar(40) OUTPUT,
@UnitPrice money OUTPUT AS Select @ProductName = ProductName,
@UnitPrice = UnitPrice FROM Products Where ProductID = @ProductID GO
如何使用 SqlDataReader 来检索单个行
可以使用 SqlDataReader对象来检索单个行,尤其是可以从返回的数据流中检索需要的列值。以下代码片段对此进行了说明。
void GetProductDetailsUsingReader( int ProductID, out string ProductName, out decimal UnitPrice )
{ using( SqlConnection conn = new SqlConnection( "server=(local);
Integrated Security=SSPI;database=Northwind") ) {
// Set up the command object used to execute the stored proc SqlCommand cmd = new SqlCommand( "DATGetProductDetailsReader", conn );
cmd.CommandType = CommandType.StoredProcedure;
// Establish stored proc parameters.
// @ProductID int INPUT SqlParameter paramProdID = cmd.Parameters.Add( "@ProductID", ProductID );
paramProdID.Direction = ParameterDirection.Input;
conn.Open();
using( SqlDataReader reader = cmd.ExecuteReader() ) { if( reader.Read() )
// Advance to the one and only row {
// Return output parameters from returned data stream ProductName = reader.GetString(0);
UnitPrice = reader.GetDecimal(1);
} } } }
使用 SqlDataReader 对象来返回单个行
1.建立 SqlCommand 对象。
2.打开连接。
3.调用 SqlDataReader 对象的 ExecuteReader方法。
4.通过 SqlDataReader 对象的类型化访问器方法(在这里,为 GetString和 GetDecimal)来检索输出参数。
上述代码片段调用了以下存储过程。
Create PROCEDURE DATGetProductDetailsReader
@ProductID int AS Select ProductName, UnitPrice FROM Products Where ProductID =
@ProductID GO
如何使用 ExecuteScalar 来检索单个项
ExecuteScalar方法专门适用于仅返回单个值的查询。如果查询返回多个列和/或行,ExecuteScalar将只返回第一行的第一列。
以下代码说明了如何查找与特定产品 ID 相对应的产品名称:
void GetProductNameExecuteScalar( int ProductID, out string ProductName )
{ using( SqlConnection conn = new SqlConnection( "server=(local);Integrated Security=SSPI;database=northwind") )
{ SqlCommand cmd = new SqlCommand("LookupProductNameScalar", conn );
cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@ProductID", ProductID );
conn.Open();
ProductName = (string)cmd.ExecuteScalar();
} }
使用 ExecuteScalar 来检索单个项
1.建立一个 SqlCommand 对象来调用存储过程。
2.打开连接。
3.调用 ExecuteScalar 方法。注意,该方法返回一个对象类型。它包含检索到的第一列的值,并且必须转化为适当的类型。
4.关闭连接。
上述代码使用了以下存储过程:
Create PROCEDURE LookupProductNameScalar
@ProductID int AS Select TOP 1 ProductName FROM Products Where ProductID =
@ProductID GO
如何使用存储过程输出或返回参数来检索单个项
可以使用存储过程输出或返回参数来查找单个值。以下代码阐明了输出参数的用法:
void GetProductNameUsingSPOutput( int ProductID, out string ProductName )
{ using( SqlConnection conn = new SqlConnection( "server=(local);Integrated Security=SSPI;database=northwind") )
{ SqlCommand cmd = new SqlCommand("LookupProductNameSPOutput", conn );
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paramProdID = cmd.Parameters.Add("@ProductID", ProductID );
ParamProdID.Direction = ParameterDirection.Input;
SqlParameter paramPN = cmd.Parameters.Add("@ProductName", SqlDbType.VarChar, 40 );
paramPN.Direction = ParameterDirection.Output; conn.Open();
cmd.ExecuteNonQuery();
ProductName = paramPN.Value.ToString();
} }
使用存储过程输出参数来检索单个值
1.建立一个 SqlCommand 对象来调用存储过程。
2.通过将 SqlParameters 添加到 SqlCommand的 Parameters集合中,设置任何输入参数和单个输出参数。
3.打开连接。
4.调用 SqlCommand 对象的 ExecuteNonQuery方法。
5.关闭连接。
6.通过使用输出 SqlParameter 的 Value属性来检索输出值。
上述代码使用了以下存储过程。
@ProductID int,
@ProductName nvarchar(40) OUTPUT AS Select
@ProductName = ProductName FROM Products Where ProductID = @ProductID GO
以下代码阐明了如何使用返回值来指明是否存在特定行。从编码角度来看,这类似于使用存储过程输出参数,不同之处在于必须将 SqlParameter方向显式设置为 ParameterDirection.ReturnValue。
bool CheckProduct( int ProductID )
{ using( SqlConnection conn = new SqlConnection( "server=(local);
Integrated Security=SSPI;database=northwind") )
{ SqlCommand cmd = new SqlCommand("CheckProductSP", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
SqlParameter paramRet = cmd.Parameters.Add("@ProductExists", SqlDbType.Int );
paramRet.Direction = ParameterDirection.ReturnValue; conn.Open(); cmd.ExecuteNonQuery(); }
return (int)paramRet.Value == 1; }
通过使用存储过程返回值来检查是否存在特定行
1.建立一个 SqlCommand 对象来调用存储过程。
2.设置一个输入参数,该参数含有要访问的行的主键值。
3.设置单个返回值参数。将一个 SqlParameter 对象添加到 SqlCommand的 Parameters集合中,并将其方向设置为 ParameterDirection.ReturnValue。
4.打开连接。
5.调用 SqlCommand 对象的 ExecuteNonQuery方法。
6.关闭连接。
7.通过使用返回值 SqlParameter 的 Value属性来检索返回值。
上述代码使用了以下存储过程。
Create PROCEDURE CheckProductSP
@ProductID int AS IF EXISTS( Select ProductID FROM Products Where ProductID =
@ProductID )
return 1 ELSE return 0 GO
如何使用 SqlDataReader 来检索单个项
可以使用 SqlDataReader对象并通过调用命令对象的 ExecuteReader方法来获取单个输出值。这要求编写稍微多一点的代码,因为必须调用 SqlDataReader Read 方法,然后通过该读取器的访问器方法之一来检索需要的值。以下代码阐明了 SqlDataReader对象的用法。
bool CheckProductWithReader( int ProductID )
{ using( SqlConnection conn = new SqlConnection( "server=(local);
Integrated Security=SSPI;database=northwind") )
{ SqlCommand cmd = new SqlCommand("CheckProductExistsWithCount", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
cmd.Parameters["@ProductID"].Direction = ParameterDirection.Input; conn.Open();
using( SqlDataReader reader = cmd.ExecuteReader( CommandBehavior.SingleResult ) )
{ if( reader.Read() ) { return (reader.GetInt32(0) >0); } return false; } }
上述代码采用了以下存储过程。
Create PROCEDURE CheckProductExistsWithCount @ProductID int AS Select COUNT(*) FROM Products Where ProductID = @ProductID GO
如何编写 ADO.NET 手动事务处理代码
以下代码显示了如何充分利用 SQL Server .NET 数据提供程序所提供的事务处理支持,通过事务来保护资金转帐操作。该操作在同一数据库中的两个帐户之间转移资金。
public void TransferMoney( string toAccount, string fromAccount, decimal amount ) {
using ( SqlConnection conn = new SqlConnection( "server=(local);Integrated Security=SSPI;database=SimpleBank" ) )
{ SqlCommand cmdCredit = new SqlCommand("Credit", conn );
cmdCredit.CommandType = CommandType.StoredProcedure;
cmdCredit.Parameters.Add( new SqlParameter("@AccountNo", toAccount) );
cmdCredit.Parameters.Add( new SqlParameter("@Amount", amount ));
SqlCommand cmdDebit = new SqlCommand("Debit", conn );
cmdDebit.CommandType = CommandType.StoredProcedure; cmdDebit.Parameters.Add( new SqlParameter("@AccountNo", fromAccount) );
cmdDebit.Parameters.Add( new SqlParameter("@Amount", amount ));
conn.Open();
// Start a new transaction using ( SqlTransaction trans = conn.BeginTransaction() ) {
// Associate the two command objects with the same transaction cmdCredit.Transaction = trans;
cmdDebit.Transaction = trans;
try { cmdCredit.ExecuteNonQuery();
cmdDebit.ExecuteNonQuery(); // Both commands (credit and debit) were successful trans.Commit(); }
catch( Exception ex ) {
// transaction failed trans.Rollback();
// log exception details . . .
throw ex; } } } }
如何使用 Transact-SQL 执行事务处理
以下存储过程阐明了如何在 Transact-SQL 存储过程内部执行事务性资金转帐操作。
Create PROCEDURE MoneyTransfer
@FromAccount char(20),
@ToAccount char(20),
@Amount money AS BEGIN TRANSACTION -- PERFORM DEBIT OPERATION Update Accounts SET Balance = Balance -
@Amount Where AccountNumber = @FromAccount IF RowCount = 0 BEGIN RAISERROR('Invalid From Account Number', 11, 1)
GOTO ABORT END DECLARE
@Balance money Select @Balance = Balance FROM ACCOUNTS
Where AccountNumber = @FromAccount IF @BALANCE
0 BEGIN RAISERROR('Insufficient funds', 11, 1)
GOTO ABORT END -- PERFORM CREDIT OPERATION Update Accounts SET Balance = Balance + @Amount Where AccountNumber = @ToAccount
IF RowCount = 0 BEGIN RAISERROR('Invalid To Account Number', 11, 1) GOTO ABORT END COMMIT TRANSACTION RETURN 0 ABORT: ROLLBACK TRANSACTION GO
该存储过程使用 BEGIN TRANSACTION、COMMIT TRANSACTION 和 ROLLBACK TRANSACTION 语句来手动控制该事务。
如何编写事务性 .NET 类
以下示例代码显示了三个服务性 .NET 托管类,这些类经过配置以执行自动事务处理。每个类都使用 Transaction属性进行了批注,该属性的值确定是否应该启动新的事务流,或者该对象是否应该共享其直接调用方的事务流。这些组件协同工作来执行银行资金转帐任务。Transfer类被使用 RequiresNew事务属性进行了配置,而 Debit和 Credit被使用 Required进行了配置。结果,所有这三个对象在运行时都将共享同一事务。
using System;
using System.EnterpriseServices;
[Transaction(TransactionOption.RequiresNew)]
public class Transfer : ServicedComponent { [AutoComplete]
public void Transfer( string toAccount, string fromAccount, decimal amount ) {
try { // Perform the debit operation Debit debit = new Debit();
debit.DebitAccount( fromAccount, amount );
// Perform the credit operation Credit credit = new Credit();
credit.CreditAccount( toAccount, amount ); }
catch( SqlException sqlex ) {
// Handle and log exception details
// Wrap and propagate the exception throw new TransferException( "Transfer Failure", sqlex ); } } }
[Transaction(TransactionOption.Required)]
public class Credit : ServicedComponent { [AutoComplete]
public void CreditAccount( string account, decimal amount ) { try {
using( SqlConnection conn = new SqlConnection( "Server=(local); Integrated Security=SSPI";
database="SimpleBank") ) {
SqlCommand cmd = new SqlCommand("Credit", conn );
cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add( new SqlParameter("@AccountNo", account) );
cmd.Parameters.Add( new SqlParameter("@Amount", amount ));
conn.Open();
cmd.ExecuteNonQuery(); } } }
catch( SqlException sqlex ){
// Log exception details here throw;
// Propagate exception } } [Transaction(TransactionOption.Required)]
public class Debit : ServicedComponent { public void DebitAccount( string account, decimal amount ) {
try { using( SqlConnection conn = new SqlConnection( "Server=(local);
Integrated Security=SSPI";
database="SimpleBank") ) { SqlCommand cmd = new SqlCommand("Debit", conn );
cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add( new SqlParameter("@AccountNo", account) );
cmd.Parameters.Add( new SqlParameter("@Amount", amount )); conn.Open(); cmd.ExecuteNonQuery(); } }
catch (SqlException sqlex) {
// Log exception details here throw;
// Propagate exception back to caller } } }
posted @ 2008-01-19 14:58 小罗 阅读(54) 评论(0)
编辑
using System;
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
using
Excel;
using Word;
using System.IO;
namespace Common
{
/// <summary>
/// 把数据导入到.doc、.txt、.xls文件中
/// </summary>
public class Export
{
private const string DATAWORDPATH = @"C:\folder\doc\datadoc\";
private const string IMAGEWORDPATH = @"C:\folder\doc\imagedoc\";
private const string IMAGEPATH = @"C:\folder\image\";
private const string EXCELPATH = @"C:\folder\excel\";
private const string TXTPATH = @"C:\folder\txt\";
private const string IMAGEPOSTFIX = ".bmp";
private const string WORDPOSTFIX = ".doc";
private const string EXCELPOSTFIX = ".xls";
private const string TXTPOSTFIX = ".txt";
private const int DATADISTANCE = 5;
private const int TABDISTANCE = 8;
public Export()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 获得数据集Dataset--------------------------------用于调试
/// </summary>
/// <returns>Dataset</returns>
public DataSet GetData()
{
try
{
string sConnectionString;
sConnectionString = "workstation id=GUOFU;packet size=4096;user id=sa;data source=GUOFU;persist security info=True;initial catalog=YC;password=sc";
SqlConnection objConn = new SqlConnection(sConnectionString);
objConn.Open();
SqlDataAdapter daPoint = new SqlDataAdapter("Select * From Point", objConn);
DataSet dsYC = new DataSet("YC");
daPoint.FillSchema(dsYC,SchemaType.Mapped, "Point");
daPoint.Fill(dsYC,"Point");
daPoint = new SqlDataAdapter("Select * From Employee", objConn);
daPoint.FillSchema(dsYC,SchemaType.Mapped, "Employee");
daPoint.Fill(dsYC,"Employee");
return dsYC;
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 把数据文件导入到.xls文件
/// </summary>
/// <param name="ds"></param>
public void ExportToExcel(DataSet ds)
{
if(ds.Tables.Count!=0)
{
//生成.xls文件完整路径名
string tempFileName = GetTempFileName();
object filename = EXCELPATH+tempFileName+EXCELPOSTFIX;
object Nothing = System.Reflection.Missing.Value;
//创建excel文件,文件名用系统时间生成精确到毫秒
Excel.Application myExcel = new Excel.ApplicationClass();
myExcel.Application.Workbooks.Add(Nothing);
try
{
//把Dataset中的数据插入excel文件中
int totalCount = 0;
for(int k =0;k<ds.Tables.Count;k++)
{
int row = ds.Tables[k].Rows.Count;
int column = ds.Tables[k].Columns.Count;
for(int i = 0;i<column;i++)
{
myExcel.Cells[totalCount+2,1+i] = ds.Tables[k].Columns[i].ColumnName;
}
for(int i = 0;i<row;i++)
{
for(int j =0;j<column;j++)
{
myExcel.Cells[totalCount+3+i,1+j] = "'" + ds.Tables[k].Rows[i][j].ToString();
}
}
totalCount = totalCount + row +4;
}
try
{
//保存excel文件到指定的目录下,文件名用系统时间生成精确到毫秒
myExcel.ActiveWorkbook._SaveAs(filename,Nothing,Nothing,Nothing,Nothing,Nothing,XlSaveAsAccessMode.xlExclusive,Nothing,Nothing,Nothing,Nothing);
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+EXCELPATH+tempFileName+EXCELPOSTFIX);
return;
}
//让生成的excel文件可见
myExcel.Visible = true;
}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show("向excel文件中写入数据出错: " + e.Message);
}
}
else
{
System.Windows.Forms.MessageBox.Show("No Data");
}
}
/// <summary>
/// 把数据导入到.doc文件
/// </summary>
/// <param name="ds"></param>
public void ExportToWord(DataSet ds)
{
if(ds.Tables.Count!=0)
{
string tempFileName = null;
object filename = null;
object tableBehavior = Word.WdDefaultTableBehavior.wdWord9TableBehavior;
object autoFitBehavior = Word.WdAutoFitBehavior.wdAutoFitFixed;
object unit = Word.WdUnits.wdStory;
object extend = System.Reflection.Missing.Value;
object breakType = (int)Word.WdBreakType.wdSectionBreakNextPage;
object count = 1;
object character = Word.WdUnits.wdCharacter;
object Nothing = System.Reflection.Missing.Value;
try
{
tempFileName = GetTempFileName();
//生成.doc文件完整路径名
filename = DATAWORDPATH+tempFileName+WORDPOSTFIX;
//创建一个word文件,文件名用系统时间生成精确到毫秒
Word.Application myWord= new Word.ApplicationClass();
Word._Document myDoc = new Word.DocumentClass();
myDoc = myWord.Documents.Add(ref Nothing,ref Nothing,ref Nothing,ref Nothing);
myDoc.Activate();
//向把dataset中的表插入到word的文件中
for(int totalTable = 0;totalTable<ds.Tables.Count;totalTable++)
{
myWord.Application.Selection.TypeText(ds.Tables[totalTable].TableName+"表的数据如下");
myWord.Application.Selection.TypeParagraph();
myWord.Application.Selection.TypeParagraph();
Word.Range para = myWord.Application.Selection.Range;
myDoc.Tables.Add(para,ds.Tables[totalTable].Rows.Count+1,ds.Tables[totalTable].Columns.Count,ref tableBehavior,ref autoFitBehavior);
for(int column = 0; column<ds.Tables[totalTable].Columns.Count;column++)
{
myDoc.Tables.Item(totalTable+1).Cell(1,column+1).Range.InsertBefore(ds.Tables[0].Columns[column].ColumnName.Trim());
}
for(int row = 0;row<ds.Tables[totalTable].Rows.Count;row++)
{
for(int column = 0;column<ds.Tables[totalTable].Columns.Count;column++)
{
myDoc.Tables.Item(totalTable+1).Cell(row+2,column+1).Range.InsertBefore(ds.Tables[totalTable].Rows[row][column].ToString().Trim());
}
}
myWord.Application.Selection.EndKey(ref unit,ref extend);
myWord.Application.Selection.TypeParagraph();
myWord.Application.Selection.TypeParagraph();
myWord.Application.Selection.InsertBreak(ref breakType);
}
myWord.Application.Selection.TypeBackspace();
myWord.Application.Selection.Delete(ref character,ref count);
myWord.Application.Selection.HomeKey(ref unit,ref extend);
//保存word文件到指定的目录下
try
{
myDoc.SaveAs(ref filename,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
myWord.Visible = true;
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+DATAWORDPATH+tempFileName+WORDPOSTFIX);
return;
}
//让生成的excel文件可见
myWord.Visible = true;
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show("向word文件中写入数据出错: " + ex.Message);
}
}
else
{
System.Windows.Forms.MessageBox.Show("No Data");
}
}
/// <summary>
/// 把图片文件导入到.doc文件
/// </summary>
/// <param name="bp"></param>
public void ExportToWord(Bitmap bp)
{
string tempFileName = null;
string bmpPath = null;
object filename = null;
object Nothing = null;
tempFileName = GetTempFileName();
//生成.bmp文件完整路径名
bmpPath = IMAGEPATH+tempFileName+IMAGEPOSTFIX;
//生成.doc文件完整路径名
filename = IMAGEWORDPATH+tempFileName+WORDPOSTFIX;
Nothing = System.Reflection.Missing.Value;
//创建一个word文件,文件名用系统时间生成精确到毫秒
Word.Application myWord= new Word.ApplicationClass();
Word._Document myDoc = new Word.DocumentClass();
myDoc = myWord.Documents.Add(ref Nothing,ref Nothing,ref Nothing,ref Nothing);
try
{
//把bitmap对象保存到系统所生成文件完整路径中
bp.Save(bmpPath);
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+bmpPath);
return;
}
try
{
//往word文件中插入图片
myDoc.InlineShapes.AddPicture(bmpPath,ref Nothing,ref Nothing,ref Nothing);
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+bmpPath);
return;
}
try
{
//保存word文件到指定的目录下
myDoc.SaveAs(ref filename,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+IMAGEWORDPATH+tempFileName+WORDPOSTFIX);
return;
}
//让生成的word文件可见
myWord.Visible = true;
}
/// <summary>
/// 把数据文件导入到.txt文件
/// </summary>
/// <param name="ds"></param>
public void ExportToTxt(DataSet ds)
{
if(ds.Tables.Count!=0)
{
string tempFileName = null;
tempFileName = GetTempFileName();
//创建一个.txt文件,文件名用系统时间生成精确到毫秒
FileInfo file = new FileInfo(TXTPATH+tempFileName+TXTPOSTFIX);
StreamWriter textFile = null;
try
{
textFile = file.CreateText();
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+TXTPATH+tempFileName+TXTPOSTFIX);
return;
}
//把Dataset中的数据写入.txt文件中
for(int totaltable = 0;totaltable<ds.Tables.Count;totaltable++)
{
//统计dataset中当前表的行数
int row = ds.Tables[totaltable].Rows.Count;
//统计dataset中当前表的列数
int column = ds.Tables[totaltable].Columns.Count;
//用于统计当前表中每列记录中字符数最长的字符串的长度之和
int totalLength = 0;
//用于统计标题的长度(dataset中的表名的length+"表的数据如下"的length)
int titleLength = 0;
//统计每列记录中字符数最长的字符串的长度
int[] columnLength = new int[column];
for(int i = 0;i<column;i++)
{
columnLength[i] = ds.Tables[totaltable].Columns[i].ColumnName.ToString().Length;
}
for(int i = 0;i<row;i++)
{
for(int j = 0;j<column;j++)
{
if(ds.Tables[totaltable].Rows[i][j].ToString().Length>columnLength[j])
{
columnLength[j]=ds.Tables[totaltable].Rows[i][j].ToString().Length;
}
}
}
//统计当前表中每列记录中字符数最长的字符串的长度之和
for(int i = 0;i<column;i++)
{
totalLength = totalLength+columnLength[i]+DATADISTANCE;
}
totalLength = totalLength+2*TABDISTANCE-DATADISTANCE;
//统计标题的长度(dataset中的当前表名的length+"表的数据如下"的length)
titleLength = ds.Tables[totaltable].TableName.ToString().Length+"表的数据如下".Length*2;
//把标题写入.txt文件中
for(int i = 0;i<(int)((totalLength-titleLength)/2);i++)
{
textFile.Write(' ');
}
textFile.Write(ds.Tables[totaltable].TableName+"表的数据如下");
textFile.WriteLine();
for(int i = 0;i<totalLength;i++)
{
textFile.Write('*');
}
textFile.WriteLine();
textFile.Write("\t");
//把dataset中当前表的字段名写入.txt文件中
for(int i = 0;i<column;i++)
{
textFile.Write(ds.Tables[totaltable].Columns[i].ColumnName.ToString());
for(int k = 0;k<columnLength[i]-ds.Tables[totaltable].Columns[i].ColumnName.ToString().Length+DATADISTANCE;k++)
{
textFile.Write(' ');
}
}
textFile.WriteLine();
for(int i = 0;i<totalLength;i++)
{
textFile.Write('-');
}
textFile.WriteLine();
textFile.Write("\t");
//把dataset中当前表的数据写入.txt文件中
for(int i = 0;i<row;i++)
{
for(int j = 0;j<column;j++)
{
textFile.Write(ds.Tables[totaltable].Rows[i][j].ToString());
for(int k = 0;k<columnLength[j]-ds.Tables[totaltable].Rows[i][j].ToString().Length+DATADISTANCE;k++)
{
textFile.Write(' ');
}
}
textFile.WriteLine();
textFile.Write("\t");
}
textFile.WriteLine();
for(int i = 0;i<totalLength;i++)
{
textFile.Write('-');
}
textFile.WriteLine();
textFile.WriteLine();
textFile.WriteLine();
}
//关闭当前的StreamWriter流
textFile.Close();
System.Windows.Forms.MessageBox.Show("数据文件已保存到"+" "+file.FullName);
}
else
{
System.Windows.Forms.MessageBox.Show("No Data");
}
}
public string GetTempFileName()
{
return DateTime.Now.ToString("yyyyMMddhhmmssfff");
}
}
}
补充:使用以上方法必须对dcom进行配置,给用户使用office的权限。
具体配置方法如下:
1:在服务器上安装office的Excel软件.
2:在"开始"->"运行"中输入dcomcnfg.exe启动"组件服务"
3:依次双击"组件服务"->"计算机"->"我的电脑"->"DCOM配置"
4:在"DCOM配置"中找到"Microsoft Excel 应用程序",在它上面点击右键,然后点击"属性",弹出"Microsoft Excel 应用程序属性"对话框
5:点击"标识"标签,选择"交互式用户"
6:点击"安全"标签,在"启动和激活权限"上点击"自定义",然后点击对应的"编辑"按钮,在弹出的"安全性"对话框中填加一个"NETWORK SERVICE"用户(注意要选择本计算机名),并给它赋予"本地启动"和"本地激活"权限.
7:依然是"安全"标签,在"访问权限"上点击"自定义",然后点击"编辑",在弹出的"安全性"对话框中也填加一个"NETWORK SERVICE"用户,然后赋予"本地访问"权限.
这样,我们便配置好了相应的Excel的DCOM权限.
注意:我是在WIN2003上配置的,在2000上,是配置ASPNET用户
若不进行配置会出现错误
检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005。
原因是用户没有使用Excel的权限。
导出到word同样要配置使用word的权限。
继续补充: 导出到txt我用了上面的方法有问题,
try
{
textFile = file.CreateText();
}
catch
{
System.Windows.Forms.MessageBox.Show("系统找不到指定目录下的文件: "+TXTPATH+tempFileName+TXTPOSTFIX);
return;
}
总是在这里跳到catch里面。导出到word,excel都能用,继续研究txt的使用方法。
posted @ 2008-01-19 14:37 小罗 阅读(340) 评论(0)
编辑
目前的ASP.NET提供的解决方案是在Global.cs中加上FormsAuthentication_OnAuthenticated方法来捕捉已通过验证事件。该方法的缺陷是:
1.只能捕捉Forms身份验证方式,而不能捕捉Windows和Passport认证方式;
2.只能捕捉已通过身份验证事件而不能捕捉身份注销事件;
3.必须修改global.cs文件。
以上任何一个缺陷都是我无法接受的。当时在ASP.NET1.1解决那个问题时用了五六个接口,十多个类,并且有一个输出类要求应用程序登入和注销时访问相应的方法,而不是自由地使用FormsAuthentication的相关方法。现如今该问题总算比较满意地解决了。思路是这样的:
在一个HttpModule中建立两张会话表,一张记录已通过身份验证的会话;另一张记录未通过身份验证的会话,这样,在HttpApplication.AcquireRequestState事件中查找每个会话在这两张表中的状态:
状态一 两张表中都没有 这是一个新的会话
状态二 在已通过身份验证的会话表中 已通过身份验证
状态三 在未通过身份验证的会话表中 未通过身份验证
如果是状态一,则立即调用所有SSO提供器的身份查验方法,只要有任何一个SSO提供器证实已经通过了身份验证,则立即将状态调整到状态二,并通知所有订阅身份状态变化的Handler。如果是状态二或状态三,则立即与会话的实际身份状态进行比对。会话实际的身份状态可以通过查询HttpContext.User来获得。如果二者不同,则根据情况调整表中所记录的状态,并向订阅身份变化的Handler发出相应的通知。
有一个问题是:会话列表的查询频度非常高,每次Request都不可避免查询一次。所以这里对算法的选择要求较高。我在实际的项目中选择了字符串数组的BinarySearch算法。这样每次添加或删除新的会话时不可避免对字符串在数组中的位置进行调整,以保持排序状态。当然,在比对过程中也需要根据命中率调整比对顺序,例如三种状态中,显然状态二的比例最高(当然数组往往也最庞大),应该优先选择。
最后的解决方案是:只用了三个接口,一个HttpModule和几个内部类就实现了,完全不必修改global.cs,且没有任何输出类供登录认证模块调用,所有的SSO提供器也只需要通过web.config来配置,对业务层是完全透明的。这三个接口是:一个配置参数上下文接口、一个SSO提供器接口(同时兼做捕捉身份状态变化的Handler接口)、一个Handler接口的工厂接口(以保持Handler接口的构造器自由以及决定是否建立Handler接口的实现类实例)。
posted @ 2008-01-19 14:33 小罗 阅读(38) 评论(0)
编辑
URL重写已经有很多的方法,但是多数都有一个缺点,就是不支持无扩展名的网页。比如把http://blog.knowsky.com/category_1_1.htm 转换为 http://blog.knowsky.com/category.aspx?id=1。
微软提供的方法需要在根目录里面建立jyk的文件夹,然后再建立一个default.aspx的文件,如果您有100名会员的话,这是一个不可想象的事情。
另一个方法就是使用ISAPI过滤器,但是这个一般需要在服务器上安装一个DLL文件,自己没有服务器就不好办了。
下面提供一个可以说是我发明的一个方法——不知道以前有没有人想到过——利用两个特性来实现。
第一个:IIS里面的找不到文件的错误设置。
第二个:asp.net 里面的Server.Transfer("topic.aspx?id=jyk");
这两个结合起来就可以达到我们的目的了。
思路:利用404b错误捕捉客户的请求,再使用Server.Transfer转向。
在我们访问http://www.aaa.com/jyk 的时候,假设这时服务器上没有jyk文件夹,那么会返回什么结果呢?会返回一个“无法找到该页”的页面,那么这个返回结果能不能自己控制一下呢?很幸运IIS提供了这个功能,我们可以把这样的错误指定到网站里的一个页面。
操作步骤:
第一步:打开IIS管理器,网站属性——自定义错误标签——404错误——点击修改——修改“消息类型”为“URL”,在下面的文本框里填写处理这个错误得页面名称,比如/none.aspx。
第二步:在我们的网站根目录下建立一个none.aspx的网页。在里面随意写点内容(测试用)。
设置完毕,这时再访问http://www.aaa.com/jyk,显示的就是 none.aspx的网页内容了。注意这时浏览器里面的URL地址仍然是http://www.aaa.com/jyk,而不是http://www.aaa.com/none.aspx 。这一点很重要,如果地址变了,那就没有意义了。
那么我们怎么把页面转到我们希望的页面呢,这时所有的找不到文件的情况都会转到none.aspx文件,显然这不是我们想要的最终结果。那么我们怎么获取客户输入的网址呢?
打开none.aspx的后台文件,
string URL = Request.Url.Query;
我们可以使用上面的语句来获取URL地址,得到的地址格式是:
?404http://www.aaa.com/jyk
其中 “?404”是固定的,过滤掉它就是浏览器里面的URL地址了。
剩下的事情就是根据情况来转换网页了。可以拆串,再用switch来判断;也可以用正则表达式来判断。因为我正则不熟,我采用的是switch的方式。正则表达式请参考其他的资料,我也在找,如果您找到了请共享一下,谢谢。
优点:
1、 支持无扩展名的网页。不用建立文件夹和文件。
2、 思路简单,用法也很简单,代码也不复杂,不涉及高深的理论;
3、 支持搜索引擎,就是说可以被各大搜索引擎搜录。
4、 可以配合域名泛解析使用。
缺点:
1、 需要修改一下IIS 404b错误的处理方法;
2、 效率要略微低一点。
3、 如果您只使用.aspx的扩展名的话就可以不用修改IIS了。
4、 Asp不支持。因为asp的Server.Transfer不能带参数(?id=jyk),不能传递参数的重写几乎没有什么意义。
posted @ 2008-01-19 14:32 小罗 阅读(104) 评论(0)
编辑