Blackbird 是一个开源的JavaScript库,提供了一种简单的记录日志的方式和一个控制台窗口,有了这个之后,你就可以抛弃alert() 了。支持下面的浏览器:
* Internet Explorer 6+
* Firefox 2+
* Safari 2+
* Opera 9.5
Blackbird 是一个开源的JavaScript库,提供了一种简单的记录日志的方式和一个控制台窗口,有了这个之后,你就可以抛弃alert() 了。支持下面的浏览器:
* Internet Explorer 6+
* Firefox 2+
* Safari 2+
* Opera 9.5
@@identity的作用是返回最后插入的标识值,所以有很多朋友使用它来获取插入数据后的标识符。
但有一点是需要注意的,@@identity返回的是最后的标识符,所以,要想正确的返回插入后的标识符,那么就必须保证,你想要的结果是最后的标识符,否则就会隐藏bug。
仔细阅读@@identity的注释:
在一条 Insert、Select INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 Insert 或 Select INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。
在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。
@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。
例如:创建表t和t1
drop table t
drop table t1
create table t
(
id int identity(1,1)primary key,
name char(10)
)
create table t1
(
id int identity(10,1)primary key,
name char(10)
)创建表t的触发器,作用是当有新的数据插入到表t时,t1也相应的插入一条数据。
—触发器
create trigger trigger_insert on t
for insert
as
insert into t1(name) select name from inserted然后,执行执行如下语句:
insert into t(name) values('me')
select @@identity这时候,你期望得到的结果是1,但其实返回的结果却是10。
使用时,这就是你要注意的问题啦。
论坛支持:www.help-doc.com
相关知识可以参考:http://www.help-doc.com/17/ShowForum.aspx
SQL Server 2005的帮助中的内容:
SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY 是相似的函数,因为它们都返回插入到标识列中的值。
IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。有关详细信息,请参阅 IDENT_CURRENT (Transact-SQL)。
SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
例如,有两个表 T1 和 T2,并且在 T1 上定义了 Insert 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。 该方案演示了两个作用域:在 T1 上的插入,以及在 T2 通过触发器的插入。
假设 T1 和 T2 都有标识列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 Insert 语句的最后返回不同的值。@@IDENTITY 将返回在当前会话中的任何作用域内插入的最后一个标识列的值。这是在 T2 中插入的值。SCOPE_IDENTITY() 将返回在 T1 中插入的 IDENTITY 值。这是在同一个作用域内发生的最后的插入。如果在任何 Insert 语句作用于作用域中的标识列之前调用 SCOPE_IDENTITY() 函数,则该函数将返回空值。
如果语句和事务失败,它们会更改表的当前标识,从而使标识列中的值出现不连贯现象。即使未提交试图向表中插入值的事务,也永远无法回滚标识值。例如,如果因 IGNORE_DUP_KEY 冲突而导致 Insert 语句失败,表的当前标识值仍然会增加。
存储过程————————————————————————————————


Create PROCEDURE dbo.sptestList

@strOptions varchar(200) = NULL,
@intID int = NULL,
@strOut nvarchar(50) = NULL OUTPUT

AS

SET NOCOUNT ON—不返回影响的行数
SET ANSI_WARNINGS OFF—不返警告

/* 信息列表 */
IF @strOptions='LIST' BEGIN

Select
id,
name,
subject,
Source
FROM test
Where ID <=@intID

SET @strOut = @strOut + 'out'
RETURN 50
END
GO


————————————————————————-

//StoredProcedure 调用存储过程
private void BindData2()
{
SQLConnection MyConn = new SQLConnection("Server=.;Database=mine;User=sa;Pwd=123;");
MyConn.Open();

SqlCommand MyCmd = new SqlCommand();
MyCmd.Connection = MyConn;
MyCmd.CommandType = CommandType.StoredProcedure;
MyCmd.CommandText = "sptestList";
string strOut = "in—";
int intReturn = 0;

SqlParameter[] paras =
{
new SqlParameter("@strOptions","LIST"),
new SqlParameter("@intID",100),
//长度一定需要
new SqlParameter("@strOut",SqlDbType.VarChar,200),
//用来存返回值,ReturnValue随便写都可以,但类型一定是整型(因为数据库只能返回整型)
new SqlParameter("ReturnValue",SqlDbType.Int)
};
paras[2].Direction = ParameterDirection.InputOutput;//设置 传入并传出
paras[2].Value = strOut;
paras[3].Direction = ParameterDirection.ReturnValue;//设置 返回值


foreach (SqlParameter par in paras)
{
MyCmd.Parameters.Add(par);
}

SqlDataAdapter MySda = new SqlDataAdapter(MyCmd);
DataTable MyDtb = new DataTable();
MySda.Fill(MyDtb);

strOut = paras[2].Value.ToString();//接收传出
intReturn = (int)paras[3].Value;//接收返回值
Response.Write("Out=" + strOut + "; Return=" + intReturn.ToString() + "<br>");

this.Repeater1.DataSource = MyDtb;
this.Repeater1.DataBind();

MyConn.Close();

}

//SqlDataAdapter 执行查询语句
private void BindData()
{
SqlConnection MyConn = new SqlConnection("Server=.;Database=mine;User=sa;Pwd=123;");

SqlCommand MyCmd = new SqlCommand("Select TOP 100 * FROM Test", MyConn);
SqlDataAdapter MySda = new SqlDataAdapter(MyCmd);
DataTable MyDtb = new DataTable();
MySda.Fill(MyDtb);

this.Repeater1.DataSource = MyDtb;
this.Repeater1.DataBind();

}

//ExecuteNonQuery 执行插入语句
protected void FInsert()
{
SqlConnection MyConn = new SqlConnection("Server=.;DataBase=mine;Uid=sa;Pwd=123;");

SqlCommand MyCmd = new SqlCommand("Insert INTO StudentInfo(StNo,StName) VALUES(124532,'A111ww')", MyConn);
MyConn.Open();
int i = MyCmd.ExecuteNonQuery();
Response.Write(i.ToString() + "<br>");
MyConn.Close();

}

//SqlDataReader
protected void FReader()
{
SqlConnection MyConn = new SqlConnection("Server=.;Database=mine;Uid=sa;Pwd=123");
MyConn.Open();
SqlCommand MyCmd = new SqlCommand("Select Top 10 StNo,StName from StudentInfo", MyConn);

SqlDataReader MyRead = MyCmd.ExecuteReader();

while (MyRead.Read())
{
Response.Write(MyRead["StNo"].ToString() + "—" + MyRead["StName"].ToString() + "<br>");
}

MyConn.Close();

}

//ExecuteScalar
protected void FScalar()
{

//<appSettings>
//<add key ="SqlConnStr" value="Server=.;DataBase=mine;Uid=sa;Pwd=123"/>
//</appSettings>
//SqlConnection MyConn = new SqlConnection(ConfigurationManager.AppSettings["SqlConnStr"]);
SqlConnection MyConn = new SqlConnection("Server=.;Database=mine;Uid=sa;Pwd=123");
MyConn.Open();
SqlCommand MyCmd = new SqlCommand("Select Total=Count(1) from StudentInfo", MyConn);

string MyS = MyCmd.ExecuteScalar().ToString();

Response.Write(MyS + "<br>");

MyConn.Close();

}

//连接Access
private void BindAccess()
{
//<add key="AccessConString" value="App_Data/db.mdb" />
string strAccessPath = ConfigurationManager.AppSettings["AccessConString"].ToString();
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath(strAccessPath));
con.Open();
OleDbDataAdapter oda = new OleDbDataAdapter("Select * From Result", con);
DataTable Dtb = new DataTable();
oda.Fill(Dtb);

this.Repeater1.DataSource = Dtb;
this.Repeater1.DataBind();

//———————-二—————————–
//string constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("App_Data/db.mdb");
//OleDbConnection con = new OleDbConnection(constr);
//string cmdstr = "Select * FROM Result";
//con.Open();
//OleDbCommand cmd = new OleDbCommand(cmdstr, con);
//OleDbDataReader dr = cmd.ExecuteReader();
}


//OleDbCommand 执行语句
protected void Button1_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source="
+ Server.MapPath(ConfigurationManager.AppSettings["OleDbConnPathStr"]));
con.Open();

OleDbCommand cmd = new OleDbCommand("Insert Into Products(Product_Id,Title,Spec,Content) Values('ww123','成功添加01','100*1','真的成功了')", con);

cmd.ExecuteNonQuery();

con.Close();
con.Dispose();

BindData();

}

//OleDbDataAdapter 读取数据
protected void Button2_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source="
+ Server.MapPath(ConfigurationManager.AppSettings["OleDbConnPathStr"]));
con.Open();

OleDbDataAdapter odad = new OleDbDataAdapter("Select * From Products Where ID=123", con);

DataTable dtb = new DataTable();
odad.Fill(dtb);

if (dtb.Rows.Count > 0)
{
DataRow row = dtb.Rows[0];

this.Label.Text = row["ID"].ToString() + "—" + row["Title"].ToString();
}

con.Close();
con.Dispose();
}

//OleDbCommand 执行语句(参数化)
protected void Button3_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source="
+ Server.MapPath(ConfigurationManager.AppSettings["OleDbConnPathStr"]));
con.Open();

OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Insert Into Products(Product_Id,Title,Spec,Content) Values(@Product_Id,@Title,@Spec,@Content)";

OleDbParameter[] paras = {
new OleDbParameter("@Product_Id",OleDbType.VarChar),
new OleDbParameter("@Title",OleDbType.VarChar),
new OleDbParameter("@Spec",OleDbType.VarChar),
new OleDbParameter("@Content",OleDbType.VarChar)
};

paras[0].Value = "qq123";
paras[1].Value = "qq成功添加";
paras[2].Value = "10*10";
paras[3].Value = "qq真的成功了";

foreach (OleDbParameter para in paras)
{
cmd.Parameters.Add(para);
}

cmd.ExecuteNonQuery();

con.Close();
con.Dispose();

BindData();
}
当执行Update、Insert 和 Delete时,SQLHelper的ExecuteNonQuery方法能正确的返回受影响的行数,但执行Select时返回值却总是-1,今天上 MSDN查了下SQLCommand.ExecuteNonQuery方法,上边的解释是:
引用内容那上述现象的出现就是正常的了,呵呵。
MSDN地址:http://msdn2.microsoft.com/zh-cn/library/system.data.sqlclient.sqlcommand.executenonquery(VS.80).aspx
很少写这些,看了1.2.3版本的改进,确实佩服,很方便.
1.绑定事件
(1)
$("p").bind("click", function(e){});(2)
$("p").click(function() {})2.删除事件
(1)删除特定事件
$("div").unbind("click");(2)删除所有事件
$("div").unbind();3.触发事件
(1)trigger方法 触发特定元素事件
$("div").trigger('click');(2)triggerHandler方法 与trigger方法相似,但不触发浏览器默认事件,如focus事件,使用此方法,将会阻止焦点到元素上
$("input").triggerHandler("focus");
4.特殊事件
(1)one(string event,function data)
此事件只执行一次则被删除
$("p").one("click", function(){
alert("test");
});
(2)hover(over, out)
切换mouSEOver与mouSEOut事件
$("td").hover(
function () {
$(this).addClass("hover");
},
function () {
$(this).removeClass("hover");
}
);
可用unbind mouseover与mouseout方法来删除此事件
(3)toggle(oldclick,newclick)
切换执行click事件
$("li").toggle(
function () {
$(this).css("list-style-type", "disc")
.css("color", "blue");
},
function () {
$(this).css({"list-style-type":"", "color":""});
}
);可用unbind click方法来删除此事件
5. 1.2.3版本新增功能
(1)事件命名空间(便于管理)
实际使用方面:
1.当不需要全部事件,删除特定2个以上的事件.
示例:
$("div").bind("click.plugin",function() {} );
$("div").bind("mouseover.plugin", function(){});
$("div").bind("dblclick", function(){});
$("button").click(function() {$("div").unbind(".plugin"); })在事件名称后面加命名空间,在删除事件时,只需要指定命名空间即可.以上代码执行以后,dbclick仍然存在.
(2)相同事件名称,不同命名的事件执行方法
示例:
$("div").bind("click", function(){ alert("hello"); });
$("div").bind("click.plugin", function(){ alert("goodbye"); });
$("div").trigger("click!"); // alert("hello") only以上trigger方法则根据事件名称来执行事件.
简单的写几句.以上的几个方法还是非常实用方便的
验证码的页面可能由于验证码不清楚,单击需要获得新的验证码
服务器端用C#实现如下:
/// <summary>
/// 验证码类,用于生成验证码
/// </summary>
public static class ValidateCode
{
private static string CreateRandomCode(int codeCount)
{
string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z";
string[] allCharArray = allChar.Split(',');
string randomCode = "";
int temp = -1;
Random rand = new Random();
for (int i = 0; i < codeCount; i++)
{
if (temp != -1)
{
rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
}
int t = rand.Next(35);
if (temp == t)
{
return CreateRandomCode(codeCount);
}
temp = t;
randomCode += allCharArray[t];
}
return randomCode;
}
public static MemoryStream CreateImage(out string checkCode)
{
//生成随机数
checkCode = CreateRandomCode(4);
int iwidth = (int)(checkCode.Length * 13.5);
System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 20);
Graphics g = Graphics.FromImage(image);
Font f = new System.Drawing.Font("Arial", 12, System.Drawing.FontStyle.Bold);
Brush b = new System.Drawing.SolidBrush(Color.Black);
//g.FillRectangle(new System.Drawing.SolidBrush(Color.Blue),0,0,image.Width, image.Height);
g.Clear(Color.White);
g.DrawString(checkCode, f, b, 3, 3);
Pen blackPen = new Pen(Color.Black, 0);
Random rand = new Random();
for (int i = 0; i < 3; i++)
{
int y = rand.Next(image.Height);
g.DrawLine(blackPen, 0, y, image.Width, y);
}
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
g.Dispose();
image.Dispose();
return ms;
}
}
[/code]
使用Asp.net MVC实现的Controller调用验证码的Action如下:
没有生成中间gif,jpg文件
[code]
/// <summary>
/// 获得验证码
/// </summary>
public void GetValidateCode()
{
try
{
//生成验证码
string validateCode;
Session["ValidateCode"] = "";
//生成验证码图片
MemoryStream ms = ValidateCode.CreateImage(out validateCode);
ViewData["Code"] = ms;
//保存到Session
Session["ValidateCode"] = validateCode;
Response.ClearContent();
Response.ContentType = "image/Gif";
Response.BinaryWrite(ms.ToArray());
}
catch (Exception e)
{
Response.Write("验证码生成失败!错误消息:" + e.Message);
}
}
页面代码:
<script language="javascript" type="text/javascript">
//获得验证码
function GetCode()
{
//注意后面一定要加随机数,这样<img>才能更新为新的验证码
$("#validateImg").attr("src","/user/GetValidateCode?sd="+Math.random());
}
</script>
<a id="getCode" href="javascript:GetCode();"><img id="validateImg" src="/user/GetValidateCode" alt="点击获得验证码" /></a>
序列化和反序列化我们可能经常会听到,其实通俗一点的解释,序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用。
我想最主要的作用有:
1、在进程下次启动时读取上次保存的对象的信息
2、在不同的AppDomain或进程之间传递数据
3、在分布式应用系统中传递数据
……
在C#中常见的序列化的方法主要也有三个:BinaryFormatter、SoapFormatter、XML序列化
本文就通过一个小例子主要说说这三种方法的具体使用和异同点
这个例子就是使用三种不同的方式把一个Book对象进行序列化和反序列化,当然这个Book类首先是可以被序列化的。至于怎么使一个类可以序列化可以参见:C#强化系列文章一:ViewState使用兼谈序列化
Book类
using System;
using System.Collections;
using System.Text;
namespace SerializableTest
{
[Serializable]
public class Book
{
public Book()
{
alBookReader = new ArrayList();
}
public string strBookName;
[NonSerialized]
public string strBookPwd;
private string _bookID;
public string BookID
{
get { return _bookID; }
set { _bookID = value; }
}
public ArrayList alBookReader;
private string _bookPrice;
public void SetBookPrice(string price)
{
_bookPrice = price;
}
public void Write()
{
Console.WriteLine("Book ID:" + BookID);
Console.WriteLine("Book Name:" + strBookName);
Console.WriteLine("Book Password:" + strBookPwd);
Console.WriteLine("Book Price:" + _bookPrice);
Console.WriteLine("Book Reader:");
for (int i = 0; i < alBookReader.Count; i++)
{
Console.WriteLine(alBookReader[i]); [Page]
}
}
}
}
这个类比较简单,就是定义了一些public字段和一个可读写的属性,一个private字段,一个标记为[NonSerialized]的字段,具体会在下面的例子中体现出来
一、BinaryFormatter序列化方式
1、序列化,就是给Book类赋值,然后进行序列化到一个文件中
Book book = new Book();
book.BookID = "1";
book.alBookReader.Add("gspring");
book.alBookReader.Add("永春");
book.strBookName = "C#强化";
book.strBookPwd = "*****";
book.SetBookPrice("50.00");
BinarySerialize serialize = new BinarySerialize();
serialize.Serialize(book);2、反序列化
BinarySerialize serialize = new BinarySerialize();
Book book = serialize.DeSerialize();
book.Write();3、测试用的
BinarySerialize类
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializableTest
{
public class BinarySerialize
{
string strFile = "c:\book.data";
public void Serialize(Book book)
{
using (FileStream fs = new FileStream(strFile, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, book);
}
}
public Book DeSerialize()
{
Book book;
using (FileStream fs = new FileStream(strFile, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter(); [Page]
book = (Book)formatter.Deserialize(fs);
}
return book;
}
}
}
主要就是调用System.Runtime.Serialization.Formatters.Binary空间下的 BinaryFormatter类进行序列化和反序列化,以缩略型二进制格式写到一个文件中去,速度比较快,而且写入后的文件已二进制保存有一定的保密效 果。
调用反序列化后的截图如下:
也就是说除了标记为NonSerialized的其他所有成员都能序列化
二、SoapFormatter序列化方式
调用序列化和反序列化的方法和上面比较类似,我就不列出来了,主要就看看SoapSerialize类
SoapSerialize类
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace SerializableTest
{
public class SoapSerialize
{
string strFile = "c:\book.soap";
public void Serialize(Book book)
{
using (FileStream fs = new FileStream(strFile, FileMode.Create))
{
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(fs, book);
}
}
public Book DeSerialize()
{
Book book;
using (FileStream fs = new FileStream(strFile, FileMode.Open))
{
SoapFormatter formatter = new SoapFormatter();
book = (Book)formatter.Deserialize(fs);
}
return book;
}
}
}
主要就是调用System.Runtime.Serialization.Formatters.Soap空间下的SoapFormatter 类进行序列化和反序列化,使用之前需要应用 System.Runtime.Serialization.Formatters.Soap.dll(.net自带的)
序列化之后的文件是Soap格式的文件(简单对象访问协议(Simple Object Access Protocol,SOAP),是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还 支持从消息系统到远程过程调用(RPC)等大量的应用程序。SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来 使用Internet上各种不同操作环境中的分布式对象。) [Page]
调用反序列化之后的结果和方法一相同
三、XML序列化方式
调用序列化和反序列化的方法和上面比较类似,我就不列出来了,主要就看看XmlSerialize类
XmlSerialize类
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
namespace SerializableTest
{
public class XmlSerialize
{
string strFile = "c:\book.xml";
public void Serialize(Book book)
{
using (FileStream fs = new FileStream(strFile, FileMode.Create))
{
XmlSerializer formatter = new XmlSerializer(typeof(Book));
formatter.Serialize(fs, book);
}
}
public Book DeSerialize()
{
Book book;
using (FileStream fs = new FileStream(strFile, FileMode.Open))
{
XmlSerializer formatter = new XmlSerializer(typeof(Book));
book = (Book)formatter.Deserialize(fs);
}
return book;
}
}
}
从这三个测试类我们可以看出来其实三种方法的调用方式都差不多,只是具体使用的类不同
xml序列化之后的文件就是一般的一个xml文件:
book.xml
<?xml version="1.0"?>
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<strBookName>C#强化</strBookName>
<strBookPwd>*****</strBookPwd>
<alBookReader>
<anyType xsi:type="xsd:string">gspring</anyType>
<anyType xsi:type="xsd:string">永春</anyType>
</alBookReader>
<BookID>1</BookID>
</Book>输出截图如下:
也就是说采用xml序列化的方式只能保存public的字段和可读写的属性,对于private等类型的字段不能进行序列化
关于循环引用:
比如在上面的例子Book类中加入如下一个属性:
public Book relationBook;
在调用序列化时使用如下方法:
Book book = new Book();
book.BookID = "1"; [Page]
book.alBookReader.Add("gspring");
book.alBookReader.Add("永春");
book.strBookName = "C#强化";
book.strBookPwd = "*****";
book.SetBookPrice("50.00");
Book book2 = new Book();
book2.BookID = "2";
book2.alBookReader.Add("gspring");
book2.alBookReader.Add("永春");
book2.strBookName = ".NET强化";
book2.strBookPwd = "*****";
book2.SetBookPrice("40.00");
book.relationBook = book2;
book2.relationBook = book;
BinarySerialize serialize = new BinarySerialize();
serialize.Serialize(book);这样就会出现循环引用的情况,对于BinarySerialize和 SoapSerialize可以正常序列化(.NET内部进行处理了),对于XmlSerialize出现这种情况会报错:"序列化类型 SerializableTest.Book 的对象时检测到循环引用。"
# //先在项目中添加System.Web.Extensions引用
# //using System.Web.Script.Serialization;
# JavaScriptSerializer serializer = new JavaScriptSerializer();
# Dictionary<string, object> json = (Dictionary<string, object>)serializer.DeserializeObject(
# "{name: 'zswang', forum: 'c#'}");
# object value;
# if (json.TryGetValue("name", out value))
# Console.WriteLine(value); // 输出:zswang
$() function
$(selector) 等价于 JQuery(selector),用来选取一组DOM Elements。返回的是一组预定义的JavaScript 对象,这些对象不仅封装了DOM element而且提供了许多有用的方法,以作用于这些elements。
使用CSS Selectors
1. 可以使用的selectors如下表所示:
Selector Description
* 所有元素
E 所有标签名(tag name)称为E的元素
E F 所有标签名为F,且为标签E的子元素的元素(含孙子元素…)
E>F 所有标签名为F,且为标签E直接子元素的元素
E+F 所有标签名为F,且相邻兄弟元素标签名为E的元素
E~F 所有标签名为F,且兄弟元素标签名为E的元素
E:has(F) 所有标签名为E, 且包含至少一个标签名为F元素的元素
E.C 所有标签名为E, 且包含类名称为C的元素
E#I 所有标签名为E, 且id为I的元素
E[A] 所有标签名为E,且拥有属性名为A的元素,属性值任意
E[A=V] 所有标签名为E,且拥有属性名为A,属性值为V的元素
E[A^=V] 所有标签名为E, 且属性名为A,属性值以V开始的元素
E[A$=V] 所有标签名为E,且属性名为A,属性值以V结尾的元素
E[A*=V] 所有标签名为E,且属性名为A,属性值包含V的元素
2. 使用position过滤器
可以使用的position过滤器包括:

Selector Description
:first 页面中第一个得到满足的元素. 如:li a:first 返回第一个 li 项下的链接
:last 页面中最后一个得到满足的元素。如:li a:last 返回最后一个 li 项下的链接
:first-child 第一个子元素 如:li:first-child 返回 所有作为子元素的li 项中的第一li 元素
:last-child 最后一个子元素. 如: li:last-child 返回 作为子元素的li 项中的最后一个 li 元素
:only-child 返回所有没有兄弟元素的元素(这个元素只作为其它元素的子元素存在)
:nth-child(n) 返回第n个子元素. 如:li:nth-child(2) 返回 所有作为子元素的 li 项的第二个.
:nth-child(even|odd) 返回偶数(Even) 或奇数(Odd) 子元素. 如:li:nth-child(even) 返回所有作为子元素的li项的偶数元素.
:nth-child(Xn+Y) 返回Xn+Y计算结果的第n个子元素.如果Y为0,则被忽略. 如:li:nth-child(3n) 返回所有作为子元素的li项的每第3n个元素.
:even and :odd 返回偶数(Even)或奇数(odd)个子元素。不同于nth-child系列,这个匹配所有页面中的元素(而不仅仅是作为子元素的元素).
:eq(n) 返回序号等于n的元素(从0基数哦)
:gt(n) 返回序号大于n的元素,不包括第n个元素。
:lt(n) 返回序号小于n的元素,不包括第n个元素。
在应用上述表时注意:所有nth-child中都是从1开始计数的,如nth-child(3n)返回第3, 6, 9个元素。其他的还是从0计数。
3. 使用JQuery自定义的过滤器
Selector Description
:animated 选择那些目前在动画效果控件中的元素
:button 选择所有button元素(input[type=submit], input[type=reset],
input[type=button], or button).
:checkbox 选择checkbox元素(input[type=checkbox]).
:checked 选择那些被checked的checkbox或radio button(supported by CSS).
:contains(foo) 选择包含文字foo的元素(注意区分文字的大小写哦).
:disabled 选择form元素中被disabled的元素(supported by CSS).
:enabled 选择form元素中被enabled的元素 (supported by CSS).
:file 选择所有file元素(input[type=file]).
:header 选择所有header元素; 例如:从<h1>到<h6> 的元素.
:hidden 选择隐藏的元素.如:$("li:hidden").css("visibility", "visible");将隐藏的li显示出来
:image 选择所有image元素 (input[type=image]).
:input 选择所有form元素(input, select, textarea, button).
:not(filter) 使指定filter取反.如:$("li:not(hidden)").css("visibility", "hidden");将所有没有隐藏的 li 隐藏掉
:parent 选择所有包含子元素的元素(including text), 空元素不算(如包含空格的).
:password 选择password元素(input[type=password]).
:radio 选择radio元素 (input[type=radio]).
:reset 选择reset buttons (input[type=reset] or button[type=reset]).
注意:
1) 过滤器可以连接起来使用,如:
:checkbox:checked:enabled
选择那些处于enabled状态并被选中的checkbox。
2) :not(filter) 只能用于过滤选择器(filter selectors)而不能用于查找选择器(find selectors)。如:
div p:not(:hidden)是合法的,
而 div :not(p:hidden) 就不行。
简单区分的方法是,:not只能用在以:(冒号) ,[(中括号)开始的filter selectors,其他的都不行。
另外,可以使用XPath Selectors,这个要使用插件,可以从这里下载。