一、C#高级特性
1.C#委托
1.1.C#委托的概述和声明
C#委托可以避免在程序中大量使用if-else语句,同时使程序具有更好的可扩展性。
1.1.1.委托的概述
委托是一种引用类型,他表示对具有特定参数列表和返回类型的方法的引用。在实例化委托时,可以将其实例与任何具有兼容签名和返回类型的方法相关联,可以通过委托实例调用方法,也可以使用委托将方法作为参数传递给其他方法。
编写架构级代码,委托的使用将大大提高程序的可扩展性
1.1.2.委托的声明
委托声明决定了可由该委托引用的方法,委托可指向一个与其具有相同标签的方法。
public delegate <return type> <delegate-name> <parameter list>
关键字 返回类型 委托名 参数列表
public delegate string TranslationDelegate (string s)
以上委托可引用任何带有一个单一string类型的参数,并返回一个string类型的方法
1.2.委托的使用
1.2.1.委托实例化
TranslationDelegate transform=new TranslationDelegate(ChineseSayHello);
其中ChineseSayHello是中文问好的方法的引用
说明:
在C#2.0的语法中,实例化委托可以简写为将方法引用直接指向委托,实例如下
TranslationDelegate transform=ChineseSayHello;
1.2.2.调用委托
一般可以使用委托对象的Invoke()方法来调用委托
transform.Invoke("张三");
可简化为
transform("张三");
注意:
指向的方法需要符合委托所定义的方法签名和返回类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1
{
class Program
{
//1.声明委托
public delegate string OpertionDelegate(string name);
static void Main(string[] args)
{
//2.实例化
//OpertionDelegate opertionDelegate= new OpertionDelegate(SayChinese);
//()=>{}
Action<string> action = new Action<string>((name)=> {
Console.WriteLine(name+"早上好");
});
//3.调用
//string message=opertionDelegate.Invoke("wt");
action("王涛");
//Console.WriteLine(message);
//OpertionDelegate opertionDelegate1 = SaEnglish;//直接指向它
Func<string, string> func = new Func<string, string>((name)=> {
return name + "say hello";
});
Console.WriteLine(func("hy:"));
Func<string, string> func1 = (name) =>
{
return name + "say hello";
};
Console.WriteLine(func1("hy:@"));
//Console.WriteLine(opertionDelegate1("lily"));
//委托作为参数使用——调用
//Console.WriteLine(Say("李四",SaEy));
}
//委托作为参数使用
public static string Say(string name, OpertionDelegate opertionDelegate)
{
return opertionDelegate(name);
}
public static string SayChinese(string name)
{
return name + ":早上好";
}
public static string SaEnglish(string name)
{
return name + ":say hello";
}
public static string SaEy(string name)
{
return name + ":say Ey";
}
}
}
1.2.3.多播委托
委托对象有一个好用属性,可通过使用+运算符将多个对象分配到一个委托实例上,形成多播委托。多播委托包含已分配的委托列表,因此多播委托被调用时会依次调用列表中的委托。但是多播委托仅可合并类型相同的委托。使用-运算符可以从多播委托中删除组件委托。
1.2.4.使用委托将方法作为参数传递给另一个方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._1
{
class Program
{
//多播委托
//1.声明一个委托
public delegate void OperteDelegate(string name);
static void Main(string[] args)
{
//2.实例化委托
//OperteDelegate operteDelegate = Eating;
//匿名方法
OperteDelegate operteDelegate = delegate (string name)
{
Console.WriteLine(name + "正在吃饭");
};
operteDelegate += Watching;
operteDelegate("刘星");
//3.委托调用+=
}
//吃饭 一个入参
/*public static void Eating(string name)
{
Console.WriteLine(name+"正在吃饭!");
}*/
//看电视
public static void Watching(string name)
{
Console.WriteLine(name + "正在看电视!");
}
}
}
2.隐式类型与匿名类型
2.1.隐式类型
在C#中,声明的变量可以使用隐式类型,即将普通变量声明中的数据类型名称替换为var,编译可以根据变量的初始值推断变量的类型。
var 变量=初始值;
隐式类型两点限制:
变量必须初始化
声明变量,推断出类型后,变量类型不能改变
2.2.匿名类型
匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需先显式定义一个类型。
类型名由编译器生成,并且不能再源代码级使用。
每个属性的类型由编译器推断,可通过使用new运算符和对象初始值创建匿名类型
2.2.1.匿名类
匿名类其本质和普通定义的类一样,只不过是由系统的编译器来完成命名的
2.2.2.匿名方法
委托是引用与其具有相同标签的方法。匿名方法是没有名称只有主体的方法
注意:
匿名方法不用声明返回值类型,但是匿名方法返回值类型必须和委托返回值类型一致。
在参数方面,参数数量、类型和修饰符必须和委托一样
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._2
{
//匿名类
public class Program
{
static void Main(string[] args)
{
var user = new user()
{
userName = "张三",
age = 18,
isMarray = false
};
var user1 = new
{
userName = "张三",
age = 18,
isMarray = false
};
Console.WriteLine("user类型"+user.GetType());
var name = user.userName;
Console.WriteLine("user类型"+name.GetType());
//匿名调用
Console.WriteLine("name类型" + user1.GetType());
var name1 = user.userName;
Console.WriteLine("name类型" + name1.GetType());
}
}
public class user
{
public string userName;
public int age;
public bool isMarray;
}
}
3.C#扩展方法与yield关键字
3.1.C#扩展方法
扩展方法使编码人员能够向现有类型添加方法,而无需创建新的派生类型、重新编译或以其他方法修改原始类型。
3.1.1.扩展方法介绍
C#扩展方法是允许使用实例方法的调用语法来调用静态方法的语言功能。
C#扩展方法至少有一个参数,C#扩展方法的第一个参数指定该方法作用于哪种类型,并且该参数以this修饰符为前缀。
C#扩展方法不能破坏面向对象封装概念,所以只能是访问所扩展类的public成员。
C#扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
C#扩展方法的定义与调用如下:
定义包含C#扩展方法的静态类,此类必须对客户端代码可见。
将C#扩展方法实现为静态方法,并且使其可访问性与所在类的可访问性一致
C#扩展方法的第一个参数是指定方法所操作的类型,此参数前面必须加上this修饰符
在调用代码中添加using指令,用于指定包含扩展方法类的命名空间
C#扩展方法的调用与调用类型的实例方法一样
3.1.2.C#扩展方法的创建和使用
例如:为string类型扩展一个单词计数的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._3
{
public static class TestExtensionM
{
//1.静态类
//2.静态方法
//3.this
// 9 18
public static int ExtensionInt(this int s)
{
return s + s;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._3
{
public static class StringExtension
{
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '.', '?' },StringSplitOptions.RemoveEmptyEntries).Count();
}
}
}
StringSplitOptions.RemoveEmptyEntries 去除空项
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._3
{
//C#扩展方法
class Program
{
static void Main(string[] args)
{
int a = 9;
a = a.ExtensionInt();
//a=TestExtensionM.ExtensionInt(a);
Console.WriteLine(a);
string str = "hello lily morring";
int num=str.WordCount();
Console.WriteLine("单词个数"+num);
}
}
}
3.2.yield关键字
迭代器是C#2.0中的新功能,有了它,我们就可以在自己的类或结构中支持foreach迭代而不必实现整个IEnumerabl接口,只需要提供一个迭代器,即可遍历类中的数据结构
yield关键字向编译器指示该关键字所在的方法是迭代器块。编译器将生成一个类来实现迭代器块中所表示的行为。
在迭代器块中,yield关键字与return关键字结合使用,向迭代器对象提供值。该值为返回值,例如,在foreach语句中每一次循环中返回的值。
yield关键字也可与break结合使用,表示迭代结束。
如果在语句中使用yield关键字,则意味着有该关键字出现的方法、运算符或get访问器是迭代器。通过使用yield定义迭代器,可在实现自定义集合类型的IEnumerator<T>和IEnumerator模式时无需使用其他显式类型
例如:使用foreach循环语句对List<T>集合进行循环遍历,将符合条件的数据返回。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._3._2
{
public class Good
{
public string GoodName { get; set; }
public int GoodPrice { get; set; }
}
public class UserGoods
{
public static IEnumerable<Good> GetGoods(List<Good> goods,int price)
{
foreach (var item in goods)
{
if (item.GoodPrice==price)
{
yield return item;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1._3._2
{
//yield关键字
class Program
{
static void Main(string[] args)
{
List<Good> goods = new List<Good>()
{
new Good{GoodName="可乐",GoodPrice=4},
new Good{GoodName="爆米花",GoodPrice=4},
new Good{GoodName="雪糕",GoodPrice=5},
new Good{GoodName="薯条",GoodPrice=7},
new Good{GoodName="方便面",GoodPrice=4}
};
var obj=UserGoods.GetGoods(goods, 4);
foreach (var item in obj)
{
Console.WriteLine("商品价格{0}|,商品名称{1}",item.GoodPrice,item.GoodName);
}
}
}
}
4.Lambda表达式
4.1.Lambda表达式概述
Lambda表达式是一个匿名方法,即没有方法名的方法。
C#的Lambda表达式都使用Lambda运算符“=>”,该运算符读为“goes to”
形参列表=>方法体
函数体多于一条语句的可用大括号括起
4.2. Lambda表达式的使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo1
{
class Program
{
//1.声明委托
public delegate string OpertionDelegate(string name);
static void Main(string[] args)
{
//2.实例化
//OpertionDelegate opertionDelegate= new OpertionDelegate(SayChinese);
//()=>{}
Action<string> action = new Action<string>((name)=> {
Console.WriteLine(name+"早上好");
});
//3.调用
//string message=opertionDelegate.Invoke("wt");
action("王涛");
//Console.WriteLine(message);
//OpertionDelegate opertionDelegate1 = SaEnglish;//直接指向它
Func<string, string> func = new Func<string, string>((name)=> {
return name + "say hello";
});
Console.WriteLine(func("hy:"));
Func<string, string> func1 = (name) =>
{
return name + "say hello";
};
Console.WriteLine(func1("hy:@"));
//Console.WriteLine(opertionDelegate1("lily"));
//委托作为参数使用——调用
//Console.WriteLine(Say("李四",SaEy));
}
//委托作为参数使用
public static string Say(string name, OpertionDelegate opertionDelegate)
{
return opertionDelegate(name);
}
public static string SayChinese(string name)
{
return name + ":早上好";
}
public static string SaEnglish(string name)
{
return name + ":say hello";
}
public static string SaEy(string name)
{
return name + ":say Ey";
}
}
}
二、LINQ
1.LINQ概述与查询语法
LINQ(Language Integrated Query)语言集成查询
LINQ主要关键字 | |
关键字 | 说明 |
from | 指定范围变量和数据源 |
where | 根据bool表达式从数据源中筛选数据 |
select | 指定查询结果中的元素所具有的类型或表现形式 |
group | 对查询结果按照键/值执行分组 |
into | 提供一个标识符,它可以充当对join、group或select子句结果的引用 |
orderby | 对查询出的元素执行排序(ascending/descending) |
join | 按照两个指定匹配条件对等连接两个数据源 |
let | 产生一个用于存储子表达式查询结果的范围变量 |
完整的LINQ语法的写法可以定义为以下结构,粗体表示LINQ关键字
from [type] id in source
type是可选项,id是数据源集合中的一项,source是数据源集合,如果集合中的类型与type指定的类型不同,则导致强制类型转化
[join [type] id in source on expr equals expr [into subGroup]]
一个LINQ语句中可以有0个或多个join子句,此处的source可以不同于第一句中的source。expr是一个表达式。subGroup是一个临时变量,他继承自IGrouping,代表一个分组,即一对多中的多,可以通过此变量得到该组包含的对象个数(Count)以及该组对象的键(Key)
[from [type] id in source | let id=expr | where condition]
一个LINQ语句中可以有1个或多个from子句,可以有0个或多个let子句(let子句可以创建一个临时变量)可以有0个或多个where子句(where子句指定查询条件)
[orderby ordering,ordering,ordering...]
一个LINQ语句中可以有0个或多个orderby子句,即排序,每种排序方式以逗号分开
select expr | group expr by key
一个LINQ语句必须以select或group by结束,select是要检索的内容,group by是对查询的内容执行分组
[into id query]
最后一个into子句起到的作用是将前面语句的结果作为后面语句操作的数据源
注意:查询表达式必须以from子句开头,并且必须以select或group子句结尾。在第一个from子句和最后一个select或group子句之间,查询表达式可以包含一个或多个可选子句,如where、orderby、join、let,甚至附加的from子句。还可以使用into关键字使join或group子句的结果能够充当同一查询表达式中附加查询子句的源。
提醒:IEnumerable接口时LINQ查询的核心接口,只有实现了IEnumerable接口的数据源,才能执行相关的LINQ操作。LINQ查询操作由三个步骤组成,即获取数据源,创建查询和执行查询。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo2._1
{
internal class Program
{
//查询语法 方法语法
static void Main(string[] args)
{
//linQ查询三步骤
//1.定义数据源
int[] numbers = new int[7] {0,3,2,5,1,6,4 };
string[] names = { "Tom", "Dick", "Marry", "Hary", "Jay", "Money" };
//2.创建查询语法 IEnumerable<int>
/*var numQuery =
from num in numbers
where (num % 2) == 0
orderby num
select num;*/
//把能被2整除的数 改成方法语法
var numQuery = numbers
.Where(x => x % 2 == 0)
.OrderBy(x => x);
//方法语法
var nameQuery = names
.Where(n=>n.Contains("a"))
.OrderBy(n=>n.Length)
.Select(n => n.ToUpper());
//3.执行语法
foreach (var num in numQuery)
{
Console.WriteLine("{0,1}", num);
}
foreach (var item in nameQuery)
{
Console.WriteLine("{0,1}", item);
}
}
}
}
2.LINQ方法语法基础
通用类型名说明 | |
通用类型名称 | 用途 |
TSource | Input Sequence中的Element类型 |
TResult | Output Sequence中的Element类型 |
TKey | 使用sorting、grouping、joining等的键值类型 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo2._2
{
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Score { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading.Tasks;
namespace demo2._2
{
class Program
{
static List<Student> students = new List<Student> {
new Student{First="Swetlant",Last="zhangsan",ID=111,Score=new List<int>{98,89,74,99} },
new Student{First="Swetlant1",Last="shangsan1",ID=111,Score=new List<int>{98,49,38,99} },
new Student{First="Swetlant2",Last="lhangsan2",ID=111,Score=new List<int>{58,69,78,99} },
new Student{First="Swetlant3",Last="ihangsan3",ID=111,Score=new List<int>{28,79,78,99} },
new Student{First="Swetlant4",Last="phangsan4",ID=111,Score=new List<int>{91,89,88,99} },
new Student{First="Swetlant5",Last="zhangsan5",ID=111,Score=new List<int>{98,89,68,99} },
new Student{First="Swetlant6",Last="zhangsan6",ID=111,Score=new List<int>{98,89,87,99} },
new Student{First="Swetlant7",Last="zhangsan7",ID=111,Score=new List<int>{98,89,76,99} },
new Student{First="Swetlant8",Last="zhangsan8",ID=111,Score=new List<int>{98,89,56,99} },
};
static void Main(string[] args)
{
//1.构建数据源
//2.创建方法语法
//2.1第三门成绩大于70
var studentQuery = students
.Where(s => s.Score[2] > 70 && s.Score[0] > 90)
.OrderByDescending(s => s.Score[0]);
//2.2第三门成绩大于70并且第一门大于90
//2.3根据第一门成绩降序
//2.4分组
//var studentQuery2 = students.GroupBy(a => a.Last[0]);
//2.5聚合函数求平均值
var studentQuery2 = students.Select(p => new {
last=p.Last,
first=p.First,
scores=p.Score.Average()
}).FirstOrDefault();
//3.执行
/*foreach (var item in studentQuery)
{
Console.WriteLine("{0},{1},{2}", item.First, item.Score[2], item.Score[0]);
}*/
}
}
}
投影(取列)
var studentQuery=students.Select(p=>new{last=p.Last,first=p.First,id=p.Id});
foreach(var student in studentQuery){
Console.WriteLine("{0},{1},{2}",student.last,student.first,student.id);
}
3.LINQ聚合操作与元素操作
3.1.LINQ聚合操作
执行聚合的标准查询运算符方法 | ||
方法名 | 说明 | 查询表达式语法 |
Count() | 对集合中的元素计数,以及对集合中满足条件的元素计数 | 不适用于查询语法 |
LongCount() | 与Count相同,当Count中元素的个数超过int类型值的上限时使用 | 不适用于查询语法 |
Max() | 确定集合中的最大值 | 不适用于查询语法 |
Min() | 确定集合中的最小值 | 不适用于查询语法 |
Sum() | 计算集合中值的总和 | 不适用于查询语法 |
Average() | 计算集合中值的平均值 | 不适用于查询语法 |
说明:所有的聚合操作只支持方法语法,不支持查询语法
3.2.LINQ元素操作
执行元素操作运算的标准查询运算符方法 | ||
方法名 | 说明 | 查询表达式语法 |
Elementat() | 返回集合中指定索引处的元素 | 不适用于查询语法 |
ElementatorDefault() | 返回集合中指定索引处的元素,如果索引超出范围则返回默认值 | 不适用于查询语法 |
First() | 返回集合中的第一个元素或满足条件的第一个元素 | 不适用于查询语法 |
FirstOrDefault() | 返回集合中的第一个元素或满足条件的第一个元素,如果没有则返回默认值 | 不适用于查询语法 |
Last() | 返回集合中的最后一个元素或满足条件的最后一个元素 | 不适用于查询语法 |
LastOrDefault() | 返回集合中的最后一个元素或满足条件的最后一个元素,如果没有则返回默认值 | 不适用于查询语法 |
Single() | 返回集合中的唯一元素或满足条件的唯一元素 | 不适用于查询语法 |
SingleOrDefault() | 返回集合中的唯一元素或满足条件的唯一元素,如果没有则返回默认值 | 不适用于查询语法 |
注意:所有元素操作运算返回值的类型均为集合中的元素类型,而非集合类型。所有元素操作运算都不支持查询语法的方法书写,当时使用Elementat()、First()、Last()、Single()运算时,在操作的集合中元素个数为0时会报错,使用对应的ElementatorDefault()、FirstOrDefault()、LastOrDefault()、SingleOrDefault()可以避免报错并返回默认值。
但是Singer运算要求取操作的集合中唯一的元素,当操作的集合中元素个数为0时将报错,SingleOrDefault()运算符可以返回默认值,而当操作的集合中元素个数多于1时,Single()和SingleOrDefault()运算都会报错。
4.数据类型转换
执行数据类型转换运算的标准查询运算符方法 | ||
方法名 | 说明 | 查询表达式语法 |
ToList() | 将集合转换为List<T> | 不适用于查询语法 |
ToArray() | 将集合转换为数组 | 不适用于查询语法 |
ToDictionary() | 根据键选择器函数将元素放入Dictionary<TKey,Telement>中 | 不适用于查询语法 |
ToLookup() | 根据键选择器函数将元素放入Lookup<TKey,Telement>中 | 不适用于查询语法 |
AsEnumerable() | 将一个序列转换为IEnumerable<T>集合 | 不适用于查询语法 |
AsQueryable() | 将IEnumerable<T>转换为IQueryable<T> | 不适用于查询语法 |
Cast() | 将集合的元素强制转换为指定类型 | 不适用于查询语法 |
OfType() | 根据值强制转换为指定类型的能力筛选值 | 不适用于查询语法 |
三、EF的基本使用
1.数据实体模型概述
1.1.ORM技术介绍
O对应程序中的类
R为联系,对应数据库中的关系表
M表示程序中对象和数据库中关系表的映射关系
1.2.EF建模
EF是微软公司开发的基于ADO.NET的ORM框架
EF支持Database First(数据库优先)、Model First(模型优先)、Code First(代码优先)三种模式
添加新项——数据——ADO.NET实体数据模型——来自数据库的EF设计器——新建连接——实体框架6.x——勾选数据库对象——完成
2.数据模型更新与添加数据
2.1.数据模型更新
在EF设计器的空白处单击鼠标右键,选择从数据库更新模型
2.2添加数据
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace demo3
{
public partial class OrderAdd : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (meixinEntities db = new meixinEntities())
{
DropDownList1.DataSource = db.m_user.ToList();
DropDownList1.DataTextField = "email";
DropDownList1.DataValueField = "id";
DropDownList1.DataBind();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
//新增按钮
//构造添加订单的对象
m_order order = new m_order
{
m_user_id = Convert.ToInt32(DropDownList1.SelectedValue),
m_user_email = DropDownList1.SelectedValue,
message = txtMessage.Text,
phone = txtPhone.Text,
status = "准备配送",
ordertime = DateTime.Now.Date,
address = txtAddress.Text,
total = Convert.ToDouble(txtCount.Text)
};
//add()
using (meixinEntities db = new meixinEntities())
{
db.m_order.Add(order);
//savechange()
db.SaveChanges();
//跳转到列表页
Response.Redirect("OrderList.aspx");
}
}
}
}
3.EF执行查询、更新与删除
3.1.查询和删除
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="OrderList.aspx.cs" Inherits="demo3.OrderList" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div style="padding-left:100px;">
<asp:LinkButton ID="lbtAdd" runat="server" OnClick="lbtAdd_Click">新增</asp:LinkButton>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:BoundField DataField="id" HeaderText="订单ID" />
<asp:TemplateField HeaderText="用户邮箱">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("m_user.email") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="address" HeaderText="地址" />
<asp:BoundField DataField="message" HeaderText="消息" />
<asp:BoundField DataField="status" HeaderText="状态" />
<asp:BoundField DataField="phone" HeaderText="电话" />
<asp:BoundField DataField="ordertime" HeaderText="订单时间" />
<asp:BoundField DataField="total" HeaderText="总额" />
<asp:TemplateField HeaderText="操作">
<ItemTemplate>
<asp:LinkButton ID="lbtEdit" runat="server" CommandName="编辑" CommandArgument='<%# Eval("id") %>'>编辑</asp:LinkButton>
<asp:LinkButton ID="lbtDel" runat="server" CommandName="删除" CommandArgument='<%# Eval("id") %>' OnClientClick="return confirm('是否要删除?')">删除</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace demo3
{
public partial class OrderList : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//绑定数据
using(meixinEntities db=new meixinEntities())
{
GridView1.DataSource = db.m_order.ToList();
GridView1.DataBind();
}
}
protected void lbtAdd_Click(object sender, EventArgs e)
{
//新增
Response.Redirect("OrderAdd.aspx");
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
//获取参数
int orderId = Convert.ToInt32(e.CommandArgument);
if (e.CommandName=="编辑")
{
//编辑
Response.Redirect("OrderEdite.aspx?id="+ orderId);
}
if (e.CommandName == "删除")
{
//删除
using(meixinEntities db =new meixinEntities())
{
m_order order= db.m_order.FirstOrDefault(p => p.id == orderId);
db.m_order.Remove(order);
if (db.SaveChanges() > 0)
{
Response.Write("<script>alert('删除成功')</script>");
}
}
}
}
}
}
3.2.更新
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="OrderEdite.aspx.cs" Inherits="demo3.OrderEdite" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="border:1px solid black">
<tr>
<td>订单ID</td>
<td>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td>订单用户</td>
<td>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td>订单状态</td>
<td>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">
<asp:Button ID="Button1" runat="server" Text="提交" OnClick="Button1_Click" />
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace demo3
{
public partial class OrderEdite : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//拿到你要编辑的ID
int id = Convert.ToInt32(Request.Params["id"]);
//获取这一条数据
using (meixinEntities db = new meixinEntities())
{
m_order order = db.m_order.FirstOrDefault(p => p.id == id);
if (order != null)
{
Label1.Text = order.id.ToString();
Label2.Text = order.m_user_email;
TextBox1.Text = order.status;
}
}
//填充前台label
}
}
protected void Button1_Click(object sender, EventArgs e)
{
//修改提交
using (meixinEntities db = new meixinEntities())
{
int id = Convert.ToInt32(Request.Params["id"]);
m_order order = db.m_order.FirstOrDefault(p => p.id == id);
order.status = TextBox1.Text;
db.SaveChanges();
Response.Redirect("OrderList.aspx");
}
}
}
}
四、EF的高级使用
1.EF执行SQL语句(一)
在数据上下文DbContext中有一个Database的属性,Database属性中有两组方法,即ExecuteSqlCommand()方法和SqlQuery()方法
ExecuteSqlCommand()方法:不返回结果的,只返回受影响行数。更适合用来执行创建、插入、更新、删除操作(即执行给定的DDL/DML命令),DDL返回-1,DML返回行数
SqlQuery()方法:返回查询到的结果,并将结果保存在数据实体中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace demo4
{
class Program
{
static void Main(string[] args)
{
//创建表 DDL -1
/*string strCreate = @"create table Admin(
Id int primary key not null,
Account varchar(16),
Password varchar(20),
)";//@逐字字符 忽略转意 \n*/
//新增数据
/*string strInsertSQL = @"insert into Admin
select 1,'王五','123456' union
select 2,'张三','123456' union
select 3,'李四','123456' ";*/
//修改数据
/*string strUpdateSQL = @"update Admin
set Password='654321'
where Id=2";*/
/*string strUpdateSQL = @"update Admin set Password=@pwd1 where Id=@id1;
update Admin set Password=@pwd2 where Id=@id2";*/
/*SqlParameter[] sqlParameters =
{
new SqlParameter("@pwd1","654321"),
new SqlParameter("@id1",1),
new SqlParameter("@pwd2","654321"),
new SqlParameter("@id2",3),
};*/
//删除数据
//string strDeleteSQL = "delete from Admin";
//删除表 DDL -1
//string strDropSQL = "drop table Admin";
/*using (EFClass2Entities connDB=new EFClass2Entities())
{
*//*int rs=connDB.Database.ExecuteSqlCommand(strCreate);
if (rs.Equals(-1))
{
Console.WriteLine("表创建成功");
}*//*
//int rs = connDB.Database.ExecuteSqlCommand(strUpdateSQL,sqlParameters);
*//*int rs = connDB.Database.ExecuteSqlCommand(strInsertSQL);
if (rs > 0)
{
Console.WriteLine("表新增数据成功");
}*/
/*int rs = connDB.Database.ExecuteSqlCommand(strDropSQL);
if (rs.Equals(-1))
{
Console.WriteLine("表删除成功");
}*//*
}*/
//sqlQuery
string StrSELECT = @"select * from Admin where Id>=2 order by Id desc";
//求count
string strCount = @"select count(*) from Admin ";
using (EFClass2Entities db = new EFClass2Entities())
{
/*var rs = db.Database.SqlQuery<Admin>(StrSELECT);
foreach (var item in rs)
{
Console.WriteLine(item.Id+item.Account+item.Password);
}*/
var rs = db.Database.SqlQuery<int>(strCount).FirstOrDefault();
Console.WriteLine("一共{0}人", rs);
}
//修改 sql sqlcom 方法语法 sql
string StrSQL = @"select * from Admin where Id=2";
using (EFClass2Entities db = new EFClass2Entities())
{
Admin admin=db.Database.SqlQuery<Admin>(StrSQL).FirstOrDefault();
admin.Password = "789";
db.Entry<Admin>(admin).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
using (EFClass2Entities db = new EFClass2Entities())
{
//调用存储过程
getAdminById_Result rs= db.getAdminById(2).FirstOrDefault();
Console.WriteLine(rs.Id+rs.Account+rs.Password);
//新增
if (db.insertAdmin(4, "王五", "234")>0)
{
Console.WriteLine("新增成功");
}
}
}
}
}
2.Code First模式
通过代码自动创建模型和数据库
默认约定将命名为Id或类名+Id的属性视为表的键
3.主从表查询
3.1.延迟加载
需要的时候加载数据
EF默认支持延迟加载,有两种方法可关闭:
对于特定的导航属性,在定义属性时取消virtual
对于所有的导航属性,设置LazyLoadingEnabled为false
3.2.贪婪加载
关键字:Includel
一次连接查询后返回所有需要的相关数据的情况。导航属性——外键
3.3.显示加载
类似延迟加载,除非需要在代码中显式获取数据。在访问导航属性时,不会出现自动加载。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace demo4._4
{
internal class Program
{
static void Main(string[] args)
{
//延迟加载 使用时才会加载
//一个用户可以有多个订单
/*using (meixinEntities meixinTest=new meixinEntities())
{
var user=meixinTest.m_user.FirstOrDefault(p => p.email == "1@qq.com");
var orders=user.m_order;//查询该用户的所有订单
foreach (var item in orders)
{
Console.WriteLine("第一个订单的订单id:{0},订单地址{1}",item.id,item.address);
}
}*/
//贪婪加载 加载到内存里面,可在前端直接使用,不需要写<%%> 占内存
using(meixinEntities meixinTest1=new meixinEntities())
{
/*var users=meixinTest1.m_user.Include("m_order").FirstOrDefault(p=>p.email=="q@163.com");
foreach (var user in users.m_order)
{
Console.WriteLine("第一个订单的订单id:{0},订单地址{1}", user.id, user.address);
}*/
var users = meixinTest1.m_user.Include("m_order");
foreach (m_user user in users)
{
foreach (var item in user.m_order)
{
Console.WriteLine("第一个订单的订单id:{0},订单地址{1}", item.id, item.address);
}
}
}
//直接加载
using(meixinEntities meixinTest1 = new meixinEntities())
{
var user=meixinTest1.m_user.FirstOrDefault(p => p.email == "1@qq.com");
//显示加载从表
meixinTest1.Entry(user).Collection("m_order").Load();
foreach (var item in user.m_order)
{
Console.WriteLine("第一个订单的订单id:{0},订单地址{1}", item.id, item.address);
}
}
}
}
}
五、HttpModule与HttpHandler对象
1.HttpModule对象
过滤器
请求的必经之路
HttpApplication对象的属性包括Request、Response、Server和Session等
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace demo5
{
public class class2Model : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
}
public void Init(HttpApplication context)
{
//模型初始化 为HttpApplication 绑定两个事件
//在HttpApplication请求处理之前,触发事件
context.BeginRequest += Context_BeginRequest;
//在HttpApplication请求处理之前,触发事件
context.EndRequest += Context_EndRequest;
}
private void Context_EndRequest(object sender, EventArgs e)
{
HttpApplication httpApplication= sender as HttpApplication;
httpApplication.Response.Write("<p>HTTPModel结束处理请求</p>");
}
private void Context_BeginRequest(object sender, EventArgs e)
{
//重定向 web2
HttpApplication httpApplication= sender as HttpApplication;
//httpApplication.Response.Write("<p>HTTPModel开始处理请求</p>");
httpApplication.Context.RewritePath("WebForm2.aspx");
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
<system.webServer>
<modules>
<add name="class2Model" type="demo5.class2Model"/>
</modules>
</system.webServer>
</configuration>
2.HttpHandler对象
请求的终点
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace demo5
{
public class Class2Handel : IHttpHandler
{
//是否设置重用这个handel
public bool IsReusable => false;
public void ProcessRequest(HttpContext context)
{
//响应文本内容的信息
context.Response.ContentType = "text/plain";
context.Response.Write("今天");
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
<system.webServer>
<handlers>
<add name="class2Handel" path="*.aspx" verb="*" type="demo5.Class2Handel"/>
</handlers>
</system.webServer>
</configuration>
3.HttpHandler对象实现防盗链
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
namespace WebApplication3
{
public static class Graph
{
public static void CreateImages(HttpContext context, string checkCode)
{
int iwidth = (int)(checkCode.Length * 13);
System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 22);
Graphics g = Graphics.FromImage(image);
g.Clear(Color.White);
//定义颜色
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//定义字体
string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
Random rand = new Random();
//随机输出噪点
for (int i = 0; i < 50; i++)
{
int x = rand.Next(image.Width);
int y = rand.Next(image.Height);
g.DrawRectangle(new Pen(Color.LightGray, 0), x, y, 1, 1);
}
//输出不同字体和颜色的验证码字符
for (int i = 0; i < checkCode.Length; i++)
{
int cindex = rand.Next(7);
int findex = rand.Next(5);
Font f = new System.Drawing.Font(font[findex], 10, System.Drawing.FontStyle.Bold);
Brush b = new System.Drawing.SolidBrush(c[cindex]);
int ii = 4;
if ((i + 1) % 2 == 0)
{
ii = 2;
}
g.DrawString(checkCode.Substring(i, 1), f, b, 2 + (i * 12), ii);
}
//画一个边框
g.DrawRectangle(new Pen(ColorTranslator.FromHtml("#CCCCCC"), 0), 0, 0, image.Width - 1, image.Height - 1);
//输出到浏览器
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
context.Response.ClearContent();
//Response.ClearContent();
context.Response.ContentType = "image/gif";
context.Response.BinaryWrite(ms.ToArray());
g.Dispose();
image.Dispose();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Web;
namespace demo5._3
{
public class ImageHandel : IHttpHandler
{
public bool IsReusable => false;
public void ProcessRequest(HttpContext context)
{
//判断图片来源
Uri lastUrl=context.Request.UrlReferrer;//上一次请求的URL
Uri currentUrl=context.Request.Url;//上一次请求的URL
if (lastUrl.Host != currentUrl.Host || lastUrl.Port != currentUrl.Port)
{
//不是
string ErrorImage = context.Request.PhysicalApplicationPath + "Error/default.jpg";
context.Response.WriteFile(ErrorImage);
}
else
{
context.Response.WriteFile(context.Request.PhysicalPath);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.7.2"/>
<httpRuntime targetFramework="4.7.2"/>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
<system.webServer>
<handlers>
<add name="plink" verb="*" path="Images/*.jpg" type="demo5._3.ImageHandel"/>
</handlers>
</system.webServer>
</configuration>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="demo5._3.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>防盗链</h1>
<img src="Images/adv1.jpg"/>
<img src="Images/adv2.jpg"/>
<img src="Images/adv3.jpg"/>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="demo5._3._2.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>以下图片盗取别人网站</h1>
<img src="https://localhost:44373/Images/adv1.jpg"/>
<img src="https://localhost:44373/Images/adv2.jpg"/>
<img src="https://localhost:44373/Images/adv3.jpg"/>
</div>
</form>
</body>
</html>
4.HttpHandler对象实现验证码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using WebApplication3;
namespace demo5._3
{
/// <summary>
/// VerifCode 的摘要说明
/// </summary>
public class VerifCode : IHttpHandler,IRequiresSessionState
{
private Random randomSeed = new Random();
public void ProcessRequest(HttpContext context)
{
//产生一个5位的随机数
string strWord = "23456789ASDFGHJKZXCVBNMQWERTYUOP";
//把随机数给BMAP
string strCode = null;
for (int i = 0; i < 5; i++)
{
strCode += strWord[randomSeed.Next(0,strWord.Length)];
}
context.Session["vCode"] = strCode.ToLower();
Graph.CreateImages(context, strCode);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="demo5._3.WebForm2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>验证码</h1>
<table style="border:1px solid black;width:30%" >
<tr>
<td>用户名:</td>
<td>
<asp:TextBox ID="txtUser" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<asp:TextBox ID="txtPwd" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>验证码:</td>
<td>
<asp:TextBox ID="txtCode" runat="server"></asp:TextBox>
<asp:Image ID="Image1" runat="server" ImageUrl="~/VerifCode.ashx"/>
<asp:LinkButton ID="LinkButton1" runat="server">刷新</asp:LinkButton>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="提交" OnClick="Button1_Click" />
</div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
六、URL重写与AJAX技术
1.URL重写
将网页真实的URL隐藏起来,使用户通过相应的虚拟URL访问网页资源
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Detault.aspx.cs" Inherits="demo6.Detault" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<h1>重定向</h1>
<div>
<ul>
<li>
<a href="goods_1.html">服饰</a>
</li>
<li>
<a href="goods_2.html">美食</a>
</li>
</ul>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
namespace demo6
{
public class UelRewriteModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
}
public void Init(HttpApplication context)
{
//获取商品分类id good_1.html
context.BeginRequest += Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
HttpApplication httpApplication= sender as HttpApplication;
//获取请求的URL
string url=httpApplication.Request.RawUrl;
//截取
//判断一下请求
Regex regex=new Regex(@"\w+_\d+\.html");
if (regex.IsMatch(url))
{
//如果符合格式,就需要对url进行重写
int line = url.LastIndexOf("_");
int dot = url.LastIndexOf(".");
string id=url.Substring(line+1,dot-line-1);
string readyUrl="~/WebForm1.aspx?id="+id;
httpApplication.Server.Transfer(readyUrl);
}
}
}
}
注意: 正则表达式中的保留字符,如“.”,“?”,“^”,“$”等可以通过在前面添加反斜杠(如“\.”)来对这些字符进行转义,以匹配路径中的点
2.页面静态化技术
3.AJAX技术
异步获取后台数据和局部刷新
3.1.AJAX的四个组成部分:
XmlHttpRequest:AJAX技术的核心,用于提交请求和接收响应
DOM:用于解析响应到客户端的XML数据或其他文本数据
CSS:用于呈现解析后的数据
JavaScript:AJAX使用的编程语言
3.2.XmlHttpRequest对象
xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");IE浏览器
xmlHttpRequest=new window.XMLHttpRequest();其他浏览器
3.3. XmlHttpRequest对象的属性、方法和事件
3.3.1.readyState属性
readyState | |
值 | 状态说明 |
0 | 未初始化状态,此时创建了XmlHttpRequest对象,但尚未初始化 |
1 | 准备发送状态,此时已经调用了XmlHttpRequest对象的open()方法,并且准备将HTTP请求发送到服务器 |
2 | 已发送状态,此时已经通过XmlHttpRequest对象的send()方法将一个请求发送到服务器端,但尚未收到响应 |
3 | 正在接收状态,此时已经接收到HTTP响应的头部信息,但是消息体部分尚未完全接收 |
4 | 完成响应状态,此时已经完成了XmlHttpResponse响应的接收 |
3.3.2.responseText属性
readyState的值为0、1、2时,responseText属性包含一个空字符串
readyState的值为3时,responseText属性包含尚未完成的响应信息
readyState的值为4时,responseText属性包含完整的响应信息
3.3.3.responseXML属性
只有readyState的值为4时,responseXML属性才会存在值,并解析为XML文档,否则该属性值为NULL。如果响应的XML文档不符合规范或未完成响应回传,该属性值同样是NULL
3.3.4.responseBody属性
接收直接从服务器返回的未经解码的二进制数据,以无符号的字节数组形式保存
3.3.5.status属性
描述HTTP状态代码,只有当readyState的值为3或4时才能访问status属性,否则会引发异常
常用的status状态码 | |
1XX | 信息响应类,表示接收到请求并且继续处理 |
2XX | 处理成功响应类,表示动作被成功接收、理解和接受 |
3XX | 重定向响应类,为了完成指定的动作,必须接受进一步处理 |
4XX | 客户端错误,客户请求包含语法错误或执行错误 |
5XX | 服务端错误,服务器不能正确执行一个正确的请求 |
3.3.6.open()方法
XmlHttpRequest对象通过调用open(method,url,async,username,password)方法进行初始化工作。
method:该参数是必需的,用于指定发送HTTP请求的方式
url:指定XmlHttpRequest对象将请求发送到服务器响应的URL,该地址被自动解析为绝对地址
async:指定请求是否异步,若默认值是true,即默认为异步请求;若默认值为false,则发出同步请求
username和password:如果需要服务器验证访问用户,可以设置这两个参数,二者是可选的
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="demo6._3.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div id="xmlData">
<font>在这里显示数据信息</font>
</div>
<input type="button" value="更新数据" onclick="replaceData()"/>
</form>
<script type="text/javascript">
var xmlHttpRequest;
function replaceData() {
//1.ajax异步请求数据
if (window.ActiveXObject) {
//IE
xmlHttpRequest=ActiveXObject("Microsoft.XMLHTTP");
} else {
xmlHttpRequest = new XMLHttpRequest();//其他浏览器 0
}
//2.创建xmlhttp对象
//3.open()
//xmlHttpRequest.open("GET", "CreditCard.xml", true);//1
xmlHttpRequest.open("POST", "Handler1.ashx", true);//1
//如果是post请求下面这句必须加,不然拿不到数据
xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//4.send() 2
//xmlHttpRequest.send(null);//参数
xmlHttpRequest.send("a=3&b=4");//参数
//5.判断请求状态,替换数据
xmlHttpRequest.onreadystatechange = statusChange;
}
function statusChange() {
if (xmlHttpRequest.readyState == 4) {//返回当前文档的状态
if (xmlHttpRequest.status == 200) {
document.getElementById("xmlData").innerHTML = xmlHttpRequest.responseText;
}
}
}
</script>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace demo6._3
{
/// <summary>
/// Handler1 的摘要说明
/// </summary>
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//获取传进来的值
int a = Convert.ToInt32(context.Request.Form["a"]);
int b = Convert.ToInt32(context.Request.Form["b"]);
//做加法
int c = a + b;
//返回
context.Response.ContentType = "text/plain";
context.Response.Write(System.DateTime.Now + "a+b=" + c);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}