ASP.NET笔记

学校开的课,没怎么深入,跟着学了点常用的,整理下以备用
其实都差不多….

母版页

母版页也就是模板页 大雾:),就是一个模板,网站的很多页面有很多地方都是相同的,尤其是后台管理系统,我们不可能每次都copy一份代码,所以就有了母版页,采用母版页的页面保证只有在母版页允许自定义的地方才能写前台代码,母版页中会包含下面这样的一个标签:

1
2
3
4
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
...
</asp:ContentPlaceHolder>
<!--上面的标签内是可以添加前台代码的地方-->

Session全局变量

网页间的传值是个问题,ASP中不能和winform那样传值了,一般是用Session,我也就会这一种了….
创建方法右键–添加新项–全局应用程序类,默认是个名为Global.asax的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<%@ Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
//存在于服务器,只有一个
Application.Lock();
Application["online"] = 0;
Application.UnLock();
}

void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
}

void Application_Error(object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
}

void Session_Start(object sender, EventArgs e)
{
// 在新会话启动时运行的代码
//每一个用户拥有自己的一个Session,用户连接的时候分配,用户离开站点(连接断开)即被释放
//存在于服务端,用户无法直接获取
Session["uname"] = "loli";
Application.Lock();
Application["online"] = (int)Application["online"] + 1;
Application.UnLock();
}

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

在代码中可以直接用Session["uname"]来进行获取值

页面跳转以及IsPostBack

页面跳转没什么特别可说的,就一行代码:

1
Response.Redirect("./Admin/Default.aspx");

可以使用相对路径也可以使用绝对路径
然后就是ASP中一个比较大的坑,我们可以看到ASP官方的控件中都有个属性叫runat="server",可以理解为当触发某个条件时比如按钮的点击事件,就会和服务器进行一次交流,不说性能方面的问题,还有一个很大的问题就是会刷新整个页面,也就是说会把后台代码再执行一遍,很多时候就会把用户设置、输入的内容给重置了….
所以我们一般都会写这样的代码:

1
2
3
4
5
6
7
8
protected void Page_Load(object sender, EventArgs e)
{
//是不是第一次加载,只有第一次加载才进行数据绑定
if (!IsPostBack)
{
bindData();
}
}

连接数据库

稍微学过点C#的这里应该比较熟悉了,都差不多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static SqlConnection getConn()
{
string connString = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
return new SqlConnection(connString);
}
public static DataSet GetDataSet(string strSQL)
{
SqlConnection conn = getConn();
conn.Open();

SqlDataAdapter da = new SqlDataAdapter(strSQL, conn);
DataSet ds = new DataSet();
da.Fill(ds);
conn.Close();
return ds;
}

就是获取的Web.config中的配置,数据库连接字符串在这里面,部署到服务器后是不允许下载这个文件的

1
2
3
4
5
6
7
8
9
10
11
12
<configuration>
<connectionStrings>
<add name="conn" connectionString="Data Source=.;Initial Catalog=test;uid=sa;pwd=12345;" />
</connectionStrings>

<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<!--用户最大上传文件为40M,超时时间最大60秒,最大并发100-->
<httpRuntime targetFramework="4.5.2" maxRequestLength="40960" executionTimeout="60" appRequestQueueLimit="100"/>
</system.web>

</configuration>

GridView控件

对于这个控件确实是非常好用的,它可以直接用鼠标设置,也可以用代码,一般是要进行修改列名为中文的,可读性比较好,在编辑列选项中添加BoundField,记得进行和数据表中的字段进行绑定,同时可以添加一些编辑、更新、删除等操作,如果要用这些功能一定记得加ISPostBack判断
如果要自定义加按钮什么的,可以添加个 TemplateField里面再套个ItemTemplate然后把控件装进去
还有一点,如果加了单选框之类的控件默认改变是不会自动上传服务器的,需要手动加个AutoPostBack="true"属性,但是我们又不希望每点一个就和服务器通讯次,为了减轻压力以及更好的用户体验,可以考虑把GridView外面套一个updatepanel控件,这样应该会进行批量更新….
updatepanel标签需要和scriptmanager配套使用,我没仔细研究过,我当时只是为了解决让它不频繁的触发刷新
不要忘了在控件的属性中设置对应的事件
下面的两个例子把上面的所有功能都用到了,应该….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<asp:scriptmanager id="ScriptManager1" runat="server">
</asp:scriptmanager>

<asp:updatepanel runat="server" id="UpdatePanel1">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" AllowSorting="True" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<!-- ReadOnly="True"可设置为不可编辑部分 -->
<asp:BoundField DataField="name" HeaderText="姓名" />
<!-- 自定义选项部分 -->
<asp:TemplateField HeaderText="性别">
<ItemTemplate>
<asp:RadioButton ID="RadioButton1" runat="server" Text="男" Checked="true" GroupName="g1" AutoPostBack="true" />
<asp:RadioButton ID="RadioButton2" runat="server" Text="女" GroupName="g1" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:updatepanel>

然后是如果使用了编辑、删除、更新之类的,还是要记得加相应的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private void BindData()
{
//设置分页显示相关,也可以在属性里设
GridView1.AllowPaging = true;
GridView1.PageSize = 10;
GridView1.DataSource = GetDT();
//更新数据必须要有条件,就是这个了
GridView1.DataKeyNames = new string[] { "UserID" };
GridView1.DataBind();
}

