分析thinkphp的model 表切换

Continue Read..

入口和前期铺垫就不说了,有兴趣的朋友自己看。

主要是在model的同一个函数内操作不同表碰到的问题,所以看下源代码,分析thinkphp的处理流程。

案例:直接从action里面使用model

class testaction extends action {
    public function cb(){
	$db = new gamesmodel();
	$db->setUserActiveGame();     }

}
上面是action,下面是model

 

class gamesmodel extends model {
    protected $connection = 'DB_GAMES';
    public function setUserActiveGame(){
		$activegame = array(
		    'user_id'=> $userid,
			'login_name'=>$username,
			'game_id' => $gameid,
			'server_id'=> $serverid,
			);
		//这里的params是db类初始化默认参数
		$params = array(
		    'autoCheckFields' => false,   //在同一个db类的生命周期内操作多张表,一定要关闭字段检测,否则字段数据会被model的_facade函数unset掉
	        'trueTableName' => 'table1',  //指定表名
		);
				
		$status1 = $this->db('1','DB_GAMES',$params)->data($activegame)->add();


		$acdata = array(
			'login_name'=>$username,
			'user_id'=>$userid,
			);
		$where = 'sn=\''.$sn.'\' AND status <> 1';
		$params2 = array(
			'autoCheckFields' => false,  //同params
			'trueTableName' => 'table2',
			);
		$status2 = $this->db('1','DB_GAMES',$params2)->where($where)->save($acdata);
		

	}

一步步看,首先action里面new了gamesmodel, gamesmodel继承model,model的构造函数开始执行,

public function __construct($name='',$tablePrefix='',$connection='') {
		// 模型初始化
		$this->_initialize();
		// 获取模型名称
		if(!empty($name)) {
			if(strpos($name,'.')) { // 支持 数据库名.模型名的 定义
				list($this->dbName,$this->name) = explode('.',$name);
			}else{
				$this->name   =  $name;
			}
		}elseif(empty($this->name)){
			$this->name =   $this->getModelName();//获取到model的名称,这里是games
		}
		// 设置表前缀
		if(is_null($tablePrefix)) {// 前缀为Null表示没有前缀
			$this->tablePrefix = '';
		}elseif('' != $tablePrefix) {
			$this->tablePrefix = $tablePrefix;
		}else{
			$this->tablePrefix = $this->tablePrefix?$this->tablePrefix:C('DB_PREFIX');
		}

		// 数据库初始化操作
		// 获取数据库操作对象
		// 当前模型有独立的数据库连接信息
		//$this->db(0,empty($this->connection)?$connection:$this->connection);
	}

这里我用$m代表gamemodel的实例化对象,model类的构造函数设置了

$m->name=games

$m->tablePrefix=xxx//表前缀

在看setUserActiveGame(),$this->db('1','DB_GAMES',$params)->data($activegame)->add();这一句,

链式操作,实现方式很简单,在每个函数的最后return $this,返回自己的对象即可,我们一个一个来看

$this->db('1','DB_GAMES',$params),第一个参数是链接编号,第二个是配置文件的链接数组,第三个参数是实例化db类的带入参数,

/**
	 +----------------------------------------------------------
	 * 切换当前的数据库连接
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param integer $linkNum  连接序号
	 * @param mixed $config  数据库连接信息
	 * @param array $params  模型参数
	 +----------------------------------------------------------
	 * @return Model
	 +----------------------------------------------------------
	 */
	public function db($linkNum,$config='',$params=array()){
		if(''===$linkNum && $this->db) {
			return $this->db;
		}
		static $_linkNum    =   array();
		static $_db = array();
		if(!isset($_db[$linkNum]) || (isset($_db[$linkNum]) && $config && $_linkNum[$linkNum]!=$config) ) {
			// 创建一个新的实例
			if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数
				$config  =  C($config);
			}
			$_db[$linkNum]            =    db::getInstance($config);//获取db类的实例
		}elseif(NULL === $config){
			$_db[$linkNum]->close(); // 关闭数据库连接
			unset($_db[$linkNum]);
			return ;
		}
		if(!empty($params)) {
			if(is_string($params))    parse_str($params,$params);
			foreach ($params as $name=>$value){
				$this->setProperty($name,$value);     //设置db类的属性
			}
		}
		// 记录连接信息
		$_linkNum[$linkNum] =   $config;
		// 切换数据库连接
		$this->db   =    $_db[$linkNum];
		$this->_after_db();
		// 字段检测
		if(!empty($this->name) && $this->autoCheckFields)    $this->_checkTableInfo();//这里请看前面的函数里,在db函数的第三个参数里关闭了字段检测,重点
		return $this;
	}

注意$_db[$linkNum]            =    db::getInstance($config);,他获取了db类的实例,并在后面$this->db   =    $_db[$linkNum];

也即$m->db是db类的实例,是一个object,

继续看db::getInstance($config);

public static function getInstance() {
		$args = func_get_args();//获取参数
		return get_instance_of(__CLASS__,'factory',$args);//common.php中定义get_instance_of,这里__CLASS__是db
	}

继续看get_instance_of(__CLASS__,'factory',$args);

function get_instance_of($name, $method='', $args=array()) {
	static $_instance = array();
	$identify = empty($args) ? $name . $method : $name . $method . to_guid_string($args);//数据库链接编号验证字符串
	if (!isset($_instance[$identify])) {
		if (class_exists($name)) {
			$o = new $name();  //实例化db类
			if (method_exists($o, $method)) {  //调用method
				if (!empty($args)) {
					$_instance[$identify] = call_user_func_array(array(&$o, $method), $args);//db->factory()
				} else {
					$_instance[$identify] = $o->$method();
				}
			}
			else
				$_instance[$identify] = $o;//放入db对象的$_instance[$identify],
		}
		else
			halt('_CLASS_NOT_EXIST_' . ':' . $name);
	}
	return $_instance[$identify];//返回db对象
}

这里得到了db对象,他又调用了factory(),去看看

明天在写,下班闪人

2013-02-01 

public function factory($db_config='') {
        // 读取数据库配置
        $db_config = $this->parseConfig($db_config);
        if(empty($db_config['dbms']))
            throw_exception('_NO_DB_CONFIG_');
        // 数据库类型
        $this->dbType = strtolower($db_config['dbms']);
        $class = 'db'. $this->dbType;
        if(is_file(CORE_PATH.'lib/'.$class.'.class.php')) {
            // 内置驱动
            $path = CORE_PATH;
        }
        // 检查驱动类
        if(require_cache($path.'lib/'.$class.'.class.php')) {
            $db = new $class($db_config);                       //这里配置文件使用的mysql类型,实例化了dbmysql类
            // 获取当前的数据库类型
            if( 'pdo' != strtolower($db_config['dbms']) )
                $db->dbType = strtoupper($this->dbType);
            else
                $db->dbType = $this->_getDsnType($db_config['dsn']);
            if(APP_DEBUG)  $db->debug    = true;                 //debug开关,用于记录各种调试信息
        }else {
            // 类没有定义
            throw_exception('_NOT_SUPPORT_DB_'.': ' . $db_config['dbms']);
        }
        return $db;                                              //返回dbmysql对象
    }
ok,到这里,model层的具体实例化算是完成了,从头理一下,

$this->db('1','DB_GAMES',$params),调用model类的db方法,db函数里面的db::getInstance($config)获取了dbmysql类的实例,

这时候在gamesmodel里面var_dump($this);,可以看到这个对象是model类,dbmysql对象被当成model对象的一个元素,

即$m->db,

 

这样,具体的数据操作层的对象就实例化完毕了,等待下一步动作,$m接收后面的链式操作,处理具体事务了。

例如model中的query方法

public function query($sql,$parse=false) {
		if(!is_bool($parse) && !is_array($parse)) {
            $parse = func_get_args();
            array_shift($parse);
        }
		$sql  =   $this->parseSql($sql,$parse);
		return $this->db->query($sql);     //$this->db前面讲过,就是dbmysql的对象了(根据具体情况来,你配置的mongo,那就是mongo的实例对象!)
	}

以上就是具体的流程了,下面来说一下一个另外的东西,

在gamesmodel里面的setUserActiveGame()里面,操作了非games表的table1和table2,往这2张不同的表插入数据。

所以在$this->db('1','DB_GAMES',$params)的时候,传入了第三个参数,设置了表名和关闭掉了字段类型检测,

在model类的db()里面if(!empty($this->name) && $this->autoCheckFields)    $this->_checkTableInfo();

如果开启(默认开启),会缓存当前模型表的字段结构,存入$this->fields

在后面的插入操作会检测插入的字段是否符合缓存的模型表结构(model类的_facade()方法),不符的字段会被unset掉,

所以不设置$params的话,在实例化的时候就会自动开启字段检测,缓存表字段了,

$params = array(
				'fields' => '',
				'autoCheckFields' => false,
				'trueTableName' => $table,
		);

后面2张表的insert操作的字段会被全部unset掉,插入一条只有主键的空记录!!!

这样解决

 

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

jquery 如何获取 iframe下 div中的内容

Continue Read..
                js:
	        var div = window.frames["frameName"].document.getElementById("divID").innerHTML;

	        jQuery:
	        $("#frameID").contents().find("divID").html()
                $(window.frames["ifr"].document.body).css({ "overflow": "hidden" });
	        $(window.frames["ifr"].document.body).css({ "border": "none" });
	        $(window.frames["ifr"].document.body).css({ "overflow": "hidden" });
	        $(window.frames["ifr"].document.body).css({ "border": "none" });

	        $("#ifr").contents().find("h1").css({ "text-align": "center" });
	        $("#ifr").contents().find(".tableview").css({ "width": "100%", "margin-top": "10px" });
	        $("#ifr").contents().find(".tableview th,.tableview td").css({ "padding": "3px" });

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

【Jquery】$.getJSON跨域返回值

Continue Read..

公司弄了个提交的东西...用$.getJSON写的...在传参什么的都正常..php也执行正常...就是返回的时候没得返回值

$.getJSON(

   hrefValue+"域名?callback=?",

  { name: encodeURIComponent(name), phone:phone, area:encodeURIComponent('区域'), sjname:encodeURIComponent('类型')},

   function(data){

  if(data.status==1)

  {   

      $("#kfname").val("");

      $("#kftel").val("");

      alert('提交成功!');

  }

  } 

); 

$arr = array("message"=>"ok","status"=>"1");

echo $_GET['callback'].'('.json_encode($arr).')'; 

主要就是标红的这里...只有这样写才有返回值

点击查看原图

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

浏览器内核

Continue Read..
浏览器核心部分是“Rendering Engine”,称为“浏览器内核”,也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。

Trident(IE内核):实际上是一款开放的内核,其接口内核设计的相当成熟,因此才有许多采用IE内核而非IE的浏览器涌现。如360浏览器、Maxthon(遨游)、The World(世界之窗)、TT(腾讯)、GreenBrowser(绿色浏览器)、AvantBrowser等浏览器采用该内核。

Gecko(Fx内核):Netscape6采用的内核,后来的Mozilla FireFox(火狐浏览器)也采用了该内核,该内核特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。

Presto(Opera内核):欧朋Opera浏览器采用的内核,该内核在2003年的Opera7中首次被使用,该款引擎的特点就是渲染速度的优化达到了极致,也是目前公认网页浏览速度最快的浏览器内核,然而代价是牺牲了网页的兼容性。

Webkit(开源):苹果公司自己的内核,也是苹果的Safari浏览器使用的内核。Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍生而来,它们都是自由软件,在GPL条约下授权,同时支持BSD系统的开发。所以Webkit也是自由软件,同时开放源代码。在安全方面不受IE、Firefox的制约,所以Safari浏览器在国内还是很安全的。

WebCore:是苹果公司开发的排版引擎,它是在另外一个排版引擎“KHTML”的基础上而来的。苹果电脑于2002年采纳了KHTML。

KHTML:是HTML网页排版引擎之一,由KDE所开发。该引擎拥有速度快捷的优点,但对错误语法的容忍度则比Mozilla产品所使用的Gecko引擎小。

Geckos:使用该内核的浏览器如Firefox浏览器:Mozilla Firefox,非正式中文名称火狐,是一个开源网页浏览器,使用Geckos引擎(即非ie内核),由Mozilla基金会与数百个志愿者所开发。原名“Phoenix”(凤凰),之后改名“Mozilla Firebird”(火鸟),再改为现在的名字。 Firefox是Mozilla基金会开发的一个轻便、快速、简单与高扩充性的浏览器。
Redfox浏览器:Redfox是经过定制后的绿色安装增强FireFox版本,其特点如下:采用正式版代码编译优化,支持部分非标准网站;不写注册表,可以方便的拷贝移动或者删除;加入了大量常用扩展供大家在安装的时候选择;对原有FireFox的错误和不方便设置进行了修正;调整了部分次参数进一步加快FireFox的浏览速度。
Madfox浏览器:是一个基于Firefox的浏览器。Firefox是一个非常优秀的浏览器,但是由于我们周围有很多不符合互联网标准的网站,从而在很大程度上阻碍了Firefox的推广。对于标准和非标准,无论是技术还是非技术层面,都有着非常激烈的争论。Madfox项目的目的,是希望仅从技术的角度出发,通过扩展Firefox,尝试去兼容不符合标准和规范的网站。
DR.Orca浏览器:是一款方便、实用的单窗口多页面浏览器。它基于Geckos引擎,除了拥有Gecko核心浏览器的浏览速度快的特点,还具备了时下各种主流的浏览器所具备的很多功能,如支持鼠标手势、强大的过滤功能、群组收藏功能等。Dr.Orca还提供了多语言选择,其中包括了简体中文。
K-Meleon浏览器:是一个可自定义的,轻型的用于WIN32(WINDOWS)平台的网络浏览器,基于Geckos设计引擎。K-Meleon是在遵循GNU公共许可证下的开放源代码的自由软件。
K-Meleon浏览器:是一个可自定义的,轻型的用于WIN32(WINDOWS)平台的网络浏览器,基于Geckos设计引擎。K-Meleon是在遵循GNU公共许可证下的开放源代码的自由软件。

Presto内核:Opera为来自挪威的一个极为出色的浏览器,具有速度快、节省系统资源、订制能力强、安全性高以及体积小等特点

Kestrel内核:Opera 9.5 之后版本,最新正式版Opera 9.5使用了Kestrel内核,全新 的内核使Opera 9.5速度更快,且它支持开放网页标准。其中Opera Link功能可以使用户自由连接使用Opera浏览器的设备。

【Thinkphp】thinkphp实现多图片批量上传

Continue Read..

先上图看看

点击查看原图

点击查看原图

 

html代码

 <!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>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>发布出售信息 </title>

<script src="http://user.xtfw.cn/gonggong/ershou/js/jquery_last.js" type="text/javascript"></script>

</head>

<body>

    <div class="options xspace10">

<span class="column des">上传照片:</span>

<span>

<input type="hidden" name="upimgs" id="uploadimgs" value=""/>

<div class="infor_box attachs ">

<table cellpadding="0" cellspacing="0" border="0" class="frame" id="table_hiden">

<tr>

<td id="uploaded">

</td>

</tr>

<tr>

<td><div id="upflash"></div><p>图片必须小于2M,最多20张,允许jpg、gif、png、bmp格式。 </p></td>

</tr>

</table>

</div>

</span>

    </div>

<script src="/gonggong/upjs/jquery.swfobject.js" /></script>

<script src="/gonggong/upjs/ershou_publish.js" /></script>

</body>

</html>

 

 

这里 要加载几个js等下我打包传附件

添加一个上传处理的控制器

<?php

// 本类由系统自动生成,仅供测试用途

class AttachmentAction extends Action{

 

    public function index(){

//session_start();

// $postmodels = $this->_get('postmodels');

//if(empty($postmodels) || $postmodels == 'undefined'){echo 'error:参数错误,不能执行此操作!';exit();}

        import("@.Org.UploadFile"); 

$filesavepath = C('upfiledir') ; 

        $upload = new UploadFile(); 

$upload->maxSize = C('upmaxsize')*1024*1024 ;

$upload->savePath = $savepath = '.' . $filesavepath . '/' ; 

        $upload->allowExts = explode(',',C('upfileext')); 

 

$upload->saveRule = GetFileID();

 

$upload->thumb = true;

$upload->thumbMaxWidth = C('thumbwidth');

$upload->thumbMaxHeight = C('thumbheight');

if(!$upload->upload()) {// 上传错误提示错误信息

echo 'error:'.$upload->getErrorMsg(); exit();

}else{// 上传成功 获取上传文件信息

$info =  $upload->getUploadFileInfo();

$fullfilepath = '/' . $filesavepath . '/' . $info[0]['savename'] ;

 

 

$localfile = ROOT_DIR . $fullfilepath ; //本地文件路径

 

$fullthumbfilepath = '/' . $filesavepath . '/thumb_' . $info[0]['savename'] ;

$localthumbfilepath = ROOT_DIR . $fullthumbfilepath ;

 

 

echo $filesavepath . '/thumb_' . $info[0]['savename'];

 

}

    }

 

}

 

之前我也写过一个关于CodeIgniter图片批量上传的.....http://www.wulinlw.org/post-143.html

不懂的看网站底部有Q我...我有时间的话会告诉滴!

 

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

asp.net笔记(13)

Continue Read..

第十三章:Web应用程序包
                              打包需要解决两点
                              1)打包之后的网站中应该没有源文件(*.cs)
                              2)打包过程中应该把DotnetFrameworker打包进去,这样在安装过程
                                会自动识别目标计算机上是否有fw,如果没有则首先安装fw
                              打包的步骤:
                               1)安装WebDeployment。这是微软公司为了弥补vs2005自动的web打包而
                                 发布一个插件,它可以把一个网站进行编译,其结果是没有源文件也可以运行
                               2)创建一个web应用程序
                               3)对准web应用程序单右-->add WebDeployment Project,确定
                               4)选择WebDeployment Project单右-->生成,就可以生成一个没有*.cs的网站
                               5)添加一个Web安装项目
                               6)选中Web安装项目按F4,弹出属性窗口,在其中输入安装项目的信息,包含:安装的标题,软件的作者等等
                               7)选中Web安装项目按单右-->属性-->系统必备--->选择"从与我应用程序相同的位置下载系统必备组件
                               8)选中"web应用程序文件夹"--->单右-->添加-->项目输出-->选择以前通过WebDeployment Project生成的项目-->确定
                               9)选中Web安装项目按单右-->生成--->在生成的文件夹的Debug文件夹中会看到
                                 dotnetfx,setup.exe.WeijinSetUp.msi三个安装文件
                               10)把这三个安装文件刻成光盘,安装到目标文件就可

 

           
                                第十四章 xml文件的操作
               1)在asp.net中要操作xml文件有三种方式
               2)xmldocument类,xmlTextReader,xmlTextWriter类,DataSet类

                               xmldocument类  
            1:xmldocument实际上利用xml文档对像模型(dom)对xml进行操作
            2:工作原理是把xml文档中的全部内容读到内存中,形成一个xml文档树 
            3:通过dom能够对xml文档进行增加,删除,修改等操作
            4:缺点是如果文档非常大的话,则会导致内存资源不足的问题
            有如下的xml文件:
                 <?xml version="1.0" encoding="utf-8" ?>
  <studs>
    <stud>
       <id>S1</id>
       <name OtherName="二狗">张三</name>
        <age>20</age>
                 </stud>
                 <stud>
                       <id>S2</id>
                       <name>李四</name>
                       <age>34</age>
                </stud>
                <stud>
                       <id>S3</id>
                       <name>小张</name>
                       <age>20</age>
                </stud>
            </studs>

                        document
                           |
                           | 
                  --------------------
                  |       | 
                  xml              studs
                                     |
                                     |
                             ------------------------------------
                             |                 |                |
                            stud              stud            stud
                             |          
                             |                
                        -----------             
                        |    |    |  
                       id   name age
                        |    |    |
                        S1  张三  20


              读文件:
                   XmlDataDocument doc = new XmlDataDocument();
               string path = Environment.CurrentDirectory;
                   doc.Load(path + "\\XMLFile1.xml");
                   XmlElement root =doc.DocumentElement;//得到文档的根
                   foreach (XmlNode StudNode in root.ChildNodes)
                     {
                         string id = StudNode.ChildNodes[0].FirstChild.InnerText;
                         string name = StudNode.ChildNodes[1].FirstChild.InnerText;
                         string age = StudNode.ChildNodes[2].FirstChild.InnerText;
                         ListViewItem lv = new ListViewItem(id);
                         this.listView1.Items.Add(lv);
                         lv.SubItems.Add(name);
                         lv.SubItems.Add(age);
                   }
            增加文件:
                 XmlDocument doc = new XmlDocument();
              string path =Environment.CurrentDirectory + "\\XMLFile1.xml";
              doc.Load(path);
             XmlElement root = doc.DocumentElement;
             XmlNode StudNode=doc.CreateNode(XmlNodeType.Element, "stud", "");
              XmlNode IdNode = doc.CreateNode(XmlNodeType.Element, "id", "");
                 IdNode.InnerText = "S99";
              XmlNode NameNode = doc.CreateNode(XmlNodeType.Element, "name", "");
              NameNode.InnerText = "小二";
             XmlNode AgeNode = doc.CreateNode(XmlNodeType.Element, "age", "");
              AgeNode.InnerText ="67";
              StudNode.AppendChild(IdNode);
             StudNode.AppendChild(NameNode);
             StudNode.AppendChild(AgeNode);
             root.AppendChild(StudNode);
             doc.Save(path);
            修改文件:
                          XmlDataDocument doc = new XmlDataDocument();
               string path = Environment.CurrentDirectory;
              doc.Load(path + "\\XMLFile1.xml");
              XmlElement root =doc.DocumentElement;
               root.ChildNodes[0].ChildNodes[0].FirstChild.InnerText = "S7";
              doc.Save(path + "\\XMLFile1.xml");     
            删除文件:
                    XmlDataDocument doc = new XmlDataDocument();
                 string path = Environment.CurrentDirectory;
                    doc.Load(path + "\\XMLFile1.xml");
                    XmlElement root =doc.DocumentElement;
                    root.RemoveChild(root.ChildNodes[0]);
                    doc.Save(path + "\\XMLFile1.xml");
            读取属性:
                  XmlDataDocument doc = new XmlDataDocument();
             string path = Environment.CurrentDirectory;
             doc.Load(path + "\\XMLFile1.xml");
             XmlElement root =doc.DocumentElement;
             string st=root.ChildNodes[0].ChildNodes[1].Attributes["OtherName"].InnerText;
            MessageBox.Show(st);
  


                xmlTextReader类
          1) 这个类提供一个只读的访问xml文件的方式,相当于利用dom而言,非常快速,但是它只能够
             读,不能修改,要修改可以利用xmlTextWriter类
          2) 不论是xmlTextReader类还是xmlTextWriter类,它们对xml操作必须是从头到尾进行操作,也
             就是说如果你想操作第100个节点的内容,它们都会从第一个节点一步一步移到100个节点之后才
             能进行操作,这个与xmlDocumnet的处理机制完全不一样,所以xmlTextWriter非常不适合于修改
           
             读文件:
   string path=Environment.CurrentDirectory+"\\XMLFile1.xml";
             XmlTextReader xtr = new XmlTextReader(path);
              while (xtr.Read())
               {
   if (xtr.HasAttributes)
                     {
                            MessageBox.Show(xtr.GetAttribute(0));
                     }  
                       if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "id") //读id
                    {
                             if (xtr.Read())
                             {
                                MessageBox.Show(xtr.Value);
                              }
                         }
                   }
                   xtr.Close();
                 }
              写文件:
             XmlTextWriter xmlwrite = new XmlTextWriter("..\\..\\XMLFile.xml",Encoding.Default);
             xmlwrite.Formatting = Formatting.Indented; //设置换行标志
             xmlwrite.WriteStartDocument();//写入开始位置
            xmlwrite.WriteStartElement("peoples");//写入没有值的节点
            xmlwrite.WriteStartElement("people");//写入没有值的节点
            xmlwrite.WriteElementString("姓名", "张三");//写入有值的节点
             xmlwrite.WriteEndElement();//为没有值的节点,写入结束标记
             xmlwrite.WriteEndElement();//为没有值的节点,写入结束标记
             xmlwrite.Flush();//把缓冲区的内容,真正的写入到文件中去
            xmlwrite.Close();//关闭,以释放资源
                            
                            
                                         

                         DataSet类
           读文件:
                   string path = Environment.CurrentDirectory + "\\XMLFile1.xml";
                DataSet ds = new DataSet();
                   ds.ReadXml(path);
                   DataTable dt = ds.Tables[0];
                   string st = dt.Rows[i][j].ToString();
           增加:
              string path = Environment.CurrentDirectory + "\\XMLFile1.xml";
              DataSet ds = new DataSet();
              ds.ReadXml(path);
              DataTable dt = ds.Tables[0];
              DataRow dr = dt.NewRow();
              dr[0] = "S8";
              dr[1] = "爸爸";
              dr[2] = "45";
              dt.Rows.Add(dr);
              ds.WriteXml(path);
          修改:
            string path = Environment.CurrentDirectory + "\\XMLFile1.xml";
            DataSet ds = new DataSet();
            ds.ReadXml(path);
            DataTable dt = ds.Tables[0];
            DataRow dr = dt.Rows[0];
            dr[0] = "S8";
            dr[1] = "爸爸";
            dr[2] = "45";
            ds.WriteXml(path);

            三种方法总结:
              1)如果操作的xml文件的结构与数据表相似,则优先考虑使用dataset
              2)如果操作的xml文件的结构与数据表不相似:
                     A:如果要读:则使用xmlTextReader对像
                     B:如果要修改:则使用xmlDocument对像

 

                  高级编程
          实现客户端无刷新加传

asp.net笔记(12)

Continue Read..

第十一章:Web用户控件
                              在这一章里面,我们要学习
                      1:为什么要Web用户控件
                      2:如何创建Web用户控件
                      3:给Web用户控件加属性
                      4:给Web用户控件加方法
                      5:给Web用户控件加事件
                      6:Web用户控件应用举例
                      7:利用用户自定义控件,快速拼装网站,以实现母版页功能

                      为什么要自定义Web控件
                     对已有的Web控件进行组合,从而实现页面代码的重用。我们可以把一个网站
                     中经常要使用到部分区域做成一个Web控件,这样这个Web控件将可以在这个网站
                     的任意部分进行重用
                            
                                如何自定义Web控件         
                         添加-->Web用户控件。其扩展名为*.ascx

                                给用户自定义控件加属性
                                 1)加属性的方法与winform一样
                                 2)如果这个属性是依赖于自定义控件的某个Web控件,则可以直接
                                   加属性,但如果是单纯的属性,则一定要使用session对像来保存
                                  比如:
                                         public string MyProperty
           {
                                                    get { return Session["MyProperty"].ToString(); }
                                                    set { Session["MyProperty"] = value; }
                                                 }

                                 给用户自定义控件加方法
                                   与winform一样

                                  给自定义控件加事件
                                 A:在自定义用户控件页面中
                                   1)声明事件指针
                                        public event EventHandler OnClick;
                                                    (事件句柄类型) (指针名)
                                        以后这个指针就指向外面的与EventHandler是同一种类型
                                        的事件过程
                                  2)触发事件:
                                     if (this.OnClick!=null) //表示如果这个指针有某个具体的指向
                                      {
                                         this.OnClick(sender, e); 就通过指针去执行它所指向的事件
                                     } 
                                 B:在使用这个控件的页面的Page_Load事件中写入:
                                        this.MyUserControll1.OnClick += new EventHandler(LonginButton_OnClick);
                                        注意使用Tab键会自动生成对应的代码
                                 举例:
                                  1)做一个登录框的Web用户控件,并添加用户名密码属性,同时加入单击登录按钮的事件
                                  2)做一个专门用来显示某些对像内容的Web控件,像列表一样,有超链接
                                    像显示新闻一样
                                                                            
                                 利用用户自定义控件,快速拼装网站,以实现母版页功能
                                        举例:拼装网站


                                 第十二章:Css样式表
                                   1:什么是样式表
                                   2:如何来定义样式表  
                                   3:样式表中的选择器     
                                   4:如何在页面中来使用样式表  
                                   5:几种常用的样式表             

                                       
                                     什么是样式表        
     CSS就是Cascading Style Sheets,中文翻译为“层叠样式表”,简称样式表,它是一种制作网页的新技术
     样式表是由很多的样式规则组成的,这些规则规定浏览器如果显示文档。一旦样式表创建好之后,就可以
     把这种样式规则应用于整个网页上,从页让这些网页也具备这些样式规则,最重要的是一旦修改了样式表,
     则所有应用于该样式表的网页都会更着发生变化
                                   
                                      如何来定义样式表
                           格式:
                             选择器{属性名:属性值}
                       比如:
                            h1{color:red} 把h1的文字颜色变成红色
                        说明:
                          1)选择符是可以是多种形式,一般是你要定义样式的HTML标记,例如BODY、P、TABLE……,你可以通过此方法定义它的属性和值,属性和值要用冒号隔开
                          2)如果属性的值是多个单词组成,必须在值上加引号,比如字体的名称经常是几个单词的组合:
                                 table {font-family: "sans serif"}
                          3)如果需要对一个选择符指定多个属性时,我们使用分号将所有的属性和值分开:
      table{color:red;font-size:40px}
      表的字体颜色为红色,字体大小为40px
                         4)为了使你定义的样式表方便阅读,你可以采用分行的书写格式:
                                table
                                {
                                      color:red;
                 font-size:40px //最后一个不用分号
                                }
                         5)你可以把相同属性和值的选择符组合起来书写,用逗号将选择符分开,这样可以减少样式重复定义
                            比如:
                            table,h1{color:red;font-size:40px} 
                       

                                      样式表中的选择器
                                1)html选择器:
                                  这些选择器使用html标记的名称,因此该样式表只能够应用于一种html标记
                                2)类选择器: 
                                  用类选择符你能够把相同的元素分类定义不同的样式,定义类选择符时,在自定类的名称前面加一个点号
                                  比如:
                                     h1.c1{color:red}
                                     h1.c2{color:white}  
                                     把同个标记h1定义成为两种不同的样式
                                     然后用不在不同的段落里,只要在HTML标记里加入你定义的class参数:
                                   说明:
                                     1:类的名称可以是任意英文单词或以英文开头与数字的组合,一般以其功能和效果简要命名
                                     2:类选择符还有一种用法,在选择符中省略HTML标记名,这样可以把几个不同的元素定义成相同的样式:
                                       这样的类可以被应用到任何元素上
                                       比如:
                                         .color{color:red}
                                        以后无论什么标记都能够使用这个color。注意与
                                          h.color{color:red}的区别
                                 3)伪类选择器:
                                        主要是用来做超链接的样式


                                       如何在页面中来使用样式表                                     
                                         1:链入外部样式表
                                            把样式表做一个样式表文件,然后再通过
                                               <link rel="stylesheet" type ="text/css" href="CSS/CSS.css" />语法进行链接
                                              
                                         2:内部样式表
                                            内部样式表是把样式表放到页面的<head>区里,这些定义的样式就应用到页面中了,样式表是用<style>标记插入的
                                                <style type="text/css">
                                                    hr {color: sienna}
                                                    p {margin-left: 20px}
                                                    body {background-image:url("images/back40.gif")}
                                                 </style>

     几种常用的样式表                                        

      a:visited {
        text-decoration: none;
                      color: #000000;
                                                           }
                                                   a:hover {
                                                          text-decoration: none;
                                                          color: #000000;
                                                           }
                                                     a:active {
                                                         text-decoration: none;
                                                              }                                                                           
      a:visited:一开始的链接
                                  a:hover 鼠标放在链接上的状态
                                  a:active 在链接上按下鼠标时的状态
                                 如何让表格自动换行:
                                    1)<table style="table-layout:fixed">
                                    2)<td style="word-break:break-all">

asp.net笔记(11)

Continue Read..

第十章:数据库技术
                                  1:如何将数据库的数据填充到XML文件中
                                  2:如何利用Web.Config配置数据库的连接字符串
                                  3:如何编程使用存储过程
                                  4:三层结构的数据层的封装
                                  5:如何读取Excel表格中的数据
                                  6:如何备份与还原数据库
                                  7:数据库中Ajax的实现 
                                  8:数据库的报表打印
                                  9:如何生成验证码
                                

                                   如何将数据库的数据填充到XML文件中
                                    A)生成一个Table对像
                                    B)指定Table对像的TablName属性
                                    C)调用Table对像的dt.WriteXml(Server.MapPath("chen.xml"));
                                 

                                 如何利用Web.Config配置数据库的连接字符串
                           在某些情况下,数据库的连接字符串会经常变动,例如:主机修改了密码。如果
                           把连接字符串放在代码中,则必须要编译整个项目,这个时候可以使用Web.Config
                           来存储数据库的字符串。Web.Config是一个以Xml形式的文件
                           1)在<connectionStrings>节下面配置如下:
                                   <connectionStrings>
                                     <add name="constr" connectionString="server=.;database=test;uid=sa;pwd=123"  providerName="System.Data.SqlClient">      
                                    </add>
                                   </connectionStrings>  
                           2)读取配置的字符串: 
                                   string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
                                                            

                                    如何编程使用存储过程
                  访问存储过程的步骤:
                    1)没有结果集的
                         A)没有参数的
       public static void RunNoneResultProc(string ProcName) 
                              {
                                 SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
                                _Conn.Open();
                                 Scmd.CommandType = CommandType.StoredProcedure;
                                 Scmd.ExecuteNonQuery();
                                _Conn.Close();
                              }
 
                          B)有参数的
           public static void RunNoneResultProc(string ProcName, SqlParameter[] SqlParameters) 
                 {
                    SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
                   _Conn.Open();
                    Scmd.CommandType = CommandType.StoredProcedure;
                    foreach (SqlParameter Item in SqlParameters)
                      {
                       Scmd.Parameters.Add(Item);
                      }
                    Scmd.ExecuteNonQuery();
                   _Conn.Close();
               }
           2)有结果集的
           public static DataTable RunHasResultProc(string ProcName) 
                 //没有参数,有返回结果的存储过程
            {
             _Conn.Open();
             SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
             Scmd.CommandType = CommandType.StoredProcedure;                       
             SqlDataAdapter Sda = new SqlDataAdapter(Scmd);
             DataTable Dt = new DataTable();
             Sda.Fill(Dt);
             _Conn.Close();
             return Dt;            
          }
        public static DataTable RunHasResultProc(string ProcName, SqlParameter[] SqlParameters)   //有参数,有返回结果的存储过程
        {
            _Conn.Open();
            SqlCommand Scmd = new SqlCommand(ProcName, _Conn);            
            Scmd.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter Item in SqlParameters)
            {
                Scmd.Parameters.Add(Item);
            }
            SqlDataAdapter Sda = new SqlDataAdapter(Scmd);
            DataTable Dt = new DataTable();
            Sda.Fill(Dt);
            _Conn.Close();
            return Dt;
        }                      
                    说明:
                       A: 可以使用重载的方式来完成
                       B: 可以表现为对数据库的增,删,改。操作
                       C: 举一个可以把职工的工资加上100的存储过程
                       D: 举一个可以把满足条件的职工的工资加上指定工资的存储过程
                       E: 举一个有输出参数的存储过程 
               
           
                                  三层结构的数据层的封装

  public class ClsDataOper
    {
        private static SqlConnection _Conn = new SqlConnection("server=.;database=northwind;uid=sa;pwd=;");
        public static DataTable RunHasResultSql(string sql) //执行有返回结果集的sql语句
        {
           try
            {
                SqlDataAdapter _Sada = new SqlDataAdapter(sql, _Conn);
                _Conn.Open();
                DataTable Dt = new DataTable();
                _Sada.Fill(Dt);               
                _Conn.Close();                
                return Dt;
            }
           catch (Exception e)
            {
               MessageBox.Show("返回结果集出错!", "消息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
           }
        }

        public static void RunNoneResultSql(string sql) //执行没有返回结果集的sql语句
        {
            try
            {
                SqlCommand Scmd = new SqlCommand(sql, _Conn);
                _Conn.Open();
                Scmd.ExecuteNonQuery();
                _Conn.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show("执行命令失败!", "消息", MessageBoxButtons.OK, MessageBoxIcon.Error);                
            }
        }

       public static SqlParameter GetParameter(string ParameterName,  SqlDbType ParameterType, object ParameterValue)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = ParameterName;
            p.SqlDbType = ParameterType;
            p.Value = ParameterValue;
            return p;
       }
public static SqlParameter GetParameter(string ParameterName, SqlDbType ParameterType, object ParameterValue,bool IsOutPut)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = ParameterName;
            p.SqlDbType = ParameterType;
            p.Value = ParameterValue;
            if (IsOutPut)
            {
                p.Direction = ParameterDirection.Output;
            }
            return p;
        }


        public static void RunNoneResultProc(string ProcName) //没有参数,没有返回结果的存储过程
        {
            SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
            _Conn.Open();
            Scmd.CommandType = CommandType.StoredProcedure;
            Scmd.ExecuteNonQuery();
            _Conn.Close();
        }

        public static void RunNoneResultProc(string ProcName, SqlParameter[] SqlParameters) //有参数,没有返回结果的存储过程
        {
            SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
            _Conn.Open();
            Scmd.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter Item in SqlParameters)
            {
                Scmd.Parameters.Add(Item);
            }
            Scmd.ExecuteNonQuery();
            _Conn.Close();
        }

        public static DataTable RunHasResultProc(string ProcName) //没有参数,有返回结果的存储过程
        {
            _Conn.Open();
            SqlCommand Scmd = new SqlCommand(ProcName, _Conn);
            Scmd.CommandType = CommandType.StoredProcedure;                       
            SqlDataAdapter Sda = new SqlDataAdapter(Scmd);
            DataTable Dt = new DataTable();
            Sda.Fill(Dt);
            _Conn.Close();
            return Dt;
            
        }

        public static DataTable RunHasResultProc(string ProcName, SqlParameter[] SqlParameters) //有参数,有返回结果的存储过程
        {
            _Conn.Open();
            SqlCommand Scmd = new SqlCommand(ProcName, _Conn);            
            Scmd.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter Item in SqlParameters)
            {
                Scmd.Parameters.Add(Item);
            }
            SqlDataAdapter Sda = new SqlDataAdapter(Scmd);
            DataTable Dt = new DataTable();
            Sda.Fill(Dt);
            _Conn.Close();
            return Dt;
        }
    } 

               如何读取Excel表格中的数据
                             1:加入Html的File控件,并转换成为Web服务器控件
                             2:写入以下代码:
                                    OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+this.File1.Value+";Extended Properties='excel 8.0'");
                                    OleDbDataAdapter ada = new OleDbDataAdapter("select * from [Sheet1$]", con);
                                    DataTable dt=new DataTable();
                                    ada.Fill(dt);
                                    this.GridView1.DataSource =dt;
                                    this.GridView1.DataBind();


                                 如何备份与还原数据库
                                  1:备份sql语句:
                                     backup database 数据库 to disk=路径
                                  2:还原数据库:
                                     restore database from disk=路径

                                  8:数据库的报表打印
                                      1)可以通过导出Excel来实现报表的打印
                                      2)通过水晶报表来实现打印:
                                         A)拖一个CrystalReportViewer到页面上
                                         B)选择CrystalReportViewer控件的属性:ReportSourceId,并选择"新建报表源..."
                                         C)在弹出的对话框中输入报表的数据源控件的名一般为"CrystalReportSource1",与报表
                                         D)添加一个数据集,在设计视图中选择"数据库专家",并加载数据集
                                         E)在Page_Load事件里面写上代码:
                                                   DataSet1 ds1 = new DataSet1();
                    ds1.Tables.Clear();
                                                   DataTable dt = DataOper.GetDataTable("select * from dbo.chen");
                                                   dt.TableName = "chen";
                                                   ds1.Tables.Add(dt);
                                                   this.CrystalReportSource1.ReportDocument.SetDataSource(ds1);
                                                   this.CrystalReportSource1.DataBind();
                                   
                    

 


                                  9:如何生成验证码
                        为什么要生成验证码:
                          如果只用普通的用户名和密码进行身份验证有一些弊端。原因在于用户名和密码
                          一般不会改变。暴力破解软件来对密码进行破解。具体原理其实是很简单的,这个软件会想服务器不断的
                          提交密码然后尝试登陆,提交的密码是根据字典(所谓黑客字典)或者是直接的把键盘上所有的键随意的所有组合全部尝试一遍 
     这样尝试了所有的组合之后你的密码就会被猜到,这样的破解方法一般称为暴力破解。但是现在采用验证码技术之后,
                          每一次向服务器提交登陆申请的时候不仅仅要输入密码还要输入验证码,而这个验证码是随机变化的,更重要的是验证码不是文本,而是
                          可是做成图片之后,这样黑客软件如果想读取图片的数字,几乎是不可能
                        如何生成检证码:
                            两个页面:
                              1)用于产生验证码。假设为CreateCheckCode.aspx
                                     private void CreateCheckCodeImage(string checkCode)
    {  //将验证码生成图片显示
        if (checkCode == null || checkCode.Trim() == String.Empty)
            return;
        System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
        Graphics g = Graphics.FromImage(image);
            //生成随机生成器 
            Random random = new Random();
            //清空图片背景色 
            g.Clear(Color.White);
            //画图片的背景噪音线 
            for (int i = 0; i < 25; i++)
            {
                int x1 = random.Next(image.Width);
                int x2 = random.Next(image.Width);
                int y1 = random.Next(image.Height);
                int y2 = random.Next(image.Height);

                g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
            }
            Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
            System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
            g.DrawString(checkCode, font, brush, 2, 2);
            //画图片的前景噪音点 
            for (int i = 0; i < 100; i++)
            {
                int x = random.Next(image.Width);
                int y = random.Next(image.Height);

                image.SetPixel(x, y, Color.FromArgb(random.Next()));
            }
            //画图片的边框线 
            g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);                       
            Response.ClearContent();
            Response.ContentType = "image/Gif";
            Response.BinaryWrite(ms.ToArray());
        
    }              
               2)用于实现验证码:test.aspx。
                 在里面放入一个html的img标记,形如:<img src=CreateCheckCode.aspx>
              3)实现检验码的刷新: 
                          function change()
                                 {
                                   document.getElementById("img1").src ="default3.aspx?id="+Math.random();
                                 }     

asp.net笔记(10)

Continue Read..

第十一章:跟踪、缓存、Asp.net中配置应用程序

                                  跟踪
                    1)利用asp.net提供跟踪技术用户可以察看某个asp.net页面中请求的详细信息。
                      包含表单中所有Web控件的信息,session,cookie,application等信息
                    2)利用asp.net跟踪技术可以快速的了解一个asp.net页面的执行过程,细节,从而 
                      帮助我们排除页面中错误
                    3)跟踪的分类
                       A:页面级跟踪:<%@ page trace="true" tracemode="指定模式"%>
                       B:可以通过Trace.warn("信息")来把用户自定义的消息显示在跟踪的结果中,会以红色字体显示
                       C:应用程序级跟踪:可以对一个Web应用程序的所有页进行跟踪
                         在web.config文件中进行配置
                          <configration>
                               <system.web>
                                 <trace enabled="true" pageoutput="true"/>
                               </system.web>                              
                           </configration> 
                       
                                缓存
                     什么是缓存:
                       1)缓存技术会把访问频率比较高,或者量大的数据暂存在内存中
                       2)以后在访问时不需要重新创建,可以直接从缓存中去。
                       3)所以通过缓存技术可以显著提高程序的性能
                             4)记住:一旦应用程序停止或重新启动,重新编译,缓存就会消失
                     缓存的分类:
                        A:输出缓存:
                           对整个页面进行缓存的设置,把整个页面缓存起来。
                           1)<%@ OutputCache Duration="120"> 表示把整个页面级存120秒。
                           在页面的Load事件里面写上如下代码:
                             response.write(DateTime.now.tostring());
                            结果:在打开的120秒内不断访问页面,会发现时间没有变化,因为是从
                                  缓存中取出的。但是如果在120秒之后来访问此时时间会发生改变,
                                  因为缓存会更新,从服务器中去页面。但是在接下来的120秒之内依然保持不变
                       B:数据缓存:
                          缓存是不是整个页面,而是页面中的每些数据。通常会把从数据库查询出来的
                          数据量大而且访问频率高的数据放入数据缓存中,这是由Cache类来实现的
                          它的使用格式是:
                            1)放入缓存:if (Cache["key"]==null)  Cache["key"]=值
                            2)取数据: 变量名=(类型转换)Cache["key"];
                           但是这一种格式的致命的弱点是缓存不会随着缓存中数据的更新而改变,数据的实时性不高
                           可以通过下面的代码,让缓存中的数据发生改变时,会自动通知缓存已经过期,从而重建缓存
                          在Page_load事件里面写上如下代码:
                            if (!IsPostBack)
            {
                Response.Write("开始取数据时间:" + DateTime.Now.ToLongTimeString()+"毫秒:"+DateTime.Now.Millisecond.ToString()+"<br>");
                DataTable dt = null;
                 if (Cache["dt"] == null)
                {
                     string constr=ConfigurationManager.ConnectionStrings["constr"].ConnectionString;//读取web.config配置信息
                      dt = dbManager.RunHasResultSql("select * from worker");
                      SqlCacheDependencyAdmin.EnableNotifications(constr); //为Web应用程序启用自动通知特性
                      SqlCacheDependencyAdmin.EnableTableForNotifications(constr, "worker");//设置数据库中表的自动通知特性
                     SqlCacheDependency sqldep = new SqlCacheDependency("northwind", "worker"); //创建缓存清空的依赖项为northwind中的worker表,以后只要worker表的数据的改变了缓存就会清空
                      Cache.Insert("dt", dt,sqldep); //插入缓存项             
                      Response.Write("从数据库中取数据<br>");                                
                }
                 else
                 {
                      dt = (DataTable)Cache["dt"];
                      Response.Write("从缓存中去<br>");
                 }
                 this.GridView1.DataSource = dt;
                 this.GridView1.DataBind();            
                 Response.Write("结束取数据时间:" + DateTime.Now.ToLongTimeString() + "毫秒:" + DateTime.Now.Millisecond.ToString() + "<br>");
             }

                          还要配置web.config文件如下
       *********************************************************************************************
  <configuration>
   <appSettings/>
     <connectionStrings>
        <add name="constr" connectionString="server=.;database=northwind;uid=sa;pwd=" providerName="using System.Data.SqlClient"/>
     </connectionStrings>
   <system.web>
       <caching>      
           <sqlCacheDependency enabled="true" pollTime="500"> //polltime是轮询的时间,当缓存中的数据在后台改变会过多长时间通知缓存过期单位为毫秒,至少要>=500,此项一定不能少
            <databases>
                <add name="northwind" connectionStringName="constr"/>        
            </databases>        
         </sqlCacheDependency>            
           </caching>

      *********************************************************************************************
                        
   
                   Asp.net对应用程序的配置都放在Web.Config配置文件里面,通过使用
                   Web.Config进行配置,可以增加程序的灵活性
                  
                   1:如何利用Web.Config配置数据库的连接字符串
                                1)在<connectionStrings>节下面配置如下:
                                   <connectionStrings>
                                     <add name="constr" connectionString="server=.;database=test;uid=sa;pwd=123"  providerName="System.Data.SqlClient">      
                                    </add>
                                   </connectionStrings>  
                               2)读取配置的字符串: 
                                    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
                   2:当应用程序发生错误时,自动定向到一个错误页面
                        <customErrors  mode="On" defaultRedirect="Error.aspx"/>
                   3:是否启用调式:
                          <compilation debug="true"/>
                        在开发时,可以启用,但是在发布时,一定要禁用
                   4:指定Asp.net检证模式。四种检验模式
                       A)Windows检证模式:
                          客户端每次连接Web服务器时,必须要输入Web服务器操作系统上windows
                          账户名,如此IIs才会认为你有权限来访问该Web服务器上的网页
                          (不能在本机上测试,由于本机在开机时已经登录过,也就是说已经通过的
                           window的身份检验)
                          好处:可以很好的和公司服务器的账户集成,安全
                          坏处:任何一个用户要浏览网页,必须要创建一个账号
                        结论:如果你的网站是供Internet来访问的话,不能使用此检证模式,那样
                              会创建很多账户
                       B)Forms身份验证(Internet身份检验)
                         客户端每次连接Web服务器的任何页面时,Web服务器会检查是否通过Forms身份验                         证,如果没有通过,则自动转到用户开发的登录表单中进行身份检验。一旦用户
                         通过检验,则向客户端添加一个Cookies,以后通过这个Cookies来进行身份的
                         检验。可以达到只需要登录一次,然后永远信任的特点。以前的登录方式
                         只要知道了网页名,直接在网址里面输入就可以了,非常不安全。
                         步骤:
                           <authentication mode="Forms">
                            <forms name="myauth" loginUrl="login.aspx"></forms>           
                               </authentication> 
                     
                               <authorization>
                             <deny users="?"></deny>   [拒绝没有授权的账户]   
                          </authorization>   
                        在登录页面里面输入以下代码:
                            if (this.TextBox1.Text == "chen" && this.TextBox2.Text == "123")
                                 {
                                       FormsAuthentication.SetAuthCookie(this.TextBox1.Text, false); [写入Cookies,用false和true来决定是永远信任,还是仅本次登录信任]
                                       if (FormsAuthentication.GetRedirectUrl(this.TextBox1.Text,false).EndsWith("default.aspx"))//如果是用户直接打开登录页面,此时会自动返回default.aspx
                                          {
                                              Response.Redirect("index.aspx"); //就跳转到首页
                                          }
                                          else
                                              {
                                                        FormsAuthentication.RedirectFromLoginPage(this.TextBox1.Text, false); //就跳转到上一次出错的页面
                                              }
                                 }
                           举例:
                             1)在同一个页面里面放入多个链接,有商品管理,客户管理,产品管理,登录
                               只有当用户登录过之后才通使用商品管理,客户管理,产品管理模块,
                               否则无论点那个超链接都会自动到登录页面中来
                             2)阻止用户知道某个网页的地址,直接输入该网页而运行网站
                       C)其它的Passport,与None要配置其它的服务器,使用第三方软件才能够使用,很少使用。

asp.net笔记(9)

Continue Read..

第十章:asp的内部对像
      在这一章里面我们要学习
        1:session对像
        2:application对像
        3:cookies对像         
        4:全局应用程序类Global.asax                                                                              
                            session[会话]对像
 session对像的工作原理:
   1:首先你应该把session想像成为一个大盒子,里面用来存放客户的数据
   2:当你打开一个网站的首页时,服务器就会为你创建一个大盒子,并且为这个大盒子编一个号,于是这个大     盒子就可以让你在这个网站的不同页面之间共享.直到你离开这个网站的时候,这服务器又会收回这个大盒子
   3:可见session对像的其中的一个功能就是为了实现让用户在不同页面之间实现数据共享.但是一旦用户离开     这个网站,那么session也就会自动消失
   4:一个网站可以被很多人同时访问,访问的每一个人在打开主页时,都会有一个大盒子,即session.如果另一       个用户也同时访问网站,他也拥有自己的Session变量,但两个用户之间无法通过Session共享信息
   6:sesson是一个数据的集合
   7:Session其实指的就是访问者从到达某个特定主页到离开为止的那段时间

          以游泳分配一个柜子为例来说明sesson的用法

  总结:session可以为同一个用户在不同的页面之间共享提供支持,这种支持是在服务器端维护的

    A)如何向session中添加或修改一个数据放
           session("关键字")=值
    B)如何得到session里面的每个关键字的值
        1)session.Contents(下标)
        2)session.Contents("关键字")
    C)如何得到session里面的数据个数
        session.contents.count
    D)如何查找session集合中的每一个数
        for i=1 to session.contents.count          
         response.write session.contents(i)
        next 
    E)如何删除session集合中的一项数据
       1) session.Contents.Remove(下标)
       2) session.Contents.Remove(关键字)
    F)如何清空session集合中所有数据
          session.Contents.RemoveAll()
    G)如何设置过期时间
         session在服务器上保留是有时间限制的,默认为20分钟.可以通过
         session.Timeout=值 (以分为单位)      
                

                              session应用举例
                                例1:根据登录用户的类型,来限制用户能够使用的模块
                                例2:判断用户是否登录来决定用户是否可以购物
                                例3:简单购物车。通过HasTable对像

                                              
                             application对像
session对像记载特定客户的信息,而application对像可以记载所有客户信息。好比教室中的公共存储柜,每一个学生都可以使用。application对像最典型是应用就是聊天室。大家的发言都存放到一个application对像中。彼止就可以看到发言的内容了。application对像的内容是保存在服务器端 application对像不像sessoin对像有效期的限制,它是一直存在的。从该应用程序启动直到应用程序关闭在这之间任何客户都的信息都不会diu失 

                1)application.lock:锁定application对像,防止其它客户同时对applicaton对像进行修改
                2)application.unlock:解除锁定,让其它客户可以访问。
                3)application("关键字")=值--->为application赋一个值
               
                        applicatoin应用举例
                          1:简单聊天室[显示发言人姓名,发言人内容,发言人时间]
                          2:以图形的方式统计网页被游览的次数
               

                 cookies对像 
什么是cookies
          cookies对像可以客户端长期保存信息。在客户端的计算机里面会有一个cookies文件夹,那里就是存放客户端的信息的。跟session与application不同的,
        cookies是把信息存储在客户端,不是在服务器里面,当你第一次访问某个网站时,服务器就会将相关信息保存在你的计算机硬盘上cookies文件夹里面,
      下一次再访问该网站时,它就会读取你的计算机硬盘上cookies,并将新的信息保存在你的计算机上。

cookies的分类:
 1:临时性的cookies--->没有设置expires。cookies是存储在客户端的内存中,
    当浏览器在关闭时,会自动的清除对应的cookies
 2: 永久性的cookies-->设置了expires。会存储在客户的硬盘中。即使用户在关闭计算机时,下一次也可以取     到

     
                      操作cookies
             1)response.cookies("关键字")=值   写入cookies
             2)变量名=request.cookies("关键字") 读出
             3)response.cookies("关键字").expires=#日期#   
              设置cookies的过期,做为永久性的cookies,注意在response.cookies("关键字")=值之后设置


                            应用举例
                    1:统计某个客户端曾经访问某个网站的次数 [设置成永久性的cookies]
                    2:保存用户曾经填写的用户名或密码
                    3:生日提示


                      全局应用程序类Global.asax
                   全局应用程序类里面预定义了一些事件,可以在事件里面编写代码来达到统计的目的

                      举例:
                       1)统计在线人数
                       2)一个网站的访问人数