做了四年的winfrm,最近开始开发web程序,学习笔记如下:

一,Window于Document区别:
        
    不要混淆Window对象的location属性和Document对象的location属性。前者引用一个Location对象,而后者只是一个只读字符串,并不具有Location对象的任何特性。document.location与document.URL是同义的,后者在 JavaScript1.1中是该属性的首选名称(因为这样避免了潜在的混淆)。在大多数情况下,document.location和 location.href是相同的。但是,当存在服务器重定向时,document.location包含的是已经装载的URL,而 location.href包含的则是原始请求的文档的URL。

二,asp.net脚本跳出对话框:
      <p>对话框有三种</p>
<p>1:只是提醒,不能对脚本产生任何改变;</p>
<p>2:一般用于确认,返回 true 或者 false ,所以可以轻松用于 ifelse判断 </p>
<p>3: 一个带输入的对话框,可以返回用户填入的字符串,常见于某些留言本或者论坛输入内容那里的 插入UBB格式图片 </p>
<p>下面我们分别演示:</p>
<p>演示一:提醒 对话框</p>
<p>
  <input type="submit" name="Submit" value="提交" onclick="ale()" />
</p>
<p>演示二 :确认对话框 </p>
<p>
  <input type="submit" name="Submit2" value="提交" onclick="firm()" />
</p>
<p>演示三 :要求用户输入,然后给个结果</p>
<p>
  <input type="submit" name="Submit3" value="提交" onclick="prom()" />
</p>
</body>
</html>

三,ASP.NET页面生命周期描述

下面是ASP.NET页面初始的过程:
1. Page_Init();
2. Load ViewState;
3. Load Postback data;
4. Page_Load();
5. Handle control events;
6. Page_PreRender();
7. Page_Render();
8. Unload event;
9. Dispose method called;
下面对其中的一些过程作下描述:
1. Page_Init();
这个过程主要是初始化控件,每次页面载入执行这个初始过程,包括第一次和以后的Postback(这里说下Postback,其实就可以简单理解成用户点击 SUBMIT按钮之类的,把表单<Form>提交给服务器,这就是一次postback),在这里面可以访问控件,但是这里面的控件值不是我们期待的控件里面的值,他只是一个控件的初始值(默认值),举例: 比如一个TextBox1,我们填入了"哈哈",在点击SUBMIT提交了页面后,在Page_Init()里面,我们访问到的 TextBox1.Text不是我们的"哈哈",而是开始的""空字符串,如果TextBox1在我们设计的时候提供了默认值,这里访问到的也就是提供的默认值,为什么呢,这就要看下一个过程了.

对应的事件Page.Init

2. Load ViewState
这个过程是载入VIEWSTATE和Postback数据,比如我们上面的TextBox1,这时就赋了"哈哈",所以,在Post_Init()对控件赋值是无意义的,它都会在这个过程里被改写,当然第一次页面载入例外,因为没有VIEWSTATE数据。

没有对应的事件

3.Load Postback data;
上面说了,Postback可以理解成用户提交表单数据,所以这里就是处理表单数据,当然这里要设计到控件的设计,一般情况不会要我们自己处理这个过程,我们暂且略过.

没有对应的事件
4. Page_Load();
这个过程也是每次页面载入时一定会执行的,但是注意和Page_Init的区别,上面已经涉及了,这里注意的是一般都会用到Page.IsPostBack,该值指示该页是否正为响应客户端回发而加载,或者它是否正被首次加载和访问。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
  //第一次执行的CODE HERE
}
else
{
  //用户提交FORM(即Postback)CODE HERE
}

//每次这里的都会执行CODE HERE
}

对应的事件Page.Load

5. Handle control events;
这个过程里,相应具体的控件事件,比如private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)事件等等

没有对应的事件(我们自己的事件函数都包括在这个过程里比如上面的ListBox1_SelectedIndexChanged)

6. Page_PreRender();
预先呈递对象,这里是在向用户程序呈现数据的倒数第二步,提供这个过程的意义,就是在这里能对控件属性等等要呈现给用户的数据进行修改,这也是最后的修改, 以前的修改(比如在Page_Init里面)都可能被覆盖.做完这了还会进行一个操作就是保存状态,即SaveViewState.

对应的事件时Page.PreRender

7. Page_Render();
可以在浏览器里View->Source查看到,每个页面都有一个隐藏的<input>,其中的"__VIEWSTATE"就是服务器写回来的页面状态信息,在这个之前,服务器要呈现页面(也就是构造HTML格式的文件),就是从这个"__VIEWSTATE"里面获取的数据,当然也会注意到,这里有个Page.Render事件,可以添加自己的处理代码,也就是说在这里又可以更改数据,不推荐在这里修改,既然提供了PreRender, 就应该在里面做最后的修改,当然这不是必须的,只是推荐!

对应的事件Page.Render

8. Unload event;
当向服务器请求一个对象的时候,会在内存里生成一个继承页面对象,也就是页面的类,它继承自System.Web.UI.Page.
当页面对象从内存中卸载时发生,将触发该事件.

对应的事件Page.Unload

9. Dispose method called;
销毁所有的对象.当从内存释放Page时发生,这是生存期的最后阶段。可能第8和9似乎有些模糊,不过我也没怎么搞清楚,待研究!

对应的事件Dispose

以上就是ASP.NET页面周期的描述。


四,ibatis执行insert返回主键的设置方法:
    在<insert id="Insert" parameterClass="SysAuthUsers">
      </insert>里添加<selectKey resultClass="int" type="post" property="Id" >
                select @@IDENTITY as value
            </selectKey>
    需要注意的地方:<selectKey>里的property的值必须跟
<resultMaps>
        <resultMap id="FullResultMap" class="SysAuthUsers">
            <result property="Id" column="ID" dbType="Int"/>
            <result property="Code" column="Code" dbType="NVarChar"/>
            <result property="Username" column="UserName" dbType="NVarChar"/>
            <result property="Password" column="PassWord" dbType="NVarChar"/>
            <result property="Roles" column="Roles" dbType="NVarChar"/>
            <result property="Depid" column="DepID" dbType="NVarChar"/>
            <result property="Typeid" column="TypeID" dbType="NVarChar"/>
            <result property="Dutyid" column="DutyID" dbType="NVarChar"/>
            <result property="Issys" column="IsSys" dbType="Bit"/>
            <result property="Ulock" column="ULock" dbType="Bit"/>
        </resultMap>
    </resultMaps>里的property同名,ibatis是区分大小写的。

五,ibatis执行insert语句判断是否执行成功的两种方法:
   (1)通过执行return sqlMap.Insert(NAME_SPACE + "Insert", userRntity);判断返回的数据库主键,如果返回的是null表示insert失败,否则insert成功,因为主键有int和string等多种类型所以返回值是object类型。
   (2)执行调用sqlMaps[i].Update(statementName, parameterObject);方法,虽然调用的是update方法,但是却是执行的insert语句,注意xml文件的节点写法:(因为是用id属性所以有两个<update>没有关系)。
     <update id="Insert" parameterClass="SysAuthUsers">
            INSERT INTO [dbo].[sys_auth_Users] (
              [Code]
            , [UserName]
            , [PassWord]
            , [Roles]
            , [DepID]
            , [TypeID]
            , [DutyID]
            , [IsSys]
            , [ULock]
            ) VALUES (
              #Code,dbType=NVarChar#
            , #Username,dbType=NVarChar#
            , #Password,dbType=NVarChar#
            , #Roles,dbType=NVarChar#
            , #Depid,dbType=NVarChar#
            , #Typeid,dbType=NVarChar#
            , #Dutyid,dbType=NVarChar#
            , #Issys,dbType=Bit#
            , #Ulock,dbType=Bit#
            )
      </update>

        <update id="Update" parameterClass="SysAuthUsers">
            UPDATE [dbo].[sys_auth_Users] SET
            [Code] = #Code,dbType=NVarChar#
            , [UserName] = #Username,dbType=NVarChar#
            , [PassWord] = #Password,dbType=NVarChar#
            , [Roles] = #Roles,dbType=NVarChar#
            , [DepID] = #Depid,dbType=NVarChar#
            , [TypeID] = #Typeid,dbType=NVarChar#
            , [DutyID] = #Dutyid,dbType=NVarChar#
            , [IsSys] = #Issys,dbType=Bit#
            , [ULock] = #Ulock,dbType=Bit#
            WHERE
            ([ID] = #Id,dbType=Int#)
        </update>

六,Ibatis.net里的缓存解决方案:
        IBatis.Net学习笔记四--数据库的缓存模式

在IBatis中提供了数据库缓存的模式,可以提高访问效率。对于一些不常更新的表可以直接利用IBatis的缓存方式。

要使用IBatis的数据库缓存,只要利用配置文件就可以了,实现起来比较简单:
        <select id="GetCachedAccountsViaResultMap"
                    resultMap="account-result"
                    cacheModel="account-cache" >
            select *
            from Accounts
            order by Account_ID
        </select>
最主要的就是cacheModel="account-cache",指定缓存的方式,如下,是具体配置缓存的地方:
    <cacheModels>
        <cacheModel id="account-cache" implementation="MEMORY" >
            <flushInterval hours="24"/>
            <flushOnExecute  statement="UpdateAccountViaInlineParameters"/>
            <flushOnExecute  statement="UpdateAccountViaParameterMap"/>
      <flushOnExecute  statement="InsertAccountViaParameterMap"/>
      <property name="Type" value="Weak"/>
        </cacheModel>       
    </cacheModels>

其中:implementation="MEMORY"是设置缓存的实现方式,可以指定LRU、FIFO等,有点类似于内存的页替换策略。MEMORY是最常使用的一种方式。

flushOnExecute设置的是当执行了这些语句时更新缓存。

配置好之后我进行了一个简单的测试,基本上是可以的,但也有一点问题:
1、第一次查询结果是4条记录,当我手工往数据库中插入一条记录时,第二次查询还是4条记录
2、当我把系统时间改成第二天(24小时后),再查,得到的结果是5条记录
3、当我执行了InsertAccountViaParameterMap语句插入一条记录时,再查询得到的是6条记录

也就是说:当系统中的表从不进行手工维护,也不由第三方程序修改时,可以使用数据库缓存的方式提高效率。



七,ibatis下用memocache替换掉ibatis自身的缓存解决方案:momocache的优点参见八,momocache的优点
    近有个项目, 使用Ibatis.net需要部署在负载均衡的环境下, 显然Ibatis.net的内置缓存方式, 是不能适用的.

多个Web服务器之间的缓存不能进行同步是问题的关键. 于是决定扩展他的缓存策略, 使用MemCached.

Ibatis.net现有的缓存方式有: MEMORY, LRU, FIFO, 我们扩展一个叫MemCached的方式.

1. 实现一个ICacheController类, 先要下载一个MemCaced的客户端,

我使用的是enyim.com memcached 1.2.0.2的客户端.

    /// <summary>
    /// 使用MemCached做分布式缓存
    /// </summary>
    public class MemCachedController : ICacheController
    {
        MemcachedClient _mc = null;
        private int _cacheSize = 0;
        private IList _keyList = null;

        /// <summary>
        ///
        /// </summary>
        public MemCachedController()
        {
            _mc = new MemcachedClient();
            _cacheSize = 100;
            _keyList = ArrayList.Synchronized(new ArrayList());
        }

        #region ICacheController Members
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[object key]
        {
            get
            {
                _keyList.Remove(key);
                _keyList.Add(key);
                return _mc.Get(key.ToString());
            }
            set
            {
                _mc.Store(StoreMode.Set, key.ToString(), value);
                _keyList.Add(key);
                if (_keyList.Count > _cacheSize)
                {
                    object oldestKey = _keyList[0];
                    _keyList.Remove(0);
                    _mc.Remove(oldestKey.ToString());
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Remove(object key)
        {
            //object o = _mc.Get(key.ToString());
            _keyList.Remove(key);
            _mc.Remove(key.ToString());
            return null;
        }

        /// <summary>
        ///
        /// </summary>
        public void Flush()
        {
            //_mc.FlushAll();
            foreach (object arr in _keyList)
            {
                _mc.Remove(arr.ToString());
            }
            _keyList.Clear();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="properties"></param>
        public void Configure(System.Collections.IDictionary properties)
        {
            string size = (string)properties["CacheSize"];
            if (size != null)
            {
                _cacheSize = Convert.ToInt32(size);
            }      
        }

        #endregion
    }

如上, 比较简单.

 

2. 第二步在DomSqlMapBuilder类中注册我们的新缓存类型.

            // xionglx添加的使用MemCached

            cacheAlias = new TypeAlias(typeof(MemCachedController));

            cacheAlias.Name = "MEMCACHED";

            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);

 

3. 在SqlMap.xsd配置文件中注册新的类型,

<xs:simpleType>

       <xs:restriction base="xs:NMTOKEN">

                <xs:enumeration value="LRU"/>

                <xs:enumeration value="MEMORY"/>

                <xs:enumeration value="FIFO"/>

                <xs:enumeration value="MEMCACHED"/>

        </xs:restriction>

</xs:simpleType>

 

4. Web.Config中添加配置.

        <!--memcached-->
        <sectionGroup name="enyim.com">
            <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
        </sectionGroup>

<enyim.com>
        <memcached>
            <servers>
                <add address="127.0.0.1" port="11211" />
                <!--<add address="127.0.0.1" port="20004" />-->
            </servers>
            <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:10:00" deadTimeout="00:02:00" />
        </memcached>
    </enyim.com>

 

经过测试, 可以正常的访问MemeCached服务端,  并且缓存正常.

需要注意的是, 实体类需要标记为可序列化.  在Map文件的缓存策略中,

<cacheModels>
        <cacheModel id="ModuleCache"  implementation="MEMCACHED"  readOnly="false">
            <flushInterval hours="24"/>
            <flushOnExecute  statement="Module.Insert"/>
            <flushOnExecute  statement="Module.Update"/>
            <flushOnExecute  statement="Module.Delete"/>
            <property name="CacheSize" value="100"/>
        </cacheModel>
    </cacheModels>

不能使用serialize="true", 反序列化的时候会出错, 我还没仔细查原因. 这里readOnly="false"是说, 这个对象是

会发生更改的, 只有那些系统初始化后, 不会发生变化的数据,才设置成readOnly="true".



八,momocache的优点于却缺点:
   Memcached 是“分布式”的内存对象缓存系统,那么就是说,那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源,即使是UNIX本地连接也一样。在我之前的测试数据中显示,memcached本地读写速度要比直接PHP内存数组慢几十倍,而APC、共享内存方式都和直接数组差不多。可见,如果只是本地级缓存,使用memcached是非常不划算的。

  使用方法:
  Memcached的使用
一 Memcached服务器端的安装 (此处将其作为系统服务安装)
  下载文件:memcached 1.2.1 for Win32 binaries (Dec 23, 2006)
   1 解压缩文件到c:/memcached
   2 命令行输入 'c:/memcached/memcached.exe -d install'
   3 命令行输入 'c:/memcached/memcached.exe -d start' ,该命令启动 Memcached ,默认监听端口为 11211
  通过 memcached.exe -h 可以查看其帮助
二   .NET memcached client library
   下载文件:https://sourceforge.net/projects/memcacheddotnet/

   里面有.net1.1  和 .net2.0的两种版本  还有一个不错的例子。




九,Enterprise Library Caching Application Block缓存方式简析:

在Caching Application Block中,定义了两种缓存类型,它们分别是内存驻留型缓存和磁盘驻留型缓存。顾名思义,这两种类型的缓存是以存贮位置来命名的,功能上则以是否能将缓存数据持久化来区别使用。

在Caching Application Block中,具体提供以下四种保存缓存数据的途径,分别是:内存存储(默认)、独立存储(Isolated Storage)、数据库存储(DataBase Cache Storage)和自定义存储(Custom Cache Storage)。

1、内存存储:内存存储缓存是以上四种方式中唯一的内存驻留型缓存,也是我们开发中最常用到的一种途径,其响应速度快的优势是其它方式无法匹敌的,但单一得采用这种方式的话会有如下弊端:
1)缓存数据不能持久化,服务器重起后缓存数据会全部丢失。
2)服务器采用负载均衡时采用内存缓存的话,一定要保证多台服务器间的内存缓存状态同步,但这样做会对IO造成较大压力,容易造成系统瓶颈,故,从系统性能和开发成本的角度讲,负载均衡的环境下不易单一的采用内存缓存。

2、独立缓存(Isolated Storage):Isolated Storage是缓存数据持久化的一种选择方式,它是磁盘驻留型缓存,如果您足够细心的话会在每一台机器上找到一个IsolatedStorage文件 夹;采用独立缓存的话,我们的缓存信息就会以二进制文件的形式就保存在这个文件夹中,如下是我所用的机器(Vista OS)上生成Cache数据后的缓存信息所在的具体目录:C:/Users/Jon/AppData/Local/IsolatedStorage/ ;
Caching Application Block没有为我们提供向指定机器读、写独立缓存的功能,因此,这种方式只适合需要缓存持久化和大数据量缓存的场合,并不适用于负载均衡的环境。

3、数据库存储(DataBase Cache Storage):如若想采用数据库存储缓存信息,首先第一步要建立缓存数据库Caching,在安装Enterprise Library后并未默认安装此数据库,若想安装,我们首先找到Enterprise Library的安装文件夹,会发现一个建立数据库的CreateCachingDb.cmd文件,执行该文件后您就会在您的SQL-Server上新建 一个名为Caching的数据库,该文件在4.1版中详细地址为:安装盘符:/安装目录/EnterpriseLibary/Blocks /Caching/Src/Database/Scripts/CreateCac控件gDb.cmd文件,在Caching数据库中只有一个 CacheData表,这个表就保存了我们所读写得缓存信息。
4、自定义存储(Custom Cache Storage):关于自定义存储并未深入研究,在此暂不详细讨论.


十、ibatis自带分页api有问题:主要是性能的问题
    在ibatis中有一个很吸引人的方法,queryForPaginatedList(java.lang.String id, int pageSize),可以返回 PaginatedList的对象,
实现翻页,刚才测试了一下PaginatedList,在1-2w行数据的时候还可以工作,但是在一个30w行的表里翻页,一次select用了363.031second
忍不住看了一下源,发现ibatis的分页依赖于数据库的jdbcDriver.

调用次序如下SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList
->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList
->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback
->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()
分页处理的函数如下
Java代码

   1. private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback); throws SQLException { 
   2.     try { 
   3.       request.setResultSet(rs);; 
   4.       ResultMap resultMap = request.getResultMap();; 
   5.       if (resultMap != null); { 
   6.         // Skip Results 
   7.         if (rs.getType(); != ResultSet.TYPE_FORWARD_ONLY); { 
   8.           if (skipResults > 0); { 
   9.             rs.absolute(skipResults);; 
  10.           } 
  11.         } else { 
  12.           for (int i = 0; i < skipResults; i++); { 
  13.             if (!rs.next();); { 
  14.               return; 
  15.             } 
  16.           } 
  17.         } 
  18.  
  19.         // Get Results 
  20.         int resultsFetched = 0; 
  21.         while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults); && rs.next();); { 
  22.           Object[] columnValues = resultMap.resolveSubMap(request, rs);.getResults(request, rs);; 
  23.           callback.handleResultObject(request, columnValues, rs);; 
  24.           resultsFetched++; 
  25.         } 
  26.       } 
  27.     } finally { 
  28.       request.setResultSet(null);; 
  29.     } 
  30.   } 

private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback); throws SQLException {
    try {
      request.setResultSet(rs);;
      ResultMap resultMap = request.getResultMap();;
      if (resultMap != null); {
        // Skip Results
        if (rs.getType(); != ResultSet.TYPE_FORWARD_ONLY); {
          if (skipResults > 0); {
            rs.absolute(skipResults);;
          }
        } else {
          for (int i = 0; i < skipResults; i++); {
            if (!rs.next();); {
              return;
            }
          }
        }

        // Get Results
        int resultsFetched = 0;
        while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults); && rs.next();); {
          Object[] columnValues = resultMap.resolveSubMap(request, rs);.getResults(request, rs);;
          callback.handleResultObject(request, columnValues, rs);;
          resultsFetched++;
        }
      }
    } finally {
      request.setResultSet(null);;
    }
  }


返回的PaginatedList实际上是PaginatedDataList类的对象,每次翻页的时候最后都会调用
Java代码

   1. private List getList(int idx, int localPageSize); throws SQLException { 
   2.    return sqlMapExecutor.queryForList(statementName, parameterObject, (idx); * pageSize, localPageSize);; 
   3.  } 

 private List getList(int idx, int localPageSize); throws SQLException {
    return sqlMapExecutor.queryForList(statementName, parameterObject, (idx); * pageSize, localPageSize);;
  }


这个方法,可见ibatis的分页机制要看jdbcDriver如何实现以及是否支持rs.absolute(skipResults)。
这种实现肯定不如数据库自己支持的分页方式来的快,一旦碰到数据量大的表,马上会死翘翘。

十一、ibatis调用存储过程的方法:
      http://www.cnblogs.com/shineqiujuan/archive/2009/08/09/1542423.html
     
      ibatis处理返回单个记录集的情况没有问题,但是对于多个记录集的情况ibatis接受的时候总是不成功
    暂时的解决办法是:尽量让存储过程返回单个的实体集。



十二、ibatis传递集合对象的使用方法:
      http://dev.firnow.com/course/1_web/javascript/jsjs/20090519/167364.html

十三、DBTimeStamp---》DateTime,在使用ibatis生成sql server数据库的实体对象时DateTime类型生成出错,手动更改成DateTime即可。

十四、ASP.NET后台代码调用前台javascript脚本的几种方法
 
 

很多人都向在服务器端调用客户端的函数来操作,也就是在asp中调用javascript脚本中已经定义好的脚本函数。经过研究,发现了一些勉强的方法。

1. 用Response.Write方法写入脚本

比如在你单击按钮后,先操作数据库,完了后显示已经完成,可以在最后想调用的地方写上
Response.Write("<script type='text/javascript'>alert();</script>");

这个方法有个缺陷就是不能调用脚本文件中的自定义的函数,只能调用内部函数,具体调用自定义的函数只能在Response.Write写上函数定义,比如Response.Write("<script type='text/javascript'>function myfun(){...}</script>");

2.用ClientScript类动态添加脚本

    用法如下:在想调用某个javascript脚本函数的地方添加代码,注意要保证MyFun已经在脚本文件中定义过了。

    ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>MyFun();</script>");

这个方法比Response.Write更方便一些,可以直接调用脚本文件中的自定义函数。

3.普通的添加控件的Attributes属性

对于普通按钮就是:Button1.Attributes.Add("onclick","MyFun();");

只能在Onload中或类似于onload的初始化过程中添加才有效。而且是先执行脚本函数,无法改变执行顺序。

注意,以上所有方法中,后台代码都不能有转化当前页的代码,比如Redirect等,要把转页代码放在脚本里面


十五,ibatis中模糊查询语法
    <isNotEmpty prepend=" " property="Xm" xsi:type="VarChar">
                and xm like '%$Xm$%'
            </isNotEmpty>


十六、aspx.cs类文件需要主要的事项: 
    #region 字段及属性(字段及属性在每次请求相应之后会释放掉类文件,所以这里不应该暂存数据)

    /// <summary>
    /// 页面常用工具类
    /// </summary>
    internal Function fc = new Function();

    #endregion
十六、aspx页面刷新的机制解释:
    刷新是把之前的页面请求重新执行一次,如果上一个请求时load则重新执行一次load,如果上一个请求为提交事件则数据会被重新提交一次。

十七,web页面里不能嵌套form,会导致里提交不出去的的

十八,web一点提交会先执行一遍load方法再执行提交方法里的代码。

十九、ibaits中特殊字符的处理
    iBATIS sql中的处理特殊符号的做法

1.做过html就知道,其实就是xml的特殊符号,需要做个转义
     &lt;          <
     &gt;         >
     &lt;          <
     &gt;         >
     &amp;      &
     &apos;      '
     &quot;      "

2.建议使用<![CDATA[  ]]>符号进行统一说明,将此符号内的任何文本不进行解析
    <![CDATA[  这里写你的sql  ]]>    

3. 处理Like可以用下面的这两种方法
    LIKE #param#||'%' 采li用字符串替换,就是替换参数的值替换param。
    其实同理可以处理其它类似的问题。

二十,sqlmap里配置的设置,Ext**.xml 里如果启用了别名,在节点了要用这个别名。

二十一、asp.net程序,服务器端c#生成一张图片程序发布到iis后报错,原因是iis权限的问题,在站点上右键选择权限,点击添加按钮,输入"ev",确定后把everyone的权限设置成可读可写即可。

二十二、asp.net程序,C#写的一段导出到excel的程序,通过调用excel自身的com实现的,在vs下测试没有出现问题,但是一旦发布到iis里却会报错,原因也是权限的问题:具体解决办法如下:
        检索 COM 类工厂中 CLSID 为{00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005。具体解决方法如下:1:在服务器上安装office的Excel软件.2:在"开始"->"运行"中输入dcomcnfg.exe启动"组件服务"3:依次双击"组件服务"->"计算机"->"我的电脑"->"DCOM配置"4:在"DCOM配置"中找到"Microsoft Excel 应用程序",在它上面点击右键,然后点击"属性",弹出"Microsoft Excel 应用程序属性"对话框5:点击"标识"标签,选择"交互式用户"6:点击"安全"标签,在"启动和激活权限"上点击"自定义",然后点击对应的"编辑"按钮,在弹出的"安全性"对话框中填加一个"NETWORK SERVICE"用户(注意要选择本计算机名),并给它赋予"本地启动"和"本地激活"权限.7:依然是"安全"标签,在"访问权限"上点击"自定义",然后点击"编辑",在弹出的"安全性"对话框中也填加一个"NETWORK SERVICE"用户,然后赋予"本地访问"权限.这样,我们便配置好了相应的Excel的DCOM权限.注意:这是在WIN2003上配置的,在2000上,可能是配置ASPNET用户由于EXCEL是在服务器上打开的,所以应该写一个把导出数据保存在服务器上,然后再传递给客户端的方法,最后每次调用这个功能的时候再删除以前在服务器上所生成的所有Excel

二十三:C#的TrimEnd方法的使用记录
  // edited by luyongchao at 20110722 TrimStart 用法有误会  
            /*
             * Trim("abcd".ToCharArray())就是删除字符串头部及尾部出现的a或b或c或d字符,删除的过程直到碰到一个既不是a也不是b也不是c也不是d的字符才结束。
             * 这里最容易引起的误会就是以为删除的是"abcd"字符串。如下例:
             *    string s = " from dual union all ";
                   s = s.Trim().TrimEnd("union all".ToCharArray());
                  可能有人以为上面s的最终结果是"from dual",但真正的结果是"from d"。需要注意的是这种写法执行的删除对象是字符数组中出现的任意字符,而不是这些字符连在一起组成的字符串!  
             */

二十四:js下控制textbox控件的可用性:
            var RadioButtonDefault = document.getElementById('RadioButtonDefault');
            var TextBoxJYL = document.getElementById('TextBoxJYL');
            
            if(RadioButtonDefault.check==false)
            {
                TextBoxJYL.removeAttribute("disabled");
            }
            else {
                TextBoxJYL.setAttribute("disabled","true");
            }


二十五:web里userControl跟主页面可以通过事件的调用来交互:
     MyUserControl myUserControl = LoadControl("MyUserControl.ascx") as MyUserControl;
            if (myUserControl != null)
            {
                myUserControl.MyEvent += new MyUserControl.MyEventHandler(userControlBtnClick);
                this.PlaceHolder1.Controls.Add(myUserControl);
            }
二十六:web页面校验有两种CSASPNETPageValidationClientSide.aspx、CSASPNETPageValidationServerSide.aspx,
 <asp:Label ID="lbl_email" runat="server" Text="Your current email address:"></asp:Label>
            <asp:TextBox ID="tb_email" runat="server"></asp:TextBox>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="tb_email"
                ErrorMessage="Required field cannot be left blank." Display="Dynamic" ></asp:RequiredFieldValidator>
            <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="Invalid email address."
                ControlToValidate="tb_email" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
                Display="Dynamic"></asp:RegularExpressionValidator>
Use:

The sample demonstrates how to use ASP.NET validation control.
There are two ways to use ASP.NET validation controls: Server-side or
Client-side. The client side validation has greater performance, because it
does not do some postback. If clients do not support client-side validation,
we can use the server side validation instead.
二十七:asp.net的导入导出功能代码
    导出
   using (OleDbConnection conn = new OleDbConnection("excel路径"))
            {
                // Create a new sheet in the Excel spreadsheet.
                OleDbCommand cmd = new OleDbCommand("create table Person(LastName varchar(50), FirstName varchar(50),PersonCategory varchar(50))", conn);

                // Open the connection.
                conn.Open();   //一open就会创建一个excel文件

                // Execute the OleDbCommand.
                cmd.ExecuteNonQuery();

                cmd.CommandText = "INSERT INTO Person (LastName, FirstName,PersonCategory) values (?,?,?)";

                // Add the parameters.
                cmd.Parameters.Add("LastName", OleDbType.VarChar, 50, "LastName");
                cmd.Parameters.Add("FirstName", OleDbType.VarChar, 50, "FirstName");
                cmd.Parameters.Add("PersonCategory", OleDbType.VarChar, 50, "PersonCategory");

                // Initialize an OleDBDataAdapter object.
                OleDbDataAdapter da = new OleDbDataAdapter("select * from Person", conn);

                // Set the InsertCommand of OleDbDataAdapter,
                // which is used to insert data.
                da.InsertCommand = cmd;

                // Changes the Rowstate()of each DataRow to Added,
                // so that OleDbDataAdapter will insert the rows.
                foreach (DataRow dr in dtSQL.Rows)
                {
                    dr.SetAdded();
                }

                // Insert the data into the Excel spreadsheet.
                da.Update(dtSQL);

            }
二十八:.net异常的处理:
    Good:
// C# sample:
try
{
    ... // Do some reading with the file
}
catch
{
    file.Position = position; // Unwind on failure
throw; // Rethrow    这里需要注意不要写成throw ex;仅仅写throw; 可以保证异常stack不丢失
}

二十九:微软企业类库5.0简介:
微软Pattern&Practices小组日前发布了 Enterprise Library 5.0,这是一套应用程序模块,可以用来为企业应用程序构建模块,它是微软关于如何编写良好的应用程序的指导。该类库包含了大量的改善,包括Unity 2.0,以及对.NET 4.0的支持。

Microsoft Enterprise Library 5.0包含了能够用于为企业应用构建应用程序模块的源代码。这些代码可以直接使用,也可以根据需要进行修改或者扩展。这套类库的主要目的是为开发者提供如何编写良好代码的指导。类库使用像插件和依赖注入等设计模式构建,公用的功能被封装在Enterprise Library Core中,它使用统一的协定进行命名和设定版本,所有的应用模块都经过了检测,并且从最初的设计阶段开始就在其中包含了单元测试。

The Enterprise Library contains the following application blocks:

Enterprise Library中包含了下列应用程序模块:

    缓存——通过内存或者数据库中的存储提供本地缓存
    加密——为多家提供商的加密方案提供了支持
    数据访问——为最常用的ADO.NET特性——像存储过程、嵌入式的SQL命令、管理连接、缓存参数——提供支持。
    异常处理——提供了很多处理器,用来处理最一般的异常:包装、替换、记录日志、错误契约(WCF)等等。
    日志——帮助我们处理日志信息的格式,并且提供了各种各样的方式来记录日志:事件、email、数据库、消息队列、文本文件、WMI、自定义方式等等、
    策略注入——帮助我们基于交叉关系为对象的行为发出警告。它是构建在DI容器Unity之上的。
    安全——帮助开发者处理授权和认证的问题。
    验证——对来自于其他用户或者系统的输入的验证提供支持。是用来验证实体不是用来验证ui的
    Unity依赖注入和侦听——它是依赖注入的容器,最初是独立发布的(1.0),现在对其进行了改善并包含在这个库中。

针对上个版本,此版本的企业库所做的改善有:

    从架构上对其进行了重构,从而得到更好的可测试性和可维护性。
    它包含了Unity,这是一个DI容器,可以由用户选择另外的容器来替换。
    支持编程式的配置
    拥有异步的数据访问机制
    合并了WPF的验证机制
    更好的日志记录性能
    支持.NET 4.0

企业库可以用在32位和64位的计算机上,但是没有在Windows XP上测试通过,并且在它所支持的操作系统的列表中也没有提到XP。尽管如此,Grigori Melnik 并没有发现不能在XP上基于.NET 3.5或者.NET 4.0使用此类库的原因。

Melnik 还提到pattern & practices团队试图与之前的版本保持兼容,但是还是存在一些不兼容的变更。


三十:jquery
vs 下jquery是可以有智能提示的  大体是要把jquery-1.4.1-vsdoc.js配置到Site.Master里面去


三十一:
    
    
三十二:vs2008下开启视警告为错误,可以完成一些代码校验的工作,举一个应用场景:“public方法没有xml的注释”,这个方法太有用了,哈哈。
    在项目通过使用了警告即错误的方式达在一定程度上达到了控制代码质量的目的,需要设置三个地方:
        “项目属性---》生成---》降警告视为错误(选择'全部'或者'特定警告')”
        “项目属性---》生成---》输出(Xml文档文件要打上对勾)”
        “项目属性---》代码分析--》第一项(生成时启用代码分析)不打勾,第二项(禁止显示所生成代码的结果)打勾;在设置list里自己需要检                   测的代码规则”

三十三:解决方案文件夹的使用
        step1:修改sln文件,使得解决方案里可以看到文件夹
        step2:右键添加已有项点击"选择项",把dll添加进来
        step3:各个项目从统一的地方添加应用

三十四:使用spring.web可以不用每个页面都添加一段脚本,可以添加到web.config里
    <pages theme="Spring">
            <controls>
                <add tagPrefix="spring" namespace="Spring.Web.UI.Ckey });
mbly="Spring.Web"/>
            </controls>
        </pages>

三十五:spring.net.dao 配置文件中 dao.xml及server.xml中节点对应关系是不区分大小写的


三十六:spring可以适用编程的方式实现回滚:
14.6. 编程方式的事务管理
Spring.NET提供了两种方法来进行编程式事务管理:

使用TransactionTemplate类

直接使用IPlatformTransactionManager的实现类

如果您要使用编程方式进行事务管理,Spring团队推荐使用第一种方式(即使用TransactionTemplate类)。

14.6.1. 使用TransactionTemplate
TransactionTemplate的工作方式与Spring.NET的其它模板类如AdoTemplate和HibernateTemplate相同。它使用回调方法将应用程序的代码从样板式的准备工作和资源管理中解放出来。如果使用System.Transaction的话就必须自己处理这些烦人的工作。使用TransactionTemplate时,提交是默认的行为,异常则会触发自动回滚,不需要使用TransactionScope来手工的进行提交或回滚。

同Spring.NET中其它模板类一样,TransactionTemplate的对象是线程安全的。

如果需要在事务环境中执行,应用程序必须使用如下的代码。注意ITransactionCallback可以用来返回某个值:

TransactionTemplate tt = new TransactionTemplate(TransactionManager);

string userId = "Stewie";

object result = tt.Execute(delegate {
                             dao.UpdateOperation(userId);
                             return dao.UpdateOperation2();
                           });

三十七:spring.net支持的数据库:
DbProviderFactory类利用给定的Provider名称创建IDbProvider对象。在为IDbProvider对象设置了连接字符串以后,就可以用它来创建IDbConnection对象。Provider名称和对应的数据库如下所示。

SqlServer-1.1:Microsoft SQL Server,provider V1.0.5000.0,用于.NET框架V1.1。

SqlServer-2.0(System.Data.SqlClient的别名):Microsoft SQL Server,provider V2.0.0.0,用于.NET框架V2.0。

OleDb-1.1:OleDb,provider V1.0.5000.0,用于.NET框架V1.1。

OleDb-2.0(System.Data.OleDb的别名):OleDb,provider V2.0.0.0,用于.NET框架V2.0。

OracleClient-2.0(System.Data.OracleClient的别名):Oracle,Microsoft provider V2.0.0.0。

OracleODP-2.0(System.DataAccess.Client的别名):Oracle, Oracle provider V2.102.2.20。

MySql:MySQL, MySQL provider 1.0.7.3007(按:Spring.NET的当前版本(1.1 Preview3)需要MySqlConnector 1.0.7.30072,您可以从MySql的网站上单独下载,当然您也可以修改Spring.Data以使用1.08 RC或5.02beta版。)

你可能感兴趣的:(Web,数据库,ibatis,memcached,Microsoft,PostBack)