<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_无常</title><subtitle type="text">记录无常工作上的点点滴滴</subtitle><id>http://feed.cnblogs.com/blog/u/4402/rss</id><updated>2011-11-22T14:39:13Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/4402/rss"/><entry><id>http://www.cnblogs.com/wuchang/archive/2011/11/22/2259540.html</id><title type="text">使用MSBUILD 构建时出错 error MSB3086: Task could not find &amp;quot;sgen.exe&amp;quot; using the SdkToolsPath</title><summary type="text">如果项目有添加有WB引用，比如引用其它网站的WEB服务等，那么VS在编译时会自动生成个 [项目名称].Serializers.dll的文件，就是把引用服务中的相关对象信息生成硬编码的程序集，以提高效率。 但是，如果在远程服务器上使用msbuil构建时，服务器上如果没安装有winsdk，那么构建就会失败，出现类似这样的信息： (GenerateSerializationAssemblies ta...</summary><published>2011-11-22T14:39:00Z</published><updated>2011-11-22T14:39:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/11/22/2259540.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/11/22/2259540.html"/><content type="html">&lt;p&gt;如果项目有添加有WB引用，比如引用其它网站的WEB服务等，那么VS在编译时会自动生成个 [项目名称].Serializers.dll的文件，就是把引用服务中的相关对象信息生成硬编码的程序集，以提高效率。&lt;/p&gt;  &lt;p&gt;但是，如果在远程服务器上使用msbuil构建时，服务器上如果没安装有winsdk，那么构建就会失败，出现类似这样的信息：&lt;/p&gt;  &lt;pre&gt;(GenerateSerializationAssemblies target) -&amp;gt;&#xD;
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;Microsoft.Common.targets(2249,9): &#xD;
error MSB3086: Task could not find &amp;quot;sgen.exe&amp;quot; using the SdkToolsPath &amp;quot;&amp;quot; or &#xD;
the registry key &#xD;
&amp;quot;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A&amp;quot;. &#xD;
Make sure the SdkToolsPath is set and the tool exists in the &#xD;
correct processor specific location under the SdkToolsPath and that&#xD;
the Microsoft Windows SDK is installed &lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;font color="#242626"&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;font color="#242626"&gt;解决办法是在在项目的属性设置窗口中把 Generate serialization assembly: 设置为 Off。&lt;/font&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;font color="#242626"&gt;from : &lt;a href="http://blog.lizj.me"&gt;http://blog.lizj.me&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;font color="#242626"&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/2259540.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/11/22/2259540.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/11/21/2257737.html</id><title type="text">PPTPD默认MTU太大引起一些网站上不了的问题</title><summary type="text">代理服务器更换centos6半月有余，更换后发现wint系统拨号后访问 sina.com.cn / iciba.com / 360.com 等部分网站时页面打不开，而在服务器上或和机房内直接用通过服务器做网关的其它机器都能正常访问，一直不到其解。 今晚搜索了一下，找到些资料，发现是PPTPD默认的MTU太大，导致链路上有些设备堵塞。 解决思路就是把MTU改小些，方法大概有三种： 一、如果开启...</summary><published>2011-11-21T14:23:00Z</published><updated>2011-11-21T14:23:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/11/21/2257737.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/11/21/2257737.html"/><content type="html">&lt;p&gt;代理服务器更换centos6半月有余，更换后发现wint系统拨号后访问 sina.com.cn / iciba.com / 360.com 等部分网站时页面打不开，而在服务器上或和机房内直接用通过服务器做网关的其它机器都能正常访问，一直不到其解。&lt;/p&gt;  &lt;p&gt;今晚搜索了一下，找到些资料，发现是PPTPD默认的MTU太大，导致链路上有些设备堵塞。&lt;/p&gt;  &lt;p&gt;解决思路就是把MTU改小些，方法大概有三种：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;一、如果开启了iptables的（验证过可行）&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;iptables -A FORWARD -p tcp --syn -s &lt;font color="#ff0000"&gt;&lt;strong&gt;10.0.0.0/24&lt;/strong&gt;&lt;/font&gt; -j TCPMSS --set-mss 1356    &lt;br /&gt;其中粗体部分换上你的pptp client的IP段&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;二 、在 /etc/ppp/ip-up 中，exit 0行前添加 (验证过可行)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;ifconfig $1 mtu 1356&lt;/p&gt;  &lt;p&gt;看到ip-up中有一行：    &lt;br /&gt;[ -x /etc/ppp/ip-up.local ] &amp;amp;&amp;amp; /etc/ppp/ip-up.local &amp;quot;$@&amp;quot;     &lt;br /&gt;所以也在 ip-up.local文件中添加ifconfig $1 mtu 1356也同效。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;三、在PPTPD配置文件中设置：&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;打开/etc/ppp/options.pptpd    &lt;br /&gt;在文件最后添加 mtu1356&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;出处： blog.lizj.me&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;相关的资料：&lt;/p&gt;  &lt;p&gt;用WindowsXP拨入pptpd搭建的VPNServer后传输大包有问题&lt;a href="http://os.chinaunix.net/a2006/0205/955/000000955488.shtml"&gt;http://os.chinaunix.net/a2006/0205/955/000000955488.shtml&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Fedora core 2下建立Poptop服务器以及常见问题    &lt;br /&gt;&lt;a href="http://fanqiang.chinaunix.net/app/other/2005-09-13/3655.shtml"&gt;http://fanqiang.chinaunix.net/app/other/2005-09-13/3655.shtml&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/2257737.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/11/21/2257737.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/10/04/2199018.html</id><title type="text">CentOS 6.0 安装配置rails 2.3.11 + redmine 1.2.1 笔记</title><summary type="text">没想到安装过程这么曲折，gem安装时下载经常是不成功的，无耐只好把.gem文件下载回来再本地安装，加上radmine 1.2.1对各组件的版本了也比较挑剔，中间走了不少弯路，折腾了二天时间，终于摸清路子。顺便把安装方法记录下来。0.安装相关的软件包 1:# yum install httpd httpd-devel openssl-devel\ zlib-devel gcc gcc-c++ curl-devel subversion -y1.安装MySql数据库安装MySQL ，并设置为开机自动启动。 1: # yum install mysql mysql-devel mysql-...</summary><published>2011-10-04T09:33:00Z</published><updated>2011-10-04T09:33:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/10/04/2199018.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/10/04/2199018.html"/><content type="html">&lt;p&gt;没想到安装过程这么曲折，gem安装时下载经常是不成功的，无耐只好把.gem文件下载回来再本地安装，加上radmine 1.2.1对各组件的版本了也比较挑剔，中间走了不少弯路，折腾了二天时间，终于摸清路子。顺便把安装方法记录下来。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;0.安装相关的软件包&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:#&lt;/span&gt; yum install httpd httpd-devel openssl-devel\&lt;br /&gt; zlib-devel gcc gcc-c++  curl-devel subversion -y&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.安装MySql数据库&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;安装MySQL ，并设置为开机自动启动。&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; # yum install mysql mysql-devel mysql-server&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:&lt;/span&gt; # chkconfig --levels 235 mysqld on&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:&lt;/span&gt; # /etc/init.d/mysqld start&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;创建Redmine数据库，执行mysql -u root -p登录mysql，在mysql&amp;gt;命令行中输入如以下sql代码：&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;DATABASE&lt;/span&gt; redmine &lt;span style="color: #0000ff;"&gt;CHARACTER&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;SET&lt;/span&gt; utf8 &lt;span style="color: #0000ff;"&gt;COLLATE&lt;/span&gt; utf8_general_ci;&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;USER&lt;/span&gt; &lt;span style="color: #006080;"&gt;'redmine'&lt;/span&gt;@&lt;span style="color: #006080;"&gt;'localhost'&lt;/span&gt; IDENTIFIED &lt;span style="color: #0000ff;"&gt;BY&lt;/span&gt; &lt;span style="color: #006080;"&gt;'redmine'&lt;/span&gt;;&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;GRANT&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;ALL&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;ON&lt;/span&gt; redmine.* &lt;span style="color: #0000ff;"&gt;TO&lt;/span&gt; &lt;span style="color: #006080;"&gt;'redmine'&lt;/span&gt;@&lt;span style="color: #006080;"&gt;'localhost'&lt;/span&gt;;&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;p&gt;添加一个数据库readmine，创建一个用户登录用户redmine，密码和用户名相同，并且授权访问redmine数据库。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span color="#666666" style="color: #666666;"&gt;注：mysql安装后默认root是没设置密码的，如果要改root密码，执行 usr/bin/mysqladmin -u root password 'new-password' 修改。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.安装Ruby 1.8.7&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下载Ruby1.8.7源码编译安装，建个临时目录存放安装过程需要下载的文件&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:#&lt;/span&gt; mkdir ~/rails_install&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:#&lt;/span&gt; cd ~/redmine_install&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:#&lt;/span&gt; wget ftp:&lt;span style="color: #008000;"&gt;//ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p352.tar.gz &lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum4"&gt;   4:#&lt;/span&gt; tar zxvf ruby-1.8.7-p352.tar.gz &lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum5"&gt;   5:#&lt;/span&gt; cd ruby-1.8.7-p352&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum6"&gt;   6:#&lt;/span&gt; ./configure &lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum7"&gt;   7:#&lt;/span&gt; make&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum8"&gt;   8:#&lt;/span&gt; make install&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;安装成功后执行 ruby &amp;ndash;v 可看到ruby的版本信息，如： &lt;br /&gt;ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.安装RubyGems&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个比较挑剔，在redmine安装指导（&lt;a href="http://www.redmine.org/projects/redmine/wiki/RedmineInstall"&gt;http://www.redmine.org/projects/redmine/wiki/RedmineInstall&lt;/a&gt;）中提到有要求，要在1.3.7 ~ 1.7.0之间，这里我选择了1.6.2版。同样是下载源码安装。&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:#&lt;/span&gt; cd ~/rails_install&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:#&lt;/span&gt; wget http:&lt;span style="color: #008000;"&gt;//rubyforge.org/frs/download.php/74445/rubygems-1.6.2.tgz&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:#&lt;/span&gt; tar zxvf rubygems-1.6.2.tgz&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum4"&gt;   4:#&lt;/span&gt; cd rubygems-1.6.2&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum5"&gt;   5:#&lt;/span&gt; ruby setup.rb&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;安装成功后，执行gem &amp;ndash;v ，可看到版本信息。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.安装Rails及相关gems&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果直接用gem install xxx 安装的，大都都安装不成功，不知是我这边网络问题还是其它原因，所以只好把用到的文件都下载回来再本地安装。&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; # cd ~/rails_install&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:&lt;/span&gt; # wget http://rubygems.org/downloads/rake-0.8.3.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:&lt;/span&gt; # wget http://rubygems.org/downloads/rack-1.1.0.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum4"&gt;   4:&lt;/span&gt; # wget http://rubygems.org/downloads/rails-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum5"&gt;   5:&lt;/span&gt; # wget http://rubygems.org/downloads/activesupport-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum6"&gt;   6:&lt;/span&gt; # wget http://rubygems.org/downloads/activerecord-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum7"&gt;   7:&lt;/span&gt; # wget http://rubygems.org/downloads/actionpack-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum8"&gt;   8:&lt;/span&gt; # wget http://rubygems.org/downloads/actionmailer-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum9"&gt;   9:&lt;/span&gt; # wget http://rubygems.org/downloads/activeresource-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum11"&gt;  11:&lt;/span&gt; # wget http://rubygems.org/downloads/i18n-0.4.2.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum12"&gt;  12:&lt;/span&gt; # wget http://rubygems.org/downloads/mysql-2.8.1.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum13"&gt;  13:&lt;/span&gt; # wget http://rubygems.org/downloads/cgi_multipart_eof_fix-2.5.0.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum14"&gt;  14:&lt;/span&gt; # wget http://rubygems.org/downloads/coderay-1.0.0.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum15"&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum16"&gt;  16:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; rake-0.8.3.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum17"&gt;  17:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; rack-1.1.0.gem &lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum18"&gt;  18:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; rails-2.3.11.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum19"&gt;  19:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; mysql-2.8.1.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum20"&gt;  20:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; i18n-0.4.2.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum21"&gt;  21:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; cgi_multipart_eof_fix-2.5.0.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum22"&gt;  22:&lt;/span&gt; # gem  install --&lt;span style="color: #0000ff;"&gt;local&lt;/span&gt; coderay-1.0.0.gem&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;安装成功后运行rails可以看到相应的版本信息&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.安装&lt;strong&gt;Redmine 1.2.1&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;使用svn下载Redmine 1.2源码到/var/www目录中&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; # svn co http://redmine.rubyforge.org/svn/branches/1.2-stable /var/www/redmine1.2&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;redmine数据库配置，将config目录下的数据库配置模板复制一份&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:#&lt;/span&gt; cd /var/www/redmine1.2/&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:#&lt;/span&gt; cp config/database.yml.example config/database.yml&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:#&lt;/span&gt; nano config/database.yml&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;打开复制出来的database.yml文件，配置production节点的mysql登录信息。&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; production:&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:&lt;/span&gt;   adapter: mysql&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:&lt;/span&gt;   database: redmine&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum4"&gt;   4:&lt;/span&gt;   host: localhost&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum5"&gt;   5:&lt;/span&gt;   username: redmine&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum6"&gt;   6:&lt;/span&gt;   password: redmine&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;生成session存储加密信息和数据库&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; # cd /var/www/redmine1.2&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:&lt;/span&gt; # rake config/initializers/session_store.rb&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum3"&gt;   3:&lt;/span&gt; # RAILS_ENV=production rake db:migrate&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum4"&gt;   4:&lt;/span&gt; # RAILS_ENV=production rake redmine:load_default_data&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;在执行最后一行命令时，会提示选择语言种类，输入 zh 回车即可，如果直接回车确则认默认为英文。&lt;/p&gt;&#xD;
&lt;p&gt;运行redmine&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:#&lt;/span&gt; cd /var/www/redmine1.2&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum2"&gt;   2:#&lt;/span&gt; ruby script/server webrick -p 8000 -e production&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;即可以在浏览器中输入 &lt;a href="http://[服务器IP]:8000"&gt;http://[服务器IP]:8000&lt;/a&gt; 访问redmine，默认的管理登录用户名和密码都为 admin，界面如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/201110/201110041730414111.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wuchang/201110/201110041730451207.png" width="644" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;要注意的是，centos默认是打开iptables服务的，所以要远程访问还要在iptables中添加一个放行规则。 &lt;br /&gt;# nano /etc/sysconfig/iptables &lt;br /&gt;在 -A INPUT -j REJECT&amp;nbsp; 这行前添加&lt;/p&gt;&#xD;
&lt;div id="codeSnippetWrapper"&gt;&#xD;
&lt;div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #606060;" id="lnum1"&gt;   1:&lt;/span&gt; -A INPUT -m state --state NEW -m tcp -p tcp --dport 8000 -j ACCEPT&lt;/pre&gt;&#xD;
&lt;!--CRLF--&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;然后再重启iptables服务，使修改生效。&lt;/div&gt;&#xD;
&lt;p&gt;# service iptables restart&lt;/p&gt;&#xD;
&lt;p&gt;这样就可以远程访问了。&lt;/p&gt;&#xD;
&lt;p&gt;PS:&lt;/p&gt;&#xD;
&lt;p&gt;想省事的同学可以直接在这里&lt;a href="http://bitnami.org/stack/redmine"&gt;http://bitnami.org/stack/redmine&lt;/a&gt;下载个VMWave虚拟机文件加载就可以了，也有for win的整体安装包。&lt;/p&gt;&#xD;
&lt;p&gt;出处：&lt;a href="http://wuchang.cnblogs.com"&gt;http://wuchang.cnblogs.com&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;参考： &lt;br /&gt;&lt;a href="http://www.redmine.org/projects/redmine/wiki/RedmineInstall"&gt;http://www.redmine.org/projects/redmine/wiki/RedmineInstall&lt;/a&gt; &lt;br /&gt;&lt;a href="http://www.bilot.com/?p=917"&gt;http://www.bilot.com/?p=917&lt;/a&gt; &lt;br /&gt;&lt;a href="http://endo.homeunix.net/~endo/mywiki/index.php?CentOS6.0%E3%81%A7Redmine"&gt;http://endo.homeunix.net/~endo/mywiki/index.php?CentOS6.0%E3%81%A7Redmine&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/2199018.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/10/04/2199018.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/05/30/2062490.html</id><title type="text">MVC3中实现验证提示信息多语言支持</title><summary type="text">导言在上一篇博文中提出一种通过自定义验证适配器自定义模验证提示信息的方法，实现了修改System.ComponentModel.DataAnnotations中提供的默认验证信息，但此方法是把提示信息写死在代码中，不够灵活，比如要多语言支持的情况下，就无能为力了。本文便继续加以完善，在上文方法的基础上，实现验证提示信息的多语言支持。改造MyRequiredAttributeAdapter即是要实现多语言支持，那么提示信息就不能写死在适配器中了。多语言信息内容，一般是保存在独立的XML文件中或者使用ASP.NET中内置的资源文件，本文使用后者。为了实现更灵活的验证信息，参考了这篇博文的方法，使用</summary><published>2011-05-29T16:26:00Z</published><updated>2011-05-29T16:26:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/05/30/2062490.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/05/30/2062490.html"/><content type="html">&lt;p&gt;&lt;strong&gt;导言&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在&lt;a target="_blank" href="http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html"&gt;上一篇博文&lt;/a&gt;中提出一种通过自定义验证适配器自定义模验证提示信息的方法，实现了修改&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx"&gt;System.ComponentModel.DataAnnotations&lt;/a&gt;中提供的默认验证信息，但此方法是把提示信息写死在代码中，不够灵活，比如要多语言支持的情况下，就无能为力了。&lt;/p&gt;&#xD;
&lt;p&gt;本文便继续加以完善，在&lt;a target="_blank" href="http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html"&gt;上文&lt;/a&gt;方法的基础上，实现验证提示信息的多语言支持。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;改造MyRequiredAttributeAdapter&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;即是要实现多语言支持，那么提示信息就不能写死在适配器中了。多语言信息内容，一般是保存在独立的XML文件中或者使用ASP.NET中内置的资源文件，本文使用后者。&lt;/p&gt;&#xD;
&lt;p&gt;为了实现更灵活的验证信息，参考了&lt;a target="_blank" href="http://davybrion.com/blog/2011/04/customizing-asp-net-mvcs-required-property-validation-messages/"&gt;这篇博文&lt;/a&gt;的方法，使用 &amp;ldquo;{CLASSNAME}_{PROPERTY}_required&amp;rdquo;做为资源名保存提示信息，也就是每个类的每个属性都可以指定不同的提示信息。&lt;/p&gt;&#xD;
&lt;p&gt;修改验证适配器：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img height="246" width="600" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300028457695.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;然后在站点全局资源文件目录App_GlobalResources中添加名为 &lt;strong&gt;Message&lt;/strong&gt; 的资源文件，在资源文件中按照&amp;ldquo;{CLASSNAME}_{PROPERTY}_required&amp;rdquo;的格式添加必填验证提示信息比如RegisterModel类的UserName属性的资源名为： RegisterModel_UserName_Required。然后复制填写其它语言版本：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300028475578.png"&gt;&lt;img height="248" width="588" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300028499218.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;至此，实现了从资源文件中获取提示信息的功能。但是HttpContext.GetGlobalResourceObject()方法是根据当前执行线程的文化信息来获取相应语言的资源的，一般是通过站点配置文件的system.web.globalization节点指定当前应用的语言信息，如果没指定则使用操作系统的语言环境设置。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;根据浏览器语言信息显示不同语言的提示信息&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们需要网站智能点，比如中国人访问时显示中文的提示，美国人访问时显示英文的提示信息，当然我们不能先去问下访问网站的人是想看中文还是英文&lt;img src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300025289685.png" alt="微笑"  style="border-style: none;" /&gt; ，但是我们可以从浏览器的语言设置中获取用户的默认语言。&lt;/p&gt;&#xD;
&lt;p&gt;先来实现一个MVC的过滤器，在Action执行前根据用户浏览器语言来设置当前线程的语言文化信息：&lt;/p&gt;&#xD;
&lt;pre &gt;&lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; CultureInfoAttribute : FilterAttribute, IActionFilter&#xD;
    {&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// 站点支持的语言列表&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;readonly&lt;/span&gt; List&amp;lt;&lt;span &gt;string&lt;/span&gt;&amp;gt; AvailableCultures = &lt;span &gt;new&lt;/span&gt; List&amp;lt;&lt;span &gt;string&lt;/span&gt;&amp;gt;&#xD;
        {&#xD;
            &lt;span &gt;"en-US"&lt;/span&gt;,&lt;span &gt;"zh-CN"&lt;/span&gt;&#xD;
        };&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; OnActionExecuting(ActionExecutingContext&#xD;
            filterContext)&#xD;
        {&#xD;
            &lt;span &gt;string&lt;/span&gt; cultureCode = GetBrowserCulture(filterContext);&#xD;
            &lt;span &gt;if&lt;/span&gt; (&lt;span &gt;string&lt;/span&gt;.IsNullOrEmpty(cultureCode) ||&#xD;
                !AvailableCultures.Any(o =&amp;gt; o.Equals(cultureCode, &lt;br /&gt;                         StringComparison.OrdinalIgnoreCase)))&#xD;
            {&#xD;
                &lt;span &gt;return&lt;/span&gt;;&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;try&lt;/span&gt;&#xD;
            {&#xD;
                CultureInfo culture = &lt;span &gt;new&lt;/span&gt; CultureInfo(cultureCode);&#xD;
                System.Threading.Thread.CurrentThread.CurrentCulture = culture;&#xD;
                System.Threading.Thread.CurrentThread.CurrentUICulture = culture;&#xD;
            }&#xD;
            &lt;span &gt;catch&lt;/span&gt; (Exception)&#xD;
            {&#xD;
&#xD;
            }&#xD;
        }&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// 获取浏览器的语言设置&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;param name="filterContext"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; GetBrowserCulture(ActionExecutingContext filterContext)&#xD;
        {&#xD;
            var browerCulture = filterContext.HttpContext.Request.UserLanguages;&#xD;
            &lt;span &gt;if&lt;/span&gt; (browerCulture == &lt;span &gt;null&lt;/span&gt;)&#xD;
            {&#xD;
                &lt;span &gt;return&lt;/span&gt; &lt;span &gt;null&lt;/span&gt;;&#xD;
            }&#xD;
            &lt;span &gt;foreach&lt;/span&gt; (var item &lt;span &gt;in&lt;/span&gt; browerCulture)&#xD;
            {&#xD;
                &lt;span &gt;if&lt;/span&gt; (AvailableCultures.Any(o =&amp;gt; o.Equals(item, &lt;br /&gt;                      StringComparison.OrdinalIgnoreCase)))&#xD;
                {&#xD;
                    &lt;span &gt;return&lt;/span&gt; item;&#xD;
                }&#xD;
            }&#xD;
            &lt;span &gt;return&lt;/span&gt; &lt;span &gt;null&lt;/span&gt;;&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext)&#xD;
        {&#xD;
        }&#xD;
    }&#xD;
然后在程序启动时注册为全局过滤器：&lt;/pre&gt;&#xD;
&lt;pre &gt;&lt;img height="280" width="537" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300027127011.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/pre&gt;&#xD;
&lt;style&gt;&lt;!--&#xD;
.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
--&gt;&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;完成&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;做完这步之后，我们在浏览器中更改不同的语言环境，测试看下效果：&lt;/p&gt;&#xD;
&lt;p&gt;英文：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300026283935.png"&gt;&lt;img height="245" width="487" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300026301785.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;中文：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300026328522.png"&gt;&lt;img height="264" width="484" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105300026343307.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/2062490.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/05/30/2062490.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html</id><title type="text">MVC3中使用验证适配器修改默认的验证提示信息</title><summary type="text">验证MVC中提供的模块验证非常灵活，在System.ComponentModel.DataAnnotations命名空间中提供了常用的一些验证特性，如Required、Compare等。 所有的验证特性都提供有ErrorMessage属性给我们设置自定义的出错提示信息，比如我们可以这样指定必填属性的提示：[Required(ErrorMessage =&amp;quot;请输入用户名&amp;quot;)]。 还可以通过设置ErrorMessageResourceType和 ErrorMessageResourceName属性来使用系统资源文件实现多语言支持（参考：http://haacked.com/arc</summary><published>2011-05-29T06:36:00Z</published><updated>2011-05-29T06:36:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html"/><content type="html">&lt;p&gt;&lt;strong&gt;验证&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;MVC中提供的模块验证非常灵活，在System.ComponentModel.DataAnnotations命名空间中提供了常用的一些验证特性，如Required、Compare等。 所有的验证特性都提供有ErrorMessage属性给我们设置自定义的出错提示信息，比如我们可以这样指定必填属性的提示：[Required(ErrorMessage ="请输入用户名")]。 还可以通过设置ErrorMessageResourceType和 ErrorMessageResourceName属性来使用系统资源文件实现多语言支持（参考：&lt;a href="http://haacked.com/archive/2009/12/12/localizing-aspnetmvc-validation.aspx"&gt;http://haacked.com/archive/2009/12/12/localizing-aspnetmvc-validation.aspx&lt;/a&gt;）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;项目中遇到问题，程序员为了省事验证属性都最简化，比如必填字段只指定了[Required]特性，这样就导致了验证错误提示信息不太直观，比如会这样：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img height="307" width="346" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105291436123624.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&amp;nbsp; &lt;img height="296" width="393" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105291436132162.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;客户比较挑剔，特别指定要消除鸡肠文。按照上文提到的方法，可以给Required.Errormessage指定详细的验证信息，但项目中的实体类较多，一一去修改的话工作量比较大。    &lt;br /&gt;于是寻找捷径&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;验证适配器&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;DataAnnotationsModelValidatorProvider提供有RegisterAdapter和RegisterAdapterFactory二个方法供我们注册自己的验证适配器或适配器工厂类。首先创建一个自己的适配器MyRequiredAttributeAdapter：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img height="198" width="650" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105291436134604.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;从MVC内置的System.Web.Mvc.RequiredAttributeAdapter适配器类继承（RequiredAttributeAdapter的基类y就是DataAnnotationsModelValidator&amp;lt;RequiredAttribute&amp;gt;），覆盖GetClientValidationRules方法，在这里使用自定义的提示文字创建验证规则类。&lt;/p&gt;&#xD;
&lt;p&gt;然后在程序启动时注册此适配器：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img height="176" width="684" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105291436143143.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;编译后再打开页面，提示信息已经全部改变了。    &lt;br /&gt;&lt;img height="298" width="404" src="http://images.cnblogs.com/cnblogs_com/wuchang/201105/201105291436146457.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;省去了一个一个修改的麻烦。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/2062095.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/05/29/2062095.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/02/22/1961359.html</id><title type="text">nginx 截断日志一个批处理</title><summary type="text">net stop nginxtaskkill /F /IM nginx.exeset &amp;quot;cmdstr=rename logs logs%date:~0,4%-%date:~5,2%-%date:~8,2%-%time:~0,2%-%time:~3,2%.log&amp;quot;call %cmdstr%set &amp;quot;cmdstr=md logs &amp;quot;call %cmdstr% net start nginx#pause</summary><published>2011-02-22T07:34:00Z</published><updated>2011-02-22T07:34:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/02/22/1961359.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/02/22/1961359.html"/><content type="html">&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;net stop nginx&lt;/pre&gt;&#xD;
&lt;pre &gt;taskkill /F /IM nginx.exe&#xD;
set "cmdstr=rename logs logs%date:~0,4%-%date:~5,2%-%date:~8,2%-%time:~0,2%-%time:~3,2%.log"&#xD;
&#xD;
call %cmdstr%&#xD;
set "cmdstr=md logs "&#xD;
&#xD;
call %cmdstr% &#xD;
&#xD;
net start nginx&#xD;
#pause&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;img src="http://www.cnblogs.com/wuchang/aggbug/1961359.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/02/22/1961359.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2011/02/15/1955532.html</id><title type="text">在没有安装有mvc3的主机上部署asp.net mvc3网站，需要包含的DLL文件</title><summary type="text">1.在没有安装有mvc3的主机上部署asp.net mvc3网站，需要包含的DLL文件。[代码]2.Sqlite除了需要包含System.Data.SQLite.Dll外，再在web.config中加上：[代码]</summary><published>2011-02-15T12:33:00Z</published><updated>2011-02-15T12:33:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2011/02/15/1955532.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2011/02/15/1955532.html"/><content type="html">&lt;span  style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px;"&gt;&#xD;
&lt;div style="line-height: 1.5; background-color: #ffffff; margin: 8px; font-family: verdana, Arial, Helvetica, sans-serif; color: #000000; font-size: 14px; background-origin: initial; background-clip: initial;"&gt;&#xD;
&lt;p style="text-indent: 0px; margin: 10px auto;"&gt;1.在没有安装有mvc3的主机上部署asp.net mvc3网站，需要包含的DLL文件。&lt;/p&gt;&#xD;
&lt;p style="text-indent: 0px; margin: 10px auto;"&gt;&lt;span  style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px;"&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;microsoft.web.infrastructure.dll&lt;br /&gt;system.web.helpers.dll&lt;br /&gt;system.web.mvc.dll&lt;br /&gt;system.web.razor.dll&lt;br /&gt;system.web.webpages.deployment.dll&lt;br /&gt;system.web.webpages.dll&lt;br /&gt;system.web.webpages.razor.dll&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p style="text-indent: 0px; margin: 10px auto;"&gt;&lt;/p&gt;&#xD;
&lt;p style="text-indent: 0px; margin: 10px auto;"&gt;2.Sqlite除了需要包含System.Data.SQLite.Dll外，再在web.config中加上：&lt;/p&gt;&#xD;
&lt;p style="text-indent: 0px; margin: 10px auto;"&gt;&lt;span  style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px;"&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;system.data&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;DbProviderFactories&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;remove &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;invariant&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="System.Data.SQLite"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;add &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="SQLite Data Provider"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; invariant&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="System.Data.SQLite"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; &lt;br /&gt;    description&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;=".Net Framework Data Provider for SQLite"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; &lt;br /&gt;type&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;DbProviderFactories&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;system.data&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/1955532.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2011/02/15/1955532.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2010/04/11/1709654.html</id><title type="text">ASP.NET MVC 2 RTM client side validation一个隐秘的坑</title><summary type="text">同一相站点，有些页面的客户端验证能工作，而有些死活不行。打开页面就出现&amp;ldquo;Uncaught TypeError: Cannot set property '__MVC_FormValidation' of null&amp;rdquo;错误，Chrome提示： 确定相关JS已经包含在页面中，（用的是MasterPage，二个页面包含的js文件完全相同），排除了js引用路径不正确的问题。页面上生成...</summary><published>2010-04-11T09:59:00Z</published><updated>2010-04-11T09:59:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2010/04/11/1709654.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2010/04/11/1709654.html"/><content type="html">&lt;p&gt;同一相站点，有些页面的客户端验证能工作，而有些死活不行。打开页面就出现&amp;ldquo;Uncaught TypeError: Cannot set property '__MVC_FormValidation' of null&amp;rdquo;错误，Chrome提示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_2.png"&gt;&lt;img height="234" width="533" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;确定相关JS已经包含在页面中，（用的是MasterPage，二个页面包含的js文件完全相同），排除了js引用路径不正确的问题。&lt;/p&gt;&#xD;
&lt;p&gt;页面上生成的mvcClientValidationMetadata也没问题，但客户端验证就是不起作用。&lt;/p&gt;&#xD;
&lt;p&gt;将MicrosoftAjax.js替换成MicrosoftAjax.debug.js。在Chrome调试工具中看到此异常在Sys.UI.DomElement.getElementById函数中抛出&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_12.png"&gt;&lt;img height="253" width="620" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_5.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;在394行加个断点，刷新页面，一步步跟踪，&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_18.png"&gt;&lt;img height="207" width="830" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_8.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;162行，根据ID获取某个DOM对象，在这里看到optionsFormID为null。（Chrome的js调试功能很强），再看到CallStack的上一步。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_16.png"&gt;&lt;img height="149" width="834" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_7.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;这里是在页面加载完成后处理客户端验证的mvcClientValidationMetadata 数据。&lt;/p&gt;&#xD;
&lt;p&gt;跟到这里大概能就猜出问题在哪里了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;查看页面源码，在&amp;lt;/form&amp;gt;节点后的脚本中看到生成的验证代码如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_10.png"&gt;&lt;img height="89" width="428" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_4.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;表单的ID为null！&lt;/p&gt;&#xD;
&lt;p&gt;然后我再打开难进行客户端验证的页面：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_8.png"&gt;&lt;img height="105" width="429" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_3.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;看到差别了，就是因为FormID为null。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;并且他们生成的表单也有所不同：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_6.png"&gt;&lt;img height="80" width="525" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_2.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不能进行客户端验证的Form&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_4.png"&gt;&lt;img height="73" width="517" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_1.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;能进行客户端验证的Form&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;有id的Form能进行客户端验证！&lt;/p&gt;&#xD;
&lt;p&gt;可是二个视图中都是用using (Html.BeginForm()){}生成表单的，没有特意去设置Form ID属性，为何一个有id另一个没id？&lt;/p&gt;&#xD;
&lt;p&gt;杯具！&lt;/p&gt;&#xD;
&lt;p&gt;打开二个视图页面，一个一个排查，最后发现二个视图的差别在这一点：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_22.png"&gt;&lt;img height="144" width="407" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_10.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_20.png"&gt;&lt;img height="144" width="402" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/ASP.NETMVC2RTMclientsidevalidation_E842/image_thumb_9.png" alt="image" border="0" title="image" style="display: inline; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;前都是在BeginForm()之前调用Html.EnableClientValidation();，后BeginForm之后才调用 Html.EnableClientValidation();&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;记住了，想要用mvc client side validation，请在BeginForm()之前调用Html.EnableClientValidation();&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;出处：无常笔记，&lt;a href="http://wuchang.cnblogs.com"&gt;http://wuchang.cnblogs.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/1709654.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2010/04/11/1709654.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2010/04/04/1704456.html</id><title type="text">Python:使用ctypes库调用外部DLL</title><summary type="text">昨天天写的一个小程序的总结。在Python中使用ctypes库调用外部C DLL库的函数，涉及到CDLL中在Python和C的数据类型的对应，使用C语言中struct结构体和回调函数的使用。</summary><published>2010-04-04T15:36:00Z</published><updated>2010-04-04T15:36:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2010/04/04/1704456.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2010/04/04/1704456.html"/><content type="html">&lt;p&gt;&lt;strong&gt;前言&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;朋友的公司是做GPS的，上周联系到我要帮做个程序把他们平台的车辆定位跟踪数据和省里的平台对接。看一下官方提供的三个文档，洋洋洒洒共一百多页，一大堆协议的定义甚是齐全，好在官方的文件中也带有个封装好通信功能的DLL和一个调用此接口的c++ DEMO程序，既然有现成的可用，那就不必去看他的协议了。&lt;/p&gt;&#xD;
&lt;p&gt;说实话，参加工作之后就基本没用过c++，生疏了。特别是要用c++操作数据库，对我来说比割几刀还要痛苦。官方的API中已经很详尽，要做的就是从现有平台的数据库中获取车辆定位信息，通过官方的API发送到省中心平台。&lt;/p&gt;&#xD;
&lt;p&gt;本想用C#给官方API做个包装，省得再去动用C++，可是看到此API中定义有几个Struct，而且下行数据都是通过回调函数方式提供，google了一下，似乎C#对调用有回调函数的C DLL不是很顺畅，于是放弃了，想到了&lt;a href="http://python.org/" target="_blank"&gt;Python&lt;/a&gt;。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;一、Python之ctypes&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://docs.python.org/library/ctypes.html" target="_blank"&gt;ctypes&lt;/a&gt;是&lt;a href="http://python.org/" target="_blank"&gt;Python&lt;/a&gt;的一个外部库，提供和C语言兼容的数据类型，可以很方便地调用C DLL中的函数。在Python2.5官方安装包都带有&lt;a href="http://docs.python.org/library/ctypes.html" target="_blank"&gt;ctypes&lt;/a&gt; 1.1版。ctypes的官方文档在&lt;a href="http://docs.python.org/library/ctypes.html" target="_blank"&gt;这里&lt;/a&gt;。&lt;/p&gt;&#xD;
&lt;p&gt;ctypes的使用非常简明，如调用cdecl方式的DLL只需这样：&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:b1b552ca-3c84-42c7-b5cd-a70541051496" &gt;&#xD;
&lt;pre &gt;from ctypes import *;&#xD;
h=CDLL('msvcrt.dll')&#xD;
h.printf('a=%d,b=%d,a+b=%d',1,2,1+2);&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;以上代码运行后输出 a=1,b=2,a+b=3。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;二、加载库和普通函数的调用&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;官方API提供的库中有几个主要的函数：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:57665f99-448e-4e32-94b4-8c34c4e5b0af" &gt;&#xD;
&lt;pre &gt;//初始化&#xD;
int DCSPCLIENTDLL InitInterface( const char *pCenterIP, const unsigned short nUpLinkSvrPort,const unsigned short nDownLinkSvrPort );&#xD;
&#xD;
//释放资源&#xD;
int DCSPCLIENTDLL FiniInterface( void );&#xD;
&#xD;
//登录&#xD;
int DCSPCLIENTDLL Login( const unsigned int uiBranchPlatformID, const unsigned int nUserID,  const char *pPassword );&#xD;
//注销&#xD;
int DCSPCLIENTDLL Logout( const unsigned int uiBranchPlatformID, const unsigned int nUserID,   const char *pPassword );&#xD;
&#xD;
//发车辆实时定位数据&#xD;
int DCSPCLIENTDLL SendUPRealLocation( const char * const pDeviceId,  const char cDeviceColor,&#xD;
					const unsigned short nMsgCode, const _stBPDynamicData * const pStGpsData );&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在Python中加载使用：&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:429e7718-2d10-40e0-a273-0b95a2747e10" &gt;&#xD;
&lt;pre &gt;from ctypes import *&#xD;
&#xD;
#加载API库&#xD;
api = CDLL('DCSPClientDLL.dll');&#xD;
#初始化函数的参数类型&#xD;
api.InitInterface.argtypes=[c_char_p,c_ushort,c_ushort]&#xD;
api.Login.argtypes=[c_uint,c_uint,c_char_p]&#xD;
api.Logout.argtypes=[c_uint,c_uint,c_char_p]&#xD;
&#xD;
#初始化并登录&#xD;
api.InitInterface(u"中心服务器地址" , u'上行服务端端口' , u'下行客户端端口')&#xD;
api.Login(platformID,userID,password);&#xD;
#.....其它操作&#xD;
api.Logout(platformID,userID,password); #注销&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;参数类型可以像上面的代码一样预先设定好，或者在调用函数时再把参数转成相应的c_***类型。ctypes的类型对应如下:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/PythonctypesDLL_12B8B/image_2.png"&gt;&lt;img style="display: inline; border: 0px;" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/wuchang/WindowsLiveWriter/PythonctypesDLL_12B8B/image_thumb.png" width="538" height="366" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;如此，完成了简单的第一步。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;三、C语言中的Struct数据结构&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在发送实时定位数据的函数SendUPRealLocation中有一个参数是结构体类型 _stBPDynamicData。python中没有struct这种数据结构，ctypes很周全，对C的struct和union这二种数据类型都提供很好的支持。stBPDynamicData结构的定义如下：&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:17e1d796-27b5-4238-b475-505346d2e4eb" &gt;&#xD;
&lt;pre &gt;// 车辆动态数据结构体&#xD;
struct _stBPDynamicData&#xD;
{&#xD;
    // 加密状态&#xD;
    unsigned char encrypt;&#xD;
    // GPS 时间&#xD;
    _StructTime gpsTime;&#xD;
    // 经度&#xD;
    unsigned int  longitude;&#xD;
    // 纬度&#xD;
    unsigned int  latitude;&#xD;
    // GPS速度&#xD;
    unsigned short unGpsSpeed;&#xD;
    // 行驶记录仪速度&#xD;
    unsigned short unTachographSpeed;&#xD;
    // 车辆当前总里程数&#xD;
    unsigned int uiMileageTotal;&#xD;
    // 角度&#xD;
    unsigned short angle;&#xD;
    // 车辆状态&#xD;
    unsigned short state;&#xD;
    // 报警状态&#xD;
    unsigned short alarm;&#xD;
};&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;在python中，需要定义一个与这兼容的类，继承于ctypes.Structure，其中还用到一个_StructTime结构，这里一并贴出代码：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:8fef74f4-4669-460b-88ed-df2ed37253c6" &gt;&#xD;
&lt;pre &gt;class _StructTime(Structure):&#xD;
    _fields_ =[('day',c_ubyte),&#xD;
               ('month',c_ubyte),&#xD;
               ('year',c_ushort),&#xD;
               ('hour',c_ubyte),&#xD;
               ('minute',c_ubyte),&#xD;
               ('second',c_ubyte)];    &#xD;
    def __str__(self):&#xD;
        return '{0}-{1}-{2} {3}:{4}:{5}'.format(self.year,self.month,self.day,self.hour,self.minute,self.second);&#xD;
        &#xD;
class _stBPDynamicData(Structure):&#xD;
    _fields_ =[('encrypt',c_ubyte),&#xD;
               ('gpsTime',_StructTime),             &#xD;
               ('longitude',c_uint),&#xD;
               ('latitude',c_uint),&#xD;
               ('unGpsSpeed',c_ushort),&#xD;
               ('unTachographSpeed',c_ushort),&#xD;
               ('uiMileageTotal',c_uint),&#xD;
               ('angle',c_ushort),&#xD;
               ('state',c_ushort),&#xD;
               ('alarm',c_ushort)];&#xD;
    def __str__(self):&#xD;
        return u'({0},{1}),{6},sp:{2},angle:{3},st:{4},al:{5}'.format(self.longitude,&#xD;
                self.latitude,self.unGpsSpeed,&#xD;
                self.angle ,self.state,self.alarm,self.gpsTime );&#xD;
    &#xD;
class gpsData(Structure):&#xD;
    _fields_ =[('strDeviceID',c_char_p),&#xD;
               ('cDeviceColor',c_char),             &#xD;
               ('nMsgCode',c_ushort),&#xD;
               ('stBPD',_stBPDynamicData)];&#xD;
    def __str__(self):&#xD;
        return u'{0},{1}'.format(self.strDeviceID,self.stBPD );&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;gpsData是我自己加的一个类，用于记录每辆车的信息。&lt;/p&gt;&#xD;
&lt;p&gt;现在就可以使用SendUPRealLocation函数发送车辆实时数据了：&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:0ff1a6cf-34d6-46a6-ba43-3e0651b4f8cf" &gt;&#xD;
&lt;pre &gt;tm=_StructTime();&#xD;
tm.year=2010;tm.month=4;tm.day=3;tm.hour=11;tm.minute=2;tm.second=11;&#xD;
bpd=_stBPDynamicData();&#xD;
bpd.gpsTime=tm;bpd.longitude=1234567;bpd.latitude=246898;#...其它参数&#xD;
data=gpsData();&#xD;
data.strDeviceID=u'桂Coo007';data.stBPD=bpd;&#xD;
#调用 API发送数据&#xD;
api.SendUPRealLocation( data.strDeviceID, data.cDeviceColor ,&#xD;
                        data.nMsgCode, addressof( data.stBPD ) );&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;注意SendUPRealLocation第三个参数是_stBPDynamicData * 指针类型，所以要用ctypes.addressof()取参数的地址。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;四、回调函数&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;写到这里就忍不住唠叨几句，这个系统的协议设计的太有 &amp;ldquo;个性&amp;rdquo;了。这个系统的功能说起来也不复杂，就是要GPS运营商把指定的车辆位置信息发送到中心平台，同时中心平台可以向各GPS终端发送一些数据和指令，比如传送文字信息到终端，或者要求终端拍张照片反馈到中心。&lt;/p&gt;&#xD;
&lt;p&gt;这个协议流程是这样，运营商端主动连接到中心服务器，然后此连接只用于传输向中心平台主动发送的数据。登录成功了之后呢，中心平台再向运营商的IP建立一个连接，用于中心下发的数据和指令。官方称为&amp;ldquo;双链路&amp;rdquo;。&lt;/p&gt;&#xD;
&lt;p&gt;于是，就要求运营商必须要有固定的公网IP（这个不是问题，据了解GPS运营商服务器都有固定IP），而且这个程序必须运行在有公网IP的电脑上或采用端口映射之类的方法。可是俺开发设计时是在大教育局域网中的，搞个端口映射都不可能更别谈公网IP了。于是，在调试下行数据部分功能时就只能远程到运营商服务器上去调试了。&lt;/p&gt;&#xD;
&lt;p&gt;回归正题。&lt;/p&gt;&#xD;
&lt;p&gt;要使用回调函数，需要先用 CFUNCTYPE 定义回调函数的类型，官方API中有十多个回调函数注册，定义摘抄：&#xD;
&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:97af39d9-5115-4628-a105-b4698141e72f" &gt;&#xD;
&lt;pre &gt;#define DCSPCLIENTDLL __declspec(dllexport)&#xD;
&#xD;
typedef void (*pDownTextInfoFv) ( const char *const pDeviceID,&#xD;
                                  const char cDeviceColor, const char *const pInfo );&#xD;
&#xD;
typedef void (*pDownCommunicateReqFv) ( const char *const pDeviceID,&#xD;
                                        const char cDeviceColor,  const char *const pCalledTel );&#xD;
extern "C"&#xD;
{&#xD;
    void DCSPCLIENTDLL RegDownTextInfoFunc( pDownTextInfoFv pFv );&#xD;
    void DCSPCLIENTDLL RegDownCommunicateReqFunc( pDownCommunicateReqFv pFv );&#xD;
};&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在python中，定义相应的类型和回调处理函数：&lt;/p&gt;&#xD;
&lt;div style="margin: 0px; display: inline; float: none; padding: 0px;" id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:681100ee-7fd4-468d-8319-1f6338d5074a" &gt;&#xD;
&lt;pre &gt;"""下发文字信息"""&#xD;
def downTextInfo(pDeviceID,cDeviceColor,pInfo):&#xD;
    print(u'&amp;lt;-[下发文字]:{0},{1}'.format(str(pDeviceID),str(pInfo)) );&#xD;
    r=api.SendUpTextInfoAck(pDeviceID, cDeviceColor, True ); &#xD;
    if r==0:&#xD;
        print(u'-&amp;gt;回复下发文字成功。');&#xD;
    else:&#xD;
        print(u'-&amp;gt;回复下发文字失败。');&#xD;
&#xD;
pDownTextInfoFv = CFUNCTYPE(c_void_p,c_char_p, c_char, c_char_p)  #回调函数类型定义&#xD;
pDownTextInfoHandle = pDownTextInfoFv(downTextInfo);&#xD;
&#xD;
api.RegDownTextInfoFunc(pDownTextInfoHandle);   #注册回调函数&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中SendUpCommunicateAck是回应中心，告知已经收到信息。二个参数类型和downTextInfo中的参数类型一到，所以可以不用初始化声明此函数的参数定义。&lt;/p&gt;&#xD;
&lt;p&gt;其余的回调函数用相同的方法处理。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;结尾&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;调试完API对接部分功能后，在想用哪个py库操作数据库比较方便呢，找了一下之后才想到为何不用ironPython而可以直接使用ado.net访问数据库，岂不是更爽。&lt;/p&gt;&#xD;
&lt;p&gt;于是把代码搬到ironPython2.6中试试，让我十分惊喜的是不用做任何个性代码直接运行成功！&lt;a href="http://ironpython.net/" target="_blank"&gt;ironPython&lt;/a&gt; 2.6中的ctypes和Python2.6的一样都是1.1.0版。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;PS:借用 &lt;a target="_blank" href="http://www.cnblogs.com/JeffreyZhao"&gt;1号园友&lt;/a&gt;的主题和CSS。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;出处：无常笔记 &lt;a href="http://wuchang.cnblogs.com"&gt;http://wuchang.cnblogs.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/1704456.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2010/04/04/1704456.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/wuchang/archive/2010/03/13/1685217.html</id><title type="text">NHibernate+Oracle 遇到ORA-01461和ORA-01084及解决方法</title><summary type="text">如果使用到Oracle的CLOB字段，那么NHibernate会遇到很诡异的&amp;ldquo;ORA-01461:仅可以插入LONG列的LONG值赋值&amp;rdquo;错误。关于此错误的分析和解决方法在这里(http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx)有详细的介绍，实现NHibernate的自定义类型IUserType接口...</summary><published>2010-03-13T12:10:00Z</published><updated>2010-03-13T12:10:00Z</updated><author><name>无常</name><uri>http://www.cnblogs.com/wuchang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/wuchang/archive/2010/03/13/1685217.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/wuchang/archive/2010/03/13/1685217.html"/><content type="html">&lt;p&gt;如果使用到Oracle的CLOB字段，那么NHibernate会遇到很诡异的&amp;ldquo;&lt;strong&gt;ORA-01461:仅可以插入LONG列的LONG值赋值&lt;/strong&gt;&amp;rdquo;错误。关于此错误的分析和解决方法在&lt;a target="_blank" href="http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx"&gt;这里&lt;/a&gt;(&lt;a href="http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx"&gt;http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx&lt;/a&gt;)有详细的介绍，实现NHibernate的自定义类型IUserType接口 ：&lt;/p&gt;&#xD;
&lt;div  id="scid:910B5D6B-F5A5-4108-B1A2-B97D2D405F5A:8ce12bf3-99e1-4f71-b4c2-d4d178b65f93" style="margin: 0px; display: inline; float: none; padding: 0px;"&gt;&#xD;
&lt;pre &gt;public abstract class PatchForOracleLobField : IUserType&#xD;
    {&#xD;
        public PatchForOracleLobField()&#xD;
        {&#xD;
        }&#xD;
        public bool IsMutable&#xD;
        {&#xD;
            get { return true; }&#xD;
        }&#xD;
        public System.Type ReturnedType&#xD;
        {&#xD;
            get { return typeof(String); }&#xD;
        }&#xD;
        public SqlType[] SqlTypes&#xD;
        {&#xD;
            get&#xD;
            {&#xD;
                return new SqlType[] { NHibernateUtil.String.SqlType };&#xD;
            }&#xD;
        }&#xD;
        public object DeepCopy(object value)&#xD;
        {&#xD;
            return value;&#xD;
        }&#xD;
        public new bool Equals(object x, object y)&#xD;
        {&#xD;
            return x == y;&#xD;
        }&#xD;
        public int GetHashCode(object x)&#xD;
        {&#xD;
            return x.GetHashCode();&#xD;
        }&#xD;
        public object Assemble(object cached, object owner)&#xD;
        {&#xD;
            return DeepCopy(cached);&#xD;
        }&#xD;
        public object Disassemble(object value)&#xD;
        {&#xD;
            return DeepCopy(value);&#xD;
        }&#xD;
        public object NullSafeGet(IDataReader rs, string[] names, object owner)&#xD;
        {&#xD;
            return NHibernate.NHibernateUtil.StringClob.NullSafeGet(rs, names[0]);&#xD;
        }&#xD;
        public abstract void NullSafeSet(IDbCommand cmd, object value, int index);&#xD;
        public object Replace(object original, object target, object owner)&#xD;
        {&#xD;
            return original;&#xD;
        }&#xD;
    }&#xD;
    public class OracleClobField : PatchForOracleLobField&#xD;
    {&#xD;
        public override void NullSafeSet(IDbCommand cmd, object value, int index)&#xD;
        {&#xD;
            if (cmd is OracleCommand)&#xD;
            {&#xD;
                //CLob、NClob类型的字段，存入中文时参数的OracleDbType必须设置为OracleDbType.Clob&#xD;
                //否则会变成乱码（Oracle 10g client环境）&#xD;
                OracleParameter param = cmd.Parameters[index] as OracleParameter;&#xD;
                if (param != null)&#xD;
                {&#xD;
                    param.OracleType = OracleType.Clob;// 关键就这里啦&#xD;
                    param.IsNullable = true;&#xD;
                }&#xD;
            }&#xD;
            NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index);&#xD;
        }&#xD;
    }&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;用此方法解决了CLOB字段2000-4000字的问题，可是今天又遇到了个新的&amp;ldquo;&lt;strong&gt;ORA-01084: OCI 调用中的参数无效&lt;/strong&gt;&amp;rdquo;错误，google了一下，大概是说CLOB字段如果为null或&amp;rsquo;&amp;rsquo;时就会出这个错。&lt;/p&gt;&#xD;
&lt;p&gt;解决的办法:&lt;/p&gt;&#xD;
&lt;p&gt;将OracleClobField.NullSafeSet中的&lt;/p&gt;&#xD;
&lt;p&gt;if (cmd is OracleCommand) &amp;hellip;.&lt;/p&gt;&#xD;
&lt;p&gt;改为&lt;/p&gt;&#xD;
&lt;p&gt;if ((cmd is OracleCommand) &amp;amp;&amp;amp; !string.IsNullOrEmpty(value as string))&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果值是空或者空字符串的话就让NHibernate当默认的varchar2处理。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;from:http://wuchang.cnblogs.com&lt;/p&gt;&lt;img src="http://www.cnblogs.com/wuchang/aggbug/1685217.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/wuchang/archive/2010/03/13/1685217.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