//删除
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
if (DeleteRows("TabName", "UserID", GridView1.DataKeys[e.RowIndex].Value.ToString()))
BindData();
}

//编辑
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//让其(行)处于编辑状态,要刷新数据才能生效
GridView1.EditIndex = e.NewEditIndex;
BindData();
}

//更新
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//找到编辑状态那一行的第1列中的第一个控件,默认编辑状态后是TextBox
//操作完了不要忘了取消编辑状态,刷新数据源
if (UpdateRows("TabName", "UserID", ((TextBox)GridView1.Rows[e.RowIndex].Cells[0].Controls[0]).Text.ToString().Trim()))
{
GridView1.EditIndex = -1;
BindData();
}
}

//取消
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
BindData();
}

//切换页数
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindData();
}

Repeater控件

默认有五种模板:

  • ItemTemplate : 对每一个数据项进行格式设置
  • AlternatingItemTemplate : 对交替数据项进行格式设置 ,显示2、4、6条
  • SeparatorTemplate : 对分隔符进行格式设置
  • HeaderTemplate : 对页眉进行格式设置
  • FooterTemplate : 对页脚进行格式设置

ItemTemplate标签内的内容会重复,和数据表的行数一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<HeaderTemplate>
<!-- 显示头部 -->
<table class="movies">
<!-- table头部声明-->
<tr>
<th>序号</th>
<th>详细信息</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<!-- 数据行 -->
<tr>
<td>
<%--自动编号--%>
<asp:Label ID="lbNo" runat="server" Text="<%#Container.ItemIndex+1 %>"></asp:Label>
</td>
<td>
<asp:TextBox ID="TBweek" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"Week") %>'></asp:TextBox>
<asp:TextBox ID="TBtime" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"Time") %>'></asp:TextBox> '
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<!-- 脚注行 -->
</table>
<!-- table尾 -->
</FooterTemplate>
</asp:Repeater>

上传文件到服务器

比如你如果想导入Excel也好还是设置头像也好,文件是必须先要上传到服务器才能操作的,这里使用FileUpload控件来上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private string Upload(FileUpload fuload)
{
//获取选择文件的扩展名
string fileExtenSion = Path.GetExtension(fuload.FileName);
//检测文件扩展名(格式)
if (fileExtenSion.ToLower() != ".xls" && fileExtenSion.ToLower() != ".xlsx")
{
return null;
}
try
{
//GetFileName返回文件名和扩展名
string FileName = "App_Data\\" + Path.GetFileName(fuload.FileName);
//判断文件是否存在,如果存在先删除,Server.MapPath返回服务器的物理路径
if (File.Exists(Server.MapPath(FileName)))
{
File.Delete(Server.MapPath(FileName));
}
//上传文件到指定目录
fuload.SaveAs(Server.MapPath(FileName));
return Server.MapPath("./") + FileName;
}
catch (Exception e)
{
return null;
}
}

读取Excel文件

我基本也是从网上找的实例代码,需要安装相应的支持库才行,区分32与64位系统,可以在项目中设置IIS以64位运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private static OleDbConnection getOleConn(string fileName)
{
System.GC.Collect();
OleDbConnection oleConn;

//HDR=Yes,这代表第一行是标题,不做为数据使用
//如果用HDR=NO,则表示第一行不是标题,做为数据来使用。系统默认的是YES
string connstr2003 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'";
string connstr2007 = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES\"";

string fileExtenSion = fileName.Substring(fileName.LastIndexOf(".") + 1);
//建立连接,根据不同的扩展名,选择不同的引擎
if (fileExtenSion.ToLower() == "xls")
{
oleConn = new OleDbConnection(connstr2003);
}
else
{
oleConn = new OleDbConnection(connstr2007);
}
return oleConn;
}

public static void ReadExcelToDataSet(string fileName, string strSQL)
{
OleDbConnection conn = getOleConn(fileName);
conn.Open();

OleDbDataAdapter da = new OleDbDataAdapter(strSQL, conn);
da.SelectCommand.CommandTimeout = 600;

ds = new DataSet();
//在ds中规定表名为ExcelInfo
da.Fill(ds, "ExcelInfo");

conn.Close();
conn.Dispose();
}

Excel批量快速导入

主要使用ASP中一个叫SqlBulkCopy的类,想要导入最快要保证内存中的DT和数据库的表结构相同,倒是没必要字段也相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void SQLBulkCopy(DataTable dt,string dtName)
{
//using内的对象在代码块结束后会自动销毁,所以conn不用close
using (SqlConnection conn = getConn())
{
conn.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.DestinationTableName = dtName;
//假设数据库和Excel表的列名不同,内存列名映射到数据库的列名
//bulkCopy.ColumnMappings.Add("loct", "serve");
bulkCopy.WriteToServer(dt);
}
}
}

补充

datatable控件是个很好用的控件,包括类,对于DT的顺序问题,是有个排序方法的,比如可以这样

1
2
3
4
5
DataTable dt = getDT();
DataView dv = dt.DefaultView;
dv.Sort = "week ASC,time";
Repeater1.DataSource = dv.ToTable();
Repeater1.DataBind();

对于判断一个字符串是不是为空,又很多写法都可以实现,据说下面的这种方式比较高效:
strTest.Length == 0

喜欢就请我吃包辣条吧!

评论框加载失败,无法访问 Disqus

你可能需要魔法上网~~