<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_张志敏</title><subtitle type="text">目前聚焦于以下领域： MonoTouch， WPF/Silverlight， ASP.NET MVC, WCF REST, NHibernate </subtitle><id>http://feed.cnblogs.com/blog/u/12542/rss</id><updated>2012-05-03T08:30:39Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/12542/rss"/><entry><id>http://www.cnblogs.com/beginor/archive/2012/05/03/2480775.html</id><title type="text">SQLite 常用 SQL</title><summary type="text">总结了 SQLite 常用的 SQL 知识， 包括主键自增、拼接字符串、查询新插入的行号以及日期时间函数与格式化等， 可谓 iOS 开发必备</summary><published>2012-05-03T08:25:00Z</published><updated>2012-05-03T08:25:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/05/03/2480775.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/05/03/2480775.html"/><content type="html">&lt;p&gt;&lt;strong&gt;主键自增&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;创建表时将主键列设置为 INTEGER PRIMARY KEY ， 例如：&lt;/p&gt;  CREATE TABLE [Test] (&lt;br/&gt;  [Id] INTEGER PRIMARY KEY, &lt;br/&gt;  [Name] NVARCHAR(20) NOT NULL&lt;br/&gt;);&lt;p&gt;&lt;strong&gt;最后插入的行号&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;查看最后插入的行号是用 last_insert_rowid() 函数， 与 SQL Server 的 @@Identity 类似，例如：&lt;/p&gt;INSERT INTO [Test] (Name)&lt;br/&gt;VALUES ('Test')&lt;br/&gt;&lt;br/&gt;SELECT LAST_INSERT_ROWID()&lt;p&gt;&lt;strong&gt;连接两个字符串&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;将两个字符串连接起来用 || ， 例如：&lt;/p&gt;INSERT INTO [Test] (Name)&lt;br/&gt;VALUES ('Test_' || CAST(LAST_INSERT_ROWID() AS NVARCHAR(10)));&lt;p&gt;&lt;strong&gt;日期与时间&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;SQLite 支持下面 5 个日期与时间函数：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;date(&lt;/strong&gt;timestring, modifier, modifier, ...&lt;strong&gt;)&lt;/strong&gt; &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;time(&lt;/strong&gt;timestring, modifier, modifier, ...&lt;strong&gt;)&lt;/strong&gt; &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;datetime(&lt;/strong&gt;timestring, modifier, modifier, ...&lt;strong&gt;)&lt;/strong&gt; &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;julianday(&lt;/strong&gt;timestring, modifier, modifier, ...&lt;strong&gt;)&lt;/strong&gt; &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;strftime(&lt;/strong&gt;format, timestring, modifier, modifier, ...&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这 5 个函数都接受一个时间字符串作为参数， 紧跟着的是可选的修饰符。 strftime 函数还接受一个格式化字符串作为它的第一个参数。&lt;/p&gt;&lt;p&gt;这些时间日期函数使用 ISO-8601 规定的时间日期格式的子集， date 函数返回 YYYY-MM-DD 格式的日期， time 函数返回 HH:MM:SS 格式的时间， 而 datetime 则返回 &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot; 格式的日期时间； julianday 函数则返回自儒略日（公元前4713年1月1日）的天数； strftime 返回的格式则由其参数决定， 下面是 strftime 可以接受的参数格式：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%d&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; day of month: 00 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%f&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; fractional seconds: SS.SSS &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%H&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; hour: 00-24 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%j&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; day of year: 001-366 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%J&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; Julian day number &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%m&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; month: 01-12 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%M&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; minute: 00-59 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%s&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; seconds since 1970-01-01 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%S&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; seconds: 00-59 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%w&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; day of week 0-6 with Sunday==0 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%W&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; week of year: 00-53 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%Y&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; year: 0000-9999 &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2"&gt;&lt;font face="Consolas"&gt;&lt;strong&gt;%%&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; % &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;所有的日期时间函数都可以用 strftime 函数表示， 提供这些函数的唯一原因是为了方便和高效， 例如：&lt;/p&gt;&lt;table border="1"&gt;&lt;tbody&gt;    &lt;tr&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;date(...)&lt;/font&gt;&lt;/td&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;strftime('%Y-%m-%d', ...)&lt;/font&gt;&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;time(...)&lt;/font&gt;&lt;/td&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;strftime('%H:%M:%S', ...)&lt;/font&gt;&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;datetime(...)&lt;/font&gt;&lt;/td&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;strftime('%Y-%m-%d %H:%M:%S', ...)&lt;/font&gt;&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;julianday(...)&lt;/font&gt;&lt;/td&gt;      &lt;td&gt;&lt;font size="2" face="Consolas"&gt;strftime('%J', ...)&lt;/font&gt;&lt;/td&gt;    &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;可接受的时间字符串&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DD &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DD HH:MM &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DD HH:MM:SS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DD HH:MM:SS.SSS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DDTHH:MM &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DDTHH:MM:SS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;YYYY-MM-DDTHH:MM:SS.SSS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;HH:MM &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;HH:MM:SS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;HH:MM:SS.SSS &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;now &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;DDDDDDDDDD&lt;/font&gt; &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;在第 5 至第 7 个格式中， &amp;quot;T&amp;quot; 是 ISO-8601 规定的日期时间分隔符； 第 8 至 第 10 个格式中只声明了时间， 其对应的日期为 2000-01-01 ； 第 11 个格式 ‘now’ 表示从系统获取的当前 UTC 时间； 第 12 个格式则表示从儒略日起的日期数。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;修饰符&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;时间字符串可以跟多个可选的修饰符来对时间进行调整， 每个修饰符是对其左边时间值得一个转换， 从左到右依次应用， 顺序很重要。 可用的修饰符如下：&lt;/p&gt;&lt;ol&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN days &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN hours &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN minutes &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN.NNNN seconds &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN months &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;NNN years &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;start of month &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;start of year &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;start of day &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;weekday N &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;unixepoch &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;localtime &lt;/font&gt;&lt;/li&gt;  &lt;li&gt;&lt;font size="2" face="Consolas"&gt;utc&lt;/font&gt; &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;前 6 个修饰符用于向时间字符串或修饰符指定的日期时间添加指定数量的时间。 注意 &amp;quot;±NNN months&amp;quot; 的工作方式是： 先将原来的日期渲染成 YYYY-MM-DD 格式， 对月份添加 ±NNN 的值， 然后再对结果进行修正。 如果 2001-03-31 添加了 '+1 month' 修饰符， 则应先得到 2001-04-31 ， 由于 4 月只有 30 天， 所以结果会被修正为 2001-05-01 。 如果向闰年的 2 月 29 日添加了 '±N years' 修饰符， 当 N 不是 4 的倍数时， 也会发生这样的修正。&lt;/p&gt;&lt;p&gt;第 7 到 9 的那些 &amp;quot;start of&amp;quot; 修饰符将日期转换为当前日、 月、 年的开始时间。&lt;/p&gt;&lt;p&gt;修饰符 &amp;quot;weekday&amp;quot; 将日期向后推进直到下一周的指定天数。 星期天是 0 ， 星期一是 1 ， 依此类推。&lt;/p&gt;&lt;p&gt;第 11 个修饰符 &amp;quot;unixepoch&amp;quot; 只有在日期格式为 &amp;quot;DDDDDDDDDD&amp;quot; 时才有效， 将 unix 时间戳转换成时间， 由于参数是 64 位整数， 因此， 有效地时间范围是 0000-01-01 00:00:00 至 5352-11-01 10:52:47 (Unix 时间 -62167219200 至 10675199167)&lt;/p&gt;&lt;p&gt;修饰符 &amp;quot;localtime&amp;quot; 将 utc 时间转换为本地时间， &amp;quot;utc&amp;quot; 则相反。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;计算当前日期：&lt;/p&gt;SELECT date('now');&lt;p&gt;计算当前月的最后一天：&lt;/p&gt;SELECT date('now','start of month','+1 month','-1 day');&lt;p&gt;计算给定 unix 时间戳对应的日期时间：&lt;/p&gt;SELECT datetime(1092941466, 'unixepoch');&lt;p&gt;计算给定 unix 时间戳对应的日期时间并转换成本地时间：&lt;/p&gt;SELECT datetime(1092941466, 'unixepoch', 'localtime');&lt;p&gt;计算当前的 unix 时间戳：&lt;/p&gt;SELECT strftime('%s','now');&lt;p&gt;计算从美国独立到现在的天数：&lt;/p&gt;SELECT julianday('now') - julianday('1776-07-04');&lt;p&gt;计算从2004年某个时刻到现在的秒数：&lt;/p&gt;SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56');&lt;p&gt;计算今年10月份的第一个星期三： &lt;/p&gt;SELECT date('now','start of year','+9 months','weekday 2');&lt;p&gt;计算 unix 时间纪元到现在的秒数（与 strftime('%s','now') 类似， 包含小数部分）：&lt;/p&gt;SELECT (julianday('now') - 2440587.5)*86400.0;HH:MM:SS &lt;img src="http://www.cnblogs.com/beginor/aggbug/2480775.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/05/03/2480775.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/04/25/2469545.html</id><title type="text">让 VS 编译 MonoTouch 项目源文件不再出错</title><summary type="text">使用MonoTouch做iOS开发，通常会相应的建立两个项目，一个是MonoDevelop项目，在OSX下使用，一个是VS项目，在Windows下使用，VS项目在添加MonoTouch项目的CS源文件之后，经常编译出错，而且如果安装了Resharper之类的插件之话，也会得到一大堆错误信息，本文提供了一个比较好的解决方案。</summary><published>2012-04-25T03:54:00Z</published><updated>2012-04-25T03:54:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/04/25/2469545.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/04/25/2469545.html"/><content type="html">&lt;p&gt;使用 MonoTouch 做 iOS 开发， 由于 MonoDevelop 和 VS 2010 相比， 功能差的太多， 通常会相应的建立两个项目， 一个是 MonoDevelop 项目， 在 OSX 下使用， 一个是 VS 项目， 在 Windows 下使用， 在 Windows 系统下进行编码， 之后再在 OSX 下进行调试。 不过， 默认的 VS 项目在添加 MonoTouch 项目的 CS 源文件之后， 经常编译出错， 而且如果安装了 Resharper 之类的插件之话， 也会得到一大堆错误信息， 令人感觉非常恶心。 经过一番研究发现是因为 VS 不能引用 MonoTouch 的几个核心 dll 文件导致的， 包括 mscorlib.dll ， System.dll ， System.Core.dll 等， 找到原因之后， 对应的解决方法就有了。&lt;/p&gt;  &lt;p&gt;新建项目， .Net Framework 选择 4.0 或以上， 项目类型选择类库项目， 项目名称为 MonoTouchLib ， 如下图所示：&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204251149042364.png" width="787" height="486" /&gt;&lt;/p&gt;  &lt;p&gt;编辑项目属性， 选择 build 选项卡， Configuration 选择 All Configurations ， 点击右下角的 advanced 按钮， 在弹出的 Advanced Build Setting 对话框中勾选 Do not reference mscorlib.dll ， 如下图所示：&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204251149066607.png" width="747" height="727" /&gt;&lt;/p&gt;  &lt;p&gt;右击 MonoTouchLib 项目， 在上下文菜单选择 Unload Project ， 再次右击， 选择 Edit MonoTouchLib.csproj ， 按照下图对项目文件进行修改：&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204251149064165.png" width="675" height="627" /&gt;&lt;/p&gt;  &lt;p&gt;修改好之后， 保存并重新加载项目即可。 把这个项目导出为项目模板， 以后就不用每次都重复设置了。&lt;/p&gt;  &lt;p&gt;如果再要引用其它的 MonoTouch 组件， 可以尝试直接添加引用， 如果发现引用路径不正确的话， 还按照这个方法进行修改。&lt;/p&gt;  &lt;p&gt;这样修改过后的项目， 不仅可以顺利编译 MonoTouch 项目的源文件， Resharper 也不再提示错误。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2469545.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/04/25/2469545.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/04/22/2465441.html</id><title type="text">MonoTouch绑定CocoaTouch类库</title><summary type="text">在 Windows/Linux 平台上， .Net/Mono 可以通过平台调用 (P/Invoke) 技术调用本地类库， 通过互操作 (Interop) 技术调用 COM 组件， 在 iOS 平台上， MonoTouch 也有类似的技术， 可以调用 iOS 的 CocoaTouch 类库， 这种技术在 MonoTouch 叫做绑定 (Binding) ， 整个 monotouch.dll 就是用绑定技术完成的, 本文详细介绍如何用 MonoTouch 绑定 CocoaTouch 类库。</summary><published>2012-04-22T13:02:00Z</published><updated>2012-04-22T13:02:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465441.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465441.html"/><content type="html">&lt;p&gt;&lt;strong&gt;绑定概述&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;在 Windows/Linux 平台上， .Net/Mono 可以通过平台调用 (P/Invoke) 技术调用本地类库， 通过互操作 (Interop) 技术调用 COM 组件， 在 iOS 平台上， MonoTouch 也有类似的技术， 可以调用 iOS 的 CocoaTouch 类库， 这种技术在 MonoTouch 叫做绑定 (Binding) ， 整个 monotouch.dll 就是用绑定技术完成的。&lt;/p&gt;&lt;p&gt;互联网上有很多热心网友提供的 CacoaTouch 类库， 如果想使用这些类库， 完全用 C# 重写是不可取的， 所以就要用到 MonoTouch 的绑定技术。&lt;/p&gt;  &lt;p&gt;绑定技术听起来高深， 其实仔细研究起来， 其实并不难。 接下来， 以 &lt;a href="https://github.com/kolinkrewinkel/KKGridView"&gt;KKGridView&lt;/a&gt; 为例， 说明怎样绑定 CocoaTouch 类库项目。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;准备 MonoTouch 绑定项目&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;新建一个名称为 KKGridView 的空白解决方案， 作为工作区， 再新建一个绑定项目， 名称为 Binding ， 项目建好之后， 设置绑定项目的默认命名空间为 MonoTouch.KKGrid ， 并设置项目的输出为 KKGridView ， 相关截图如下：&lt;/p&gt;&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204222056073839.png" width="932" height="507" /&gt;&lt;/p&gt;&lt;p&gt;绑定项目默认结构如下， 包含两个文件： ApiDeginition.cs 和 StructsAndEnums.cs ， 其中 ApiDefinition 用于绑定 CacoaTouch 类库定义的 interface 、 delegate 与 protocol 及其成员， 而 StructsAndEnums 用于绑定 ApiDefinition 所需的结构、 枚举以及其它。 这两个文件的编译方式是不同的， 所以对应的 C# 类型必须对号入座才行。&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204222056092575.png" width="269" height="209" /&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;获取 KKGridView 源代码并编译&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;KKGridView 在 GitHub 上的主页是 &lt;a href="https://github.com/kolinkrewinkel/KKGridView.git"&gt;https://github.com/kolinkrewinkel/KKGridView.git&lt;/a&gt; ， 使用 git 可以轻松获取其源代码。 打开一个命令行窗口， 切换到绑定项目目录， 输入下面的命令：&lt;/p&gt; git clone https://github.com/kolinkrewinkel/KKGridView.git &lt;p&gt;等命令行运行完毕， 源代码就获取好了， 接下来要编译 KKGridView ， 接着输入下面的命令：&lt;/p&gt;  cd KKGridView&lt;br/&gt;xcodebuild -project KKGridView.xcodeproj -target KKGridView -sdk iphonesimulator -configuration Release clean build&lt;br/&gt;xcodebuild -project KKGridView.xcodeproj -target KKGridView -sdk iphoneos -configuration Release clean build&lt;br/&gt;lipo -create -output libKKGridView.a build/Release-iphonesimulator/libKKGridView.a build/Release-iphoneos/libKKGridView.a&lt;p&gt;现在打开 MonoDevelop 将最终生成的 libKKGridView.a 添加到绑定项目 ， 现在可以开始进行绑定了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;绑定 Objective-C 类型至 C#&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;绑定的语法定义为：&lt;/p&gt;[BaseType(typeof(TypeBase))]&lt;br/&gt;interface MyType [: Prodocol1, Protocol2] {&lt;br/&gt;   IntPtr Constructor(string foo);&lt;br/&gt;}&lt;p&gt;MyType 与 ObjC 的类型对应， TypeBase 与 ObjC 的基类对应， Protocol1 、 Prodocol2 与 ObjC 类型实现的协议对应。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ObjC 的 interface 定义如下：&lt;/p&gt;@interface KKGridView : UIScrollView&lt;br/&gt;@end&lt;p&gt;对应的绑定语法如下：&lt;/p&gt;[BaseType(typeof(UIScrollView))]&lt;br/&gt;interface KKGridView {&lt;br/&gt;}&lt;p&gt;&lt;strong&gt;protocol&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ObjC 的 protocol 定义语法如下：&lt;/p&gt;@protocol KKGridViewDataSource &amp;lt;NSObject&amp;gt;&lt;br/&gt;@end&lt;p&gt;或者&lt;/p&gt;@protocol KKGridViewDelegate &amp;lt;NSObject , UIScrollViewDelegate&amp;gt;&lt;br/&gt;@end&lt;p&gt;ObjC 的 protocol 与 C# 的 interface 有些类似， 但是 protocol 中定义的方法有两种， optional 和 required ， 又有点儿像抽象类， MonoTouch 将其绑定为类， 并添加 ModelAttribute 标记， 对应的绑定语法分别为：&lt;/p&gt;[Model, BaseType(typeof(NSObject))]&lt;br/&gt;interface KKGridViewDataSource {&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;[Model, BaseType(typeof(UIScrollViewDelegate))]&lt;br/&gt;interface KKGridViewDelegate {&lt;br/&gt;}&lt;p&gt;&lt;strong&gt;instance method&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;实例方法绑定为对应的 C# 实例方法：&lt;/p&gt;- (NSString *)gridView:(KKGridView *)gridView titleForHeaderInSection:(NSUInteger)section;[Export(&amp;quot;gridView:titleForHeaderInSection:&amp;quot;)]&lt;br/&gt;string GridViewTitleFoHeaderInSection(KKGridView gridView, uint section);&lt;p&gt;如果是 protocol 的 required 方法， 则在对应的 C# 方法上添加 Abstract 标记， 例如：&lt;/p&gt;- (NSUInteger)gridView:(KKGridView *)gridView numberOfItemsInSection:(NSUInteger)section;[Abstract, Export(&amp;quot;gridView:numberOfItemsInSection:&amp;quot;)]&lt;br/&gt;uint GridViewNumberOfItemsInSection(KKGridView gridView, uint section);&lt;p&gt;&lt;strong&gt;class method&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ObjC 中的 class method 与 C# 中的静态方法概念一致， 因此绑定为 C# 的静态方法， 例如：&lt;/p&gt;+ (id)cellForGridView:(KKGridView *)gridView;[Static, Export(&amp;quot;cellForGridView:&amp;quot;)]&lt;br/&gt;KKGridViewCell CellFroGridView(KKGridView gridView);&lt;p&gt;&lt;strong&gt;property&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ObjC 的属性通常由 setPropertyName 、 propertyName 两个方法组成， 绑定为 C# 的属性：&lt;/p&gt;@property (nonatomic) BOOL allowsMultipleSelection; [Export(&amp;quot;allowsMultipleSelection&amp;quot;)]&lt;br/&gt;bool AllowsMultipleSelection { get; set; }&lt;p&gt;如果不是由默认的两个方法组成， 例如：&lt;/p&gt;@property (nonatomic, getter = isSelected) BOOL selected;&lt;p&gt;对应的绑定为：&lt;/p&gt;[Export(&amp;quot;selected&amp;quot;)]&lt;br/&gt;bool Selected { [Bind(&amp;quot;isSelected&amp;quot;)]get; set; }&lt;p&gt;&lt;strong&gt;enum&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;枚举的绑定是最容易的， 不过要放在 enums.cs 文件中， 例如：&lt;/p&gt;typedef enum {&lt;br/&gt;   KKGridViewAnimationFade,&lt;br/&gt;   KKGridViewAnimationResize,&lt;br/&gt;   KKGridViewAnimationSlideLeft,&lt;br/&gt;   KKGridViewAnimationSlideTop,&lt;br/&gt;   KKGridViewAnimationSlideRight,&lt;br/&gt;   KKGridViewAnimationSlideBottom,&lt;br/&gt;   KKGridViewAnimationExplode,&lt;br/&gt;   KKGridViewAnimationImplode,&lt;br/&gt;   KKGridViewAnimationNone&lt;br/&gt;} KKGridViewAnimation;public enum KKGridViewAnimation {&lt;br/&gt;   Fade,&lt;br/&gt;   Resize,&lt;br/&gt;   SlideLeft,&lt;br/&gt;   SlideTop,&lt;br/&gt;   SlideRight,&lt;br/&gt;   SlideBottom,&lt;br/&gt;   Explode,&lt;br/&gt;   Implode,&lt;br/&gt;   None&lt;br/&gt;}&lt;p&gt;&lt;strong&gt;添加 Makefile&lt;/strong&gt;&lt;/p&gt;# 定义一些常量&lt;br/&gt;PROJECT_ROOT=KKGridView&lt;br/&gt;PROJECT=$(PROJECT_ROOT)/$(PROJECT_ROOT).xcodeproj&lt;br/&gt;BUILD_ROOT=$(PROJECT_ROOT)/Build&lt;br/&gt;TARGET=$(PROJECT_ROOT)&lt;br/&gt;SDK=lib$(TARGET).a&lt;br/&gt;BTOUCH=/Developer/MonoTouch/usr/bin/btouch&lt;br/&gt;SMCS=/Developer/MonoTouch/usr/bin/smcs&lt;br/&gt;XBUILD=/Developer/usr/bin/xcodebuild&lt;br/&gt;&lt;br/&gt;# 从github获取源代码&lt;br/&gt;$(PROJECT_ROOT):&lt;br/&gt;   git clone https://github.com/kolinkrewinkel/$(PROJECT_ROOT).git&lt;br/&gt;   cd $(PROJECT_ROOT) &amp;amp;&amp;amp; git pull&lt;br/&gt;&lt;br/&gt;# 编译模拟器版本&lt;br/&gt;simulator: $(PROJECT_ROOT)&lt;br/&gt;   mkdir -p libs&lt;br/&gt;   $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build&lt;br/&gt;   mv -f $(BUILD_ROOT)/Release-iphoneSimulator/lib$(TARGET).a ./libs/lib$(TARGET)-simulator.a&lt;br/&gt;&lt;br/&gt;# 编译设备版本&lt;br/&gt;iphoneos: $(PROJECT_ROOT)&lt;br/&gt;   mkdir -p libs&lt;br/&gt;   $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -configuration Release clean build&lt;br/&gt;   mv -f $(BUILD_ROOT)/Release-iphoneos/lib$(TARGET).a ./libs/lib$(TARGET)-iphoneos.a&lt;br/&gt;&lt;br/&gt;# 讲两个版本合成为一个&lt;br/&gt;sdk:&lt;br/&gt;   lipo -create -output $(SDK) libs/lib$(TARGET)-simulator.a libs/lib$(TARGET)-iphoneos.a&lt;br/&gt;&lt;br/&gt;# 编译 MonoTouch 组件&lt;br/&gt;asm:&lt;br/&gt;   # 使用 btouch 编译出的 dll 文件总是无法运行， 不知是怎么回事， 只能用 MonoDevelop 进行编译， 所以把这里注释掉了。&lt;br/&gt;   #$(BTOUCH) -d=MONOTOUCH -out:bin/$(TARGET).dll api.cs -s:enum.cs --link-with=$(SDK),$(SDK)&lt;br/&gt;&lt;br/&gt;# 清理&lt;br/&gt;clean:&lt;br/&gt;   rm -rf $(PROJECT_ROOT) libs ios *.a *.dll *.stamp&lt;br/&gt;&lt;br/&gt;# 全部任务&lt;br/&gt;all: clean simulator iphoneos sdk asm&lt;p&gt;&lt;strong&gt;绑定项目源代码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;KKGridView 的全部绑定源代码放在 GitHub ， 地址为 &lt;a href="https://github.com/beginor/MonoTouch.KKGridView"&gt;https://github.com/beginor/MonoTouch.KKGridView&lt;/a&gt; ， 有兴趣的可以围观。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2465441.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465441.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/04/22/2465022.html</id><title type="text">升级 Xcode 4.3 后找不到 xcodebuild 的解决方法</title><summary type="text">Xcode 升级到 4.3 之后， 原来的 /Developer 目录被删除了， 新的 Developer 目录是 /Applications/Xcode.app/Contents/Developer 切换的方法是打开命令行窗口， 输入 sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer</summary><published>2012-04-22T07:44:00Z</published><updated>2012-04-22T07:44:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465022.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465022.html"/><content type="html">&lt;p&gt;Xcode 升级到 4.3 之后， 原来的 /Developer 目录被删除了， 新的 Developer 目录是&lt;/p&gt;  &lt;p&gt;/Applications/Xcode.app/Contents/Developer&lt;/p&gt;  &lt;p&gt;切换的方法是打开命令行窗口， 输入&lt;/p&gt;  &lt;p&gt;sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2465022.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/04/22/2465022.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/04/20/2459244.html</id><title type="text">iOS 静态类库项目的建立与使用</title><summary type="text">本文详细说明了如何使用 Xcode 建立于使用 CocoaTouch Static Library 项目。</summary><published>2012-04-20T06:09:00Z</published><updated>2012-04-20T06:09:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/04/20/2459244.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/04/20/2459244.html"/><content type="html">&lt;p&gt;新建 Xcode workspace&lt;/p&gt;  &lt;p&gt;打开 Xcode ， 选择 File -&amp;gt; New -&amp;gt; Workspace ， 将 Workspace 命名为 Test.xcworkspace ， 并选择合适的目录。&lt;/p&gt;  &lt;p&gt;新建 Static Library 项目&lt;/p&gt;  &lt;p&gt;选择 File -&amp;gt; New -&amp;gt; Project ， 项目模板选择 Cocoa Touch Static Library ， 项目名称命名为 MyLib.xcodeproj ， 注意选中 Use Automatic Reference Counting 。&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/20120420140623541.png" width="730" height="493" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406276510.png" width="730" height="493" /&gt;&lt;/p&gt;  &lt;p&gt;Xcode 会在项目中自动生成 MyLib.h 和 MyLib.m 文件， 单击 MyLib.h 文件， 添加下面的两个方法定义：&lt;/p&gt;  - (NSInteger) add:(NSInteger)a and:(NSInteger)b;&lt;br/&gt;+ (NSString*) connect:(NSString*)str1 and:(NSString*)str2;&lt;p&gt;再打开 MyLib.m 文件， 添加刚刚定义两个文件的实现：&lt;/p&gt;- (NSInteger) add:(NSInteger)a and:(NSInteger)b {&lt;br/&gt;   return a + b;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;+ (NSString*) connect:(NSString *)str1 and:(NSString *)str2 {&lt;br/&gt;   return [NSString stringWithFormat:@&amp;quot;%@ %@&amp;quot;, str1, str2];&lt;br/&gt;}&lt;p&gt;现在， 最终的文件看起来是这样的：&lt;/p&gt;//&lt;br/&gt;// MyLib.h&lt;br/&gt;// MyLib&lt;br/&gt;//&lt;br/&gt;// Created by gdeic on 4/16/12.&lt;br/&gt;// Copyright (c) 2012 __MyCompanyName__. All rights reserved.&lt;br/&gt;//&lt;br/&gt;&lt;br/&gt;#import &lt;foundation foundation.h&gt;&lt;br/&gt;&lt;br/&gt;@interface MyLib : NSObject&lt;br/&gt;&lt;br/&gt;- (NSInteger) add:(NSInteger)a and:(NSInteger)b;&lt;br/&gt;&lt;br/&gt;+ (NSString*) connect:(NSString*)str1 and:(NSString*)str2;&lt;br/&gt;&lt;br/&gt;@end&lt;br/&gt;&lt;br/&gt;//&lt;br/&gt;// MyLib.m&lt;br/&gt;// MyLib&lt;br/&gt;//&lt;br/&gt;// Created by gdeic on 4/16/12.&lt;br/&gt;// Copyright (c) 2012 __MyCompanyName__. All rights reserved.&lt;br/&gt;//&lt;br/&gt;&lt;br/&gt;#import &amp;quot;MyLib.h&amp;quot;&lt;br/&gt;&lt;br/&gt;@implementation MyLib&lt;br/&gt;&lt;br/&gt;- (NSInteger) add:(NSInteger)a and:(NSInteger)b {&lt;br/&gt;   return a + b;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;+ (NSString*) connect:(NSString *)str1 and:(NSString *)str2 {&lt;br/&gt;   return [NSString stringWithFormat:@&amp;quot;%@ %@&amp;quot;, str1, str2];&lt;br/&gt;}&lt;br/&gt;@end&lt;p&gt;选中 MyLib 项目， 在中间的编辑器窗口中选择项目的 Target ， 选择 Build Phases 标签， 展开 Copy Headers 分组， 下面有三个子分组， 分别是 Public 、 Project 与 Private ， 将 MyLib.h 拖拽到 Public 分组即可。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406316939.png" width="785" height="462" /&gt;&lt;/p&gt;&lt;p&gt;保存所有文件， 选择 Product -&amp;gt; Build ， 进行编译， 生成 libMyLib.a 文件， 同时也会将 MyLib.h 文件复制到输出目录。&lt;/p&gt;&lt;p&gt;使用静态类库项目&lt;/p&gt;&lt;p&gt;选择 File -&amp;gt; New -&amp;gt; Project ， 项目模板选择 iOS -&amp;gt; Application -&amp;gt; Single View Application ， 项目名称命名为 MyApp ， 注意勾选 Use Storyboards 和 Use Automatic Reference Counting 。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406343059.png" width="730" height="493" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image005" border="0" alt="clip_image005" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406385648.png" width="730" height="493" /&gt;&lt;/p&gt;&lt;p&gt;建好项目之后， 项目窗口如下如所示：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406386029.png" width="254" height="387" /&gt;&lt;/p&gt;&lt;p&gt;将 MyLib 项目拖拽到 MyApp 项目的 Frameworks 文件夹， 在弹出的对话框中选择 Create groups for any added folders ， 然后点击 Finish 按钮。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image007" border="0" alt="clip_image007" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406421126.png" width="730" height="493" /&gt;&lt;/p&gt;&lt;p&gt;选中 MyApp 项目， 在选择项目的目标 (Target) ， 选中 Summary 标签页下找到 Linked Frameworks and Library 分组选项， 如下图：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406445195.png" width="592" height="384" /&gt;&lt;/p&gt;&lt;p&gt;点击下面的加号按钮， 将工作区的 libMyLib.a 添加进去。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image009" border="0" alt="clip_image009" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406443309.png" width="402" height="462" /&gt;&lt;/p&gt;&lt;p&gt;接下来添加头文件搜索目录， 选中 Targets 上面的 Project ， 选择 Build Settings 标签页，在搜索框内输入 header search 进行过滤， 找到 Header Search Paths ， 添加一行， 输入 ../MyLib ， 并选中递归复选框。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406452852.png" width="693" height="420" /&gt;&lt;/p&gt;&lt;p&gt;现在要先验证一下对 MyLib 的引用是否正确， 打开 MyApp 项目的 ViewController.m ， 添加对 MyLib.h 的引用， 如下图所示， 并编译 MyApp ， 如果编译成功， 则表示引用正确。&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image011" border="0" alt="clip_image011" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406471970.png" width="638" height="483" /&gt;&lt;/p&gt;&lt;p&gt;打开 MainStoryboard.storyboard 文件， 在生成的 ViewController 上添加两个 UITextField 、 两个 UIButton 以及一个 UILabel， 如下图所示：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/20120420140648608.png" width="360" height="601" /&gt;&lt;/p&gt;&lt;p&gt;并添加相应的 outlet 和 action ， ViewController.h 如下：&lt;/p&gt;//&lt;br/&gt;// ViewController.h&lt;br/&gt;// MyApp&lt;br/&gt;//&lt;br/&gt;// Created by gdeic on 4/19/12.&lt;br/&gt;// Copyright (c) 2012 __MyCompanyName__. All rights reserved.&lt;br/&gt;//&lt;br/&gt;&lt;br/&gt;#import &lt;uikit uikit.h&gt;&lt;br/&gt;&lt;br/&gt;@interface ViewController : UIViewController&lt;br/&gt;&lt;br/&gt;@property (weak, nonatomic) IBOutlet UITextField *textField1;&lt;br/&gt;&lt;br/&gt;@property (weak, nonatomic) IBOutlet UITextField *textField2;&lt;br/&gt;&lt;br/&gt;@property (weak, nonatomic) IBOutlet UILabel *resultLabel;&lt;br/&gt;&lt;br/&gt;- (IBAction)addButtonClick:(id)sender;&lt;br/&gt;&lt;br/&gt;- (IBAction)connectButtonClick:(id)sender;&lt;br/&gt;&lt;br/&gt;@end&lt;p&gt;打开 ViewController.m 文件， 实现 addButtonClick: 和 connectButtonClick: 方法， 在 addButtonClick: 方法中调用 MyLib 的实例方法 add:and: ， 在 connectButtonClick: 方法中调用 MyLib 的静态方法 connect:and: ， 如下所示：&lt;/p&gt;- (IBAction)addButtonClick:(id)sender {&lt;br/&gt;   // 获取用户输入的两个数字&lt;br/&gt;   NSInteger num1 = [self.textField1.text integerValue];&lt;br/&gt;   NSInteger num2 = [self.textField2.text integerValue];&lt;br/&gt;   // 初始化一个新的 MyLib 实例&lt;br/&gt;   MyLib* myLib = [[MyLib alloc] init];&lt;br/&gt;   // 调用实例方法相加&lt;br/&gt;   NSInteger result = [myLib add:num1 and:num2];&lt;br/&gt;   // 显示结果&lt;br/&gt;   self.resultLabel.text = [NSString stringWithFormat:@&amp;quot;%d + %d = %d&amp;quot;, num1, num2,result];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (IBAction)connectButtonClick:(id)sender {&lt;br/&gt;   // 获取用户输入的两个字符串&lt;br/&gt;   NSString* str1 = self.textField1.text;&lt;br/&gt;   NSString* str2 = self.textField2.text;&lt;br/&gt;   // 调用 MyLib 的静态方法连两个字符串&lt;br/&gt;   NSString* result = [MyLib connect:str1 and:str2];&lt;br/&gt;   // 显示结果&lt;br/&gt;   self.resultLabel.text = result;&lt;br/&gt;}&lt;p&gt;点击添加按钮时， 效果如下图所示：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image013" border="0" alt="clip_image013" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406516511.png" width="396" height="744" /&gt;&lt;/p&gt;&lt;p&gt;点击 Connect 按钮时， 效果如下图所示：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://images.cnblogs.com/cnblogs_com/beginor/201204/201204201406539500.png" width="396" height="744" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2459244.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/04/20/2459244.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/04/19/2456535.html</id><title type="text">从源代码编译里程碑的 ICS ROM</title><summary type="text">操作系统选择 Ubuntu 10.04， 可以用虚拟机； 安装 Android SDK ， 并更新； 打开命令行窗口， 输入下面的命令， 准备编译环境： sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev sun-java6-jdk pngcrush schedtool 如果提示说找...</summary><published>2012-04-19T01:17:00Z</published><updated>2012-04-19T01:17:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/04/19/2456535.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/04/19/2456535.html"/><content type="html">&lt;ol&gt;   &lt;li&gt;操作系统选择 Ubuntu 10.04， 可以用虚拟机； &lt;/li&gt;    &lt;li&gt;安装 Android SDK ， 并更新； &lt;/li&gt;    &lt;li&gt;打开命令行窗口， 输入下面的命令， 准备编译环境：      &lt;br /&gt;sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev sun-java6-jdk pngcrush schedtool       &lt;br /&gt;如果提示说找不到 sun-java-jdk ， 可以安装 open-jdk6&amp;#160; 代替； &lt;/li&gt;    &lt;li&gt;安装 Repo 命令      &lt;br /&gt;curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo &amp;gt; ~/bin/repo       &lt;br /&gt;chmod a+x ~/bin/repo &lt;/li&gt;    &lt;li&gt;按照 &lt;a href="http://android.doshaska.net/cm9build" target="_blank"&gt;nadlabak 的说明&lt;/a&gt;， 输入下列命令：       &lt;br /&gt;mkdir cm4mm       &lt;br /&gt;cd cm4mm       &lt;br /&gt;repo init -u git://github.com/nadlabak/android.git -b ics       &lt;br /&gt;repo sync       &lt;br /&gt;vendor/cm/get-prebuilts       &lt;br /&gt;. build/envsetup.sh &amp;amp;&amp;amp; lunch cm_umts_sholes-eng &amp;amp;&amp;amp; mka bacon &lt;/li&gt;    &lt;li&gt;如果不出错误的话， 就可以在 out/target/product/umts_sholes 目录看到编译好的 update-cm-9.0.0-RC0-umts_sholes-UNOFFICIAL-signed.zip 文件， 这个文件可以通过 OpenRecovery 进行安装。 &lt;/li&gt; &lt;/ol&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2456535.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/04/19/2456535.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/03/26/2418403.html</id><title type="text">IIS 7.5 下应用程序池的预定义账户</title><summary type="text">IIS 7.5 下应用程序池的预定义账户详解。</summary><published>2012-03-26T11:23:00Z</published><updated>2012-03-26T11:23:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/03/26/2418403.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/03/26/2418403.html"/><content type="html">&lt;p&gt;IIS 7.5 下的应用程序池标识的预定义账户有下面几个可选项：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;ApplicationPoolIdentity&lt;/strong&gt; 默认情况下，选择“应用程序池标识”帐户。启动应用程序池时动态创建“应用程序池标识”帐户，因此，此帐户对于您的应用程序来说是最安全的。&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;LocalService&lt;/strong&gt; “本地服务”帐户是用户组的成员之一，它拥有与“网络服务”帐户相同的用户权限，但仅限于在本地计算机上使用。当应用程序池中的工作进程不需要访问它所运行在的 Web 服务器以外的内容时，可以使用此帐户。&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;LocalSystem&lt;/strong&gt; “本地系统”帐户拥有所有用户权限，它是 Web 服务器上的管理员组的成员之一。应尽可能避免使用“本地系统”帐户，因为它会给 Web 服务器带来更严重的安全风险。&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;NetworkService&lt;/strong&gt; “网络服务” 帐户是 Users 组的成员之一，并拥有运行应用程序所需的用户权限。通过使用计算机帐户的凭据，它可以在整个基于 Active Directory 的网络上进行交互。&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;如果应用程序池选择的是 ApplicationPoolIdentity ， 这个账户的权限很低， 只属于 IIS_IUSRS 用户组， 甚至不属于 Users 用户组， 而应用程序又需要访问本地文件系统 （比如日志输出） ， 就需要为 ApplicationPoolIdentity 账户设置 NTFS 权限， 这个账户在安全对话框是找不到的， 只能手工输入 IIS APPPOOL\{app pool name} 进行设置。&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://images.cnblogs.com/cnblogs_com/beginor/201203/201203261922156799.png" width="472" height="258" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://images.cnblogs.com/cnblogs_com/beginor/201203/201203261922159242.png" width="472" height="258" /&gt;&lt;/p&gt;  &lt;p&gt;通过查看 IIS_IUSRS 用户组的属性可以看到全部的“应用程序池标识”账户， 如下图：&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://images.cnblogs.com/cnblogs_com/beginor/201203/201203261922166667.png" width="405" height="418" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2418403.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/03/26/2418403.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/03/22/2411496.html</id><title type="text">Web API 依赖注入与扩展</title><summary type="text">详细介绍了 ASP.NET Web API 的依赖注入实现， 以及使用依赖注入时 Web API 公开的扩展点。</summary><published>2012-03-22T05:40:00Z</published><updated>2012-03-22T05:40:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/03/22/2411496.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/03/22/2411496.html"/><content type="html">&lt;p&gt;&lt;strong&gt;依赖注入&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;与 MVC 类似， Web API 提供了System.Web.Http.Services.IDependencyResolver 接口来实现依赖注入， 我们可以很容易的用 Unity 来实现这个接口：&lt;/p&gt;&lt;br/&gt;public class UnityDependencyResolver : IDependencyResolver {&lt;br/&gt;&lt;br/&gt;   private readonly IUnityContainer _container;&lt;br/&gt;&lt;br/&gt;   public UnityDependencyResolver(IUnityContainer container) {&lt;br/&gt;      this._container = container;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;   public object GetService(Type serviceType) {&lt;br/&gt;      return this._container.IsRegistered(serviceType) ? this._container.Resolve(serviceType) : null;&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;   public IEnumerable&amp;lt;Object&gt; GetServices(Type serviceType) {&lt;br/&gt;      return this._container.Registrations&lt;br/&gt;             .Where(reg =&gt; type.IsAssignableFrom(reg.RegisteredType))&lt;br/&gt;             .Select(reg =&gt; string.IsNullOrEmpty(reg.Name) ? this._container.Resolve(type) : this._container.Resolve(type, reg.Name));&lt;br/&gt;   }&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;p&gt;使用 UnityDependencyResolver 的方法也很简单， 只要在 Global.asax.cs 里添加下面一行代码即可：&lt;/p&gt;&lt;br/&gt;GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new UnityDependencyResolver(container));&lt;br/&gt;&lt;p&gt;将 UnityDependencyResolver 配置好之后， Web API 框架将会在运行时向其请求一系列的接口实现：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;应用启动时， Web API 框架会依次请求下列接口：&lt;/li&gt;&lt;ol&gt;&lt;li&gt;System.Web.Http.Dispatcher.IHttpControllerFactory&lt;/li&gt;&lt;li&gt;System.Web.Http.Common.ILogger&lt;/li&gt;&lt;li&gt;System.Web.Http.Dispatcher.IHttpControllerActivator&lt;/li&gt;&lt;li&gt;System.Web.Http.Controllers.IHttpActionSelector&lt;/li&gt;&lt;li&gt;System.Web.Http.Controllers.IHttpActionInvoker&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;在第一次访问某个 Controller 之前， 还会请求下面的接口 （如果重复访问相同的 Controller ， 则不会再次调用）：&lt;/li&gt;&lt;ol&gt;&lt;li&gt;System.Web.Http.Filters.IFilterProvider&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;每次处理 HTTP 请求时， Web API 请求下列接口：&lt;/li&gt;&lt;ol&gt;&lt;li&gt;System.Web.Http.Controllers.IActionValueBinder&lt;/li&gt;&lt;li&gt;System.Web.Http.ValueProviders.ValueProviderFactory （仅 Action 需要参数时才需要）&lt;/li&gt;&lt;li&gt;System.Web.Http.ModelBinding.ModelBinderProvider （仅 Action 需要参数时才需要）&lt;/li&gt;&lt;li&gt;System.Web.Http.Metadata.ModelMetadataProvider （仅 Action 需要参数时才需要）&lt;/li&gt;&lt;li&gt;System.Web.Http.Validation.ModelValidatorProvider （仅 Action 需要参数时才需要）&lt;/li&gt;&lt;li&gt;System.Net.Http.Formatting.IFormatterSelector &lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;p&gt;这些接口都是 Web API 公开的扩展点， 可以根据需要来对这些接口进行实现， 并通过 Unity 进行配置， 让其注入到 Web API 运行时中。 接下来将逐个讨论这些扩展点。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;扩展&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IHttpControllerFactory&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;IHttpControllerFactory 接口有两个方法， 负责创建和销毁 HttpController 实例：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CreateController(HttpControllerContext, Type) : IHttpController&lt;/li&gt;&lt;li&gt;ReleaseController(IHttpController) : void&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这个接口的默认实现是 DefaultHttpControllerFactory ， 根据当前请求的上下文通过创建 HttpControllerDescriptor ， 然后通过 HttpControllerDescriptor 的 ControllerActivator 创建对应的 IHttpController 实例。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ILogger&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;只是一个日志接口， 有下面的几个方法：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Log(string, TraceLevel, Func&lt;string&gt;) : void&lt;/li&gt;&lt;li&gt;LogException(string, TraceLevel, Exception) : void&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;默认的实现是 DiagnosticLogger ， 通过 ILSpy 观察， 貌似什么都没有做。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IHttpControllerActivator&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责创建具体的 Controller 实例， 只有一个方法：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create(HttpControllerContext, Type) : IHttpController&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;默认的实现是 DefaultHttpControllerActivator ， 先向 DependencyResolver 请求对应 Controller 类型的实例， 如果返回为空， 则通过动态编译包装 Controller 类型构造函数的 lambda 表达式进行创建实例， 相关的代码如下：&lt;/p&gt;&lt;br/&gt;Func&amp;lt;IHttpController&gt; func = TypeActivator.Create&amp;lt;IHttpController&gt;(controllerType);&lt;br/&gt;Tuple&amp;lt;HttpControllerDescriptor, Func&amp;lt;IHttpController&gt;&gt; value = Tuple.Create&amp;lt;HttpControllerDescriptor, Func&amp;lt;IHttpController&gt;&gt;(controllerContext.ControllerDescriptor, func);&lt;br/&gt;Interlocked.CompareExchange&amp;lt;Tuple&amp;lt;HttpControllerDescriptor, Func&amp;lt;IHttpController&gt;&gt;&gt;(ref this._fastCache, value, null);&lt;br/&gt;result = func();&lt;br/&gt;&lt;p&gt;&lt;strong&gt;IHttpActionSelector&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责选择合适的动作， 默认的实现是 ApiControllerSelector ， 选择规则如下：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;如果路由定义了 {action} ， 则通过当前的 HttpControllerContext 中的 action 的值寻找合适的方法；&lt;/li&gt;&lt;li&gt;否则， 根据当前的 HTTP 请求方法 (POST, GET, PUT, DELETE) 寻找合适的方法。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;IHttpActionInvoker&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责调用 HttpActionSelector 选择到的方法， 该接口有一个方法：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;InvokeActionAsync(HttpActionContext, CancellationToken) : Task&amp;lt;HttpResponseMessage&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;默认的实现是 ApiControllerActionInvoker ， 通过反射找出动作方法的参数信息， 然后再通过动态创建 lambda 表达式对方法进行调用， 取得返回结果， 部分代码如下：&lt;/p&gt;&lt;br/&gt;ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance");&lt;br/&gt;ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object[]), "parameters");&lt;br/&gt;List&amp;lt;Expression&gt; list = new List&amp;lt;Expression&gt;();&lt;br/&gt;ParameterInfo[] parameters = methodInfo.GetParameters();&lt;br/&gt;for (int i = 0; i &amp;lt; parameters.Length; i++)&lt;br/&gt;{&lt;br/&gt;   ParameterInfo parameterInfo = parameters[i];&lt;br/&gt;   BinaryExpression expression = Expression.ArrayIndex(parameterExpression2, Expression.Constant(i));&lt;br/&gt;   UnaryExpression item = Expression.Convert(expression, parameterInfo.ParameterType);&lt;br/&gt;   list.Add(item);&lt;br/&gt;}&lt;br/&gt;UnaryExpression instance2 = (!methodInfo.IsStatic) ? Expression.Convert(parameterExpression, methodInfo.ReflectedType) : null;&lt;br/&gt;MethodCallExpression methodCallExpression = Expression.Call(instance2, methodInfo, list);&lt;br/&gt;if (methodCallExpression.Type == typeof(void))&lt;br/&gt;{&lt;br/&gt;   Expression&amp;lt;Action&amp;lt;object, object[]&gt;&gt; expression2 = Expression.Lambda&amp;lt;Action&amp;lt;object, object[]&gt;&gt;(methodCallExpression, new ParameterExpression[]&lt;br/&gt;   {&lt;br/&gt;      parameterExpression,&lt;br/&gt;      parameterExpression2&lt;br/&gt;   });&lt;br/&gt;   Action&amp;lt;object, object[]&gt; voidExecutor = expression2.Compile();&lt;br/&gt;   return delegate(object instance, object[] methodParameters)&lt;br/&gt;   {&lt;br/&gt;      voidExecutor(instance, methodParameters);&lt;br/&gt;      return null;&lt;br/&gt;   }&lt;br/&gt;   ;&lt;br/&gt;}&lt;br/&gt;UnaryExpression body = Expression.Convert(methodCallExpression, typeof(object));&lt;br/&gt;Expression&amp;lt;Func&amp;lt;object, object[], object&gt;&gt; expression3 = Expression.Lambda&amp;lt;Func&amp;lt;object, object[], object&gt;&gt;(body, new ParameterExpression[]&lt;br/&gt;{&lt;br/&gt;   parameterExpression,&lt;br/&gt;   parameterExpression2&lt;br/&gt;});&lt;br/&gt;return expression3.Compile();&lt;br/&gt;&lt;p&gt;取得返回结果之后， 再调用  ApiResponseConverter 的 GetResponseConverter 方法找到合适的 Converter ， 最后返回 Task&amp;lt;HttpResponseMessage&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IFilterProvider&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责提供过滤的标记， Web API 框架内置了下面的几个 FilterProvider ：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;EnumerableEvaluatorFilterProvider 负责提供对 IENumerable 的每个元素的转换的标记， 简单的说， 就是负责提供将 Action 方法返回的 IEnumerable 的结果进行自定义转换的标记；&lt;/li&gt;&lt;li&gt;QueryCompositionFilterProvider 负责对 Action 方法返回的 IQueryable 的结果进行符合 OData 约定的 URL 参数进行再次过滤的标记  QueryCompositionFilterAttribute ， 目前只支持 $filter 、 $orderby 、 $skip 以及 $top ；&lt;/li&gt;&lt;li&gt;ActionDescriptorFilterProvider &lt;/li&gt;&lt;li&gt;ConfigurationFilterProvider&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;注意， 这里说的是 FilterProvider， 不是 Filter ， 也不是 FilterAttribute 。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IActionValueBinder&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责绑定 Action 方法的参数， 默认的实现是 DefaultActionValuebinder ， 通过调用 ValueProviderFactory 、 ModelBinderProvider 进行参数绑定，  支持多种形式的参数绑定， 绑定策略比较复杂， 总的来说是简单的参数从 URL 中绑定，  复杂参数从 HTTP 请求内容中获取。 &lt;/p&gt;&lt;p&gt;&lt;strong&gt;ValueProviderFactory&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;定义了 Action 参数从哪里获取， 有以下几个实现， 分别支持从 URI 、 QueryString、 Post 内容中提取参数值：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CompositeValueProviderFactory &lt;/li&gt;&lt;li&gt;KeyValueModelProviderFactory&lt;/li&gt;&lt;li&gt;RouteDataValueProviderFactory&lt;/li&gt;&lt;li&gt;QueryStringValueProviderFactory&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;ModelBinderProvider &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;定义了如何将获取到的 HTTP 请求的的参数之绑定到指定的参数。 System.Web.Http.ModelBinding.Binders 命名空间内提供了多种 BinderProvider ， 应该可以处理大多数常见的类型。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ModelMetadataProvider &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责提供模型元数据描述信息。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ModelValidatorProvider &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;负责根据元素据信息对模型进行验证。 &lt;/p&gt;&lt;p&gt;&lt;strong&gt;IFormatterSelector&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;负责选择合适的格式， 包括客户端请求的格式以及服务端返回的格式， 默认实现是 FormatterSelector ， 能够提下面的 MediaFormater ：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;BufferedmediaTypeFormatter 提供对二进制格式的读取与写入；&lt;/li&gt;&lt;li&gt;FormUrlEncodedMediaTypeFormatter 提供对表单 URL 编码格式的读取与写入；&lt;/li&gt;&lt;li&gt;JsonMediaTypeFormatter 提供对 Json 格式的读取与写入；&lt;/li&gt;&lt;li&gt;XmlMediaFormatter 提供对 XML 格式的读取与写入。&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2411496.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/03/22/2411496.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/03/19/2406624.html</id><title type="text">ASP.NET Web API 简介</title><summary type="text">ASP.Net Web API 简介</summary><published>2012-03-19T13:00:00Z</published><updated>2012-03-19T13:00:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/03/19/2406624.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/03/19/2406624.html"/><content type="html">&lt;p&gt;ASP.NET MVC 4 包含了 ASP.NET Web API， 这是一个创建可以连接包括浏览器、移动设备等多种客户端的 Http 服务的新框架， ASP.NET Web API 也是构建 RESTful 服务的理想平台。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ASP.NET Web API 特性&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;ASP.NET Web API 包含下列特性：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;先进的 HTTP 编程模型：&lt;/strong&gt; 使用新的强类型的 HTTP 对象模型直接操作 HTTP 请求和响应， 在 HTTP客户端使用相同的编程模型和 HTTP 管道； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;支持路由：&lt;/strong&gt; Web API 完整支持 ASP.NET 路由， 包括路由参数和约束。 此外， 到动作的映射支持约定， 从此将不再需要向类或者方法添加类似于 [HttpPost] 之类的属性； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;内容协商：&lt;/strong&gt; 客户端与服务端可以一起决定 API 返回数据的格式。 默认支持 XML， JSON 以及 Form URL-Encoded 格式， 可以扩展添加自定义格式， 甚至可以替换掉默认的内容协商策略； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;模型绑定与验证：&lt;/strong&gt; 模型绑定器可以轻易地从 HTTP 请求中提取数据并转换成在动作方法中使用的 .Net 对象； &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;过滤：&lt;/strong&gt; Web API 支持过滤， 包括总所周知的 [Authorize] 过滤标记， 可以为 Action 添加并插入自定义过滤， 实现认证、异常处理等； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;查询聚合：&lt;/strong&gt; 只要简单的返回 Iqueryable&amp;lt;T&amp;gt; ， Web API 将会支持通过 OData 地址约定进行查询； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;改进的 Http 细节可测试性：&lt;/strong&gt; Web API 不是将 HTTP 细节设置到一个静态的 Context 对象上， 而是使用 HttpRequestMessage 和 HttpResponseMessage 实例， 可以使用这些对象的泛型版本为这些 Http 类型添加自定义类型； &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;改进的依赖反转 (IoC) 支持：&lt;/strong&gt; Web API 使用 MVC Dependency Resolver 实现的服务定位器模式在不同的场景下来获取实例； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;基于代码的配置：&lt;/strong&gt; Web API 单独使用代码完成配置， 从而保证了配置文件的整洁； &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;自托管 (Self-Host) ：&lt;/strong&gt; Web API 除了可以托管在 IIS 中， 还可以托管在进程中，依旧可以使用路由以及其它的特性。 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;第一个 Web API 程序&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;从零开始创建 Web API 项目&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1、 创建一个空的 ASP.NET 4.0 网站项目&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Untitled picture" border="0" alt="Untitled picture" src="http://images.cnblogs.com/cnblogs_com/beginor/201203/201203192057572606.png" width="492" height="295" /&gt; &lt;/p&gt;  &lt;p&gt;2、 添加对 System.Net.Http , System.Net.Http.Formatting , System.Web.Http , System.Web.Http.Common , System.Web.Http.WebHost 的引用&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="using" border="0" alt="using" src="http://images.cnblogs.com/cnblogs_com/beginor/201203/201203192057585081.png" width="312" height="227" /&gt; &lt;/p&gt;  &lt;p&gt;3、 添加 Global Application Class ， 并在 Global 类中的 Application_Start 方法中添加如下代码：&lt;/p&gt;  RouteTable.Routes.MapHttpRoute(&lt;br/&gt;   name: &amp;quot;DefaultApi&amp;quot;,&lt;br/&gt;   routeTemplate: &amp;quot;api/{controller}/{id}&amp;quot;,&lt;br/&gt;   defaults: new {&lt;br/&gt;      id = RouteParameter.Optional&lt;br/&gt;   }&lt;br/&gt;);&lt;p&gt;4、添加一个 ProductsController ， 继承自 ApiController ， 代码如下：&lt;/p&gt;public  class ProductController : ApiController {&lt;br/&gt;&lt;br/&gt;   public IQueryable&lt;product&gt; GetAllProducts() { ... }&lt;br/&gt;&lt;br/&gt;   public Product GetProductById(int id) { ... }&lt;br/&gt;&lt;br/&gt;}&lt;p&gt;5、 在浏览器输入 URI 访问资源， 也可以通过脚本等任何客户端进行访问， 以浏览器为例：&lt;/p&gt;&lt;p&gt;在地址栏输入 http://localhost:64334/api/products 将会访问到 GetAllProducts 方法， 返回所有的 Product 实例；&lt;/p&gt;&lt;p&gt;在地址栏输入 http://localhost:64334/api/products /1 将会访问到 GetProductById 方法， 返回指定 id 的 Product 实例；&lt;/p&gt;&lt;p&gt;&lt;strong&gt;理解 API 路由&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;对于每一个 Http 消息， ASP.NET Web API 框架通过路由表决定由哪个控制器处理请求。 当你创建一个新的 Web API 项目时， 将会包含一个类似这样的一个默认的路由：&lt;/p&gt;&lt;p&gt;/api/{controller}/{id}&lt;/p&gt;&lt;p&gt;{controller} 和 {id} 是两个占位符， 当遇到一个符合这种样式的 URI ， 将将会开始寻找合适的控制器方法进行调用， 规则如下：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;{controller} 用来与控制器名称像匹配； &lt;/li&gt;  &lt;li&gt;HTTP 请求的方法用来与方法名称匹配； （本规则只适用于 GET, POST, PUT 和 DELETE） &lt;/li&gt;  &lt;li&gt;{id} ， 如果有， 将会用于和方法的 id 参数进行匹配； &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这里有一些请求的例子， 以及基于当前实现情况的的 HTTP 动作结果：&lt;/p&gt;&lt;table border="1"&gt;&lt;tbody&gt;    &lt;tr&gt;      &lt;td&gt;HTTP Method&lt;/td&gt;      &lt;td&gt;URI&lt;/td&gt;      &lt;td&gt;Action&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;GET&lt;/td&gt;      &lt;td&gt;/api/products&lt;/td&gt;      &lt;td&gt;GetAllProducts&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;GET&lt;/td&gt;      &lt;td&gt;/api/products/5&lt;/td&gt;      &lt;td&gt;GetProduct(5)&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;POST&lt;/td&gt;      &lt;td&gt;/api/products&lt;/td&gt;      &lt;td&gt;HTTP Status 405&lt;/td&gt;    &lt;/tr&gt;    &lt;tr&gt;      &lt;td&gt;GET&lt;/td&gt;      &lt;td&gt;/api/users/&lt;/td&gt;      &lt;td&gt;HTTP Status 404&lt;/td&gt;    &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;在第一个例子中， 与 &amp;quot;products&amp;quot; 相匹配的是 ProductsController ， HTTP 请求的方法是 GET ， 所以框架开始在 ProductController 类里面寻找以 “Get” 开头的方法， 此外， URI 中没有提供 id 参数， 所以框架要找一个没有参数的方法， 最后， ProductsController 的 GetAllProducts 方法满足要求。&lt;/p&gt;&lt;p&gt;第二个例子与第一个类似， 不同的是 URI 里面包含了 {id} 参数。 因此， 框架调用 GetProduct 方法， 因为它需要一个名称为 id 参数。 值得注意的是， URI 里面的 id 参数是字符串类型的 “5” ， 框架会根据方法的签名自动把它转换成整形。&lt;/p&gt;&lt;p&gt;在第三个例子中， 客户端发起 HTTP Post 请求， 框架寻找名称以 “Post” 开始的方法。 而 ProductController 类没有这样的方法， 所以框架返回的 HTTP 状态码是 405 ， 表示不允许调用的方法 （Method Not Allowed） 。&lt;/p&gt;&lt;p&gt;再看第四个例子， 客户端发送一个 GET 请求到 /api/users 。 框架寻找名称为 UserController 的控制器， 这样的类还没有定义， 所以框架返回的 HTTP 状态码是 404 ， 表示请求的资源未找到。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Web API CURD&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;什么是 CURD&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;CURD 是指 Create 、 Update 、 Read 、 Delete 四个简单的数据库操作， 通常大多数 Web 服务也通过 REST 风格的服务提供这些操作。&lt;/p&gt;&lt;p&gt;接下来将继续完善 ProductsController 以支持下面所有的操作：&lt;/p&gt;&lt;div style="direction: ltr"&gt;  &lt;table style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; border-collapse: collapse; direction: ltr; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid" border="1" cellspacing="0" cellpadding="0" valign="top"&gt;&lt;tbody&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;动作&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;&lt;span style="font-family: calibri" lang="en-US"&gt;HTTP &lt;/span&gt;&lt;span style="font-family: 宋体" lang="zh-CN"&gt;方法&lt;/span&gt;&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;相对路径&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;获取全部&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;GET&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;&lt;span style="font-family: 宋体" lang="zh-CN"&gt;指定&lt;/span&gt;&lt;span style="font-family: calibri" lang="en-US"&gt; id &lt;/span&gt;&lt;span style="font-family: 宋体" lang="zh-CN"&gt;获取&lt;/span&gt;&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;GET&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products/id&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;添加&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;POST&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;更新&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;PUT&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products/id&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.025in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;删除&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 0.895in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;DELETE&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.273in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products/id&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;    &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;资源&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ProductController 提供了两种 URI 资源：&lt;/p&gt;&lt;div style="direction: ltr"&gt;  &lt;table style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; border-collapse: collapse; direction: ltr; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid" border="1" cellspacing="0" cellpadding="0" valign="top"&gt;&lt;tbody&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.146in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;资源&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.293in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;地址&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.146in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;全部产品列表&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.293in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;      &lt;tr&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.146in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p lang="zh-CN"&gt;单个产品&lt;/p&gt;        &lt;/td&gt;        &lt;td style="border-bottom: #a3a3a3 1pt solid; border-left: #a3a3a3 1pt solid; padding-bottom: 4pt; padding-left: 4pt; width: 1.293in; padding-right: 4pt; vertical-align: top; border-top: #a3a3a3 1pt solid; border-right: #a3a3a3 1pt solid; padding-top: 4pt"&gt;          &lt;p&gt;/api/products/id&lt;/p&gt;        &lt;/td&gt;      &lt;/tr&gt;    &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;HTTP 的四个主要方法 （GET， PUT， POST， DELETE） 按照下列方式映射为 CURD 操作：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;GET 用于获取 URI 资源的进行展示， GET 操作不应对服务端有任何影响； &lt;/li&gt;  &lt;li&gt;PUT 用于更新 URI 上的一个资源， 如果服务端允许， PUT 也可以用于新建一个资源； &lt;/li&gt;  &lt;li&gt;POST 用于新建 资源， 服务端在指定的 URI 上创建一个新的对象， 将新资源的地址作为响应消息的一部分返回； &lt;/li&gt;  &lt;li&gt;DELETE 用于删除指定的 URI 资源。 &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;实现 CURD &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;新建资源&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;客户端发起 HTTP POST 请求新建资源， 为了能处理 POST 请求， 需要在 ProductController 定义一个以 Post 开头的方法， 这个方法接受一个类型为 Product 的参数。&lt;/p&gt;&lt;p&gt;根据 HTTP/1.1 协议， 需要注意的问题有：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;响应代码： Web API 默认返回的响应代码是 200 (OK) ， 但是根据 HTTP/1.1 协议， POST 请求并创建资源的响应代码应该是 201 (Created)； &lt;/li&gt;  &lt;li&gt;地址： 当服务器创建资源之后， 应该在响应的 Header 里面包含新资源的地址。 &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;新建资源的最终代码如下：&lt;/p&gt;public HttpResponseMessage&lt;product&gt; PostProduct(Product product) {&lt;br/&gt;   this._dbContext.Save(product);&lt;br/&gt;   var result = new HttpResponseMessage&lt;product&gt;(product, HttpStatusCode.Created);&lt;br/&gt;   var location = Url.Route(null, new { id = product.ProductID });&lt;br/&gt;   result.Headers.Location = new Uri(location);&lt;br/&gt;   return result;&lt;br/&gt;}&lt;p&gt;&lt;strong&gt;更新资源内容&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;更新是比较简单的， 代码如下：&lt;/p&gt;public HttpResponseMessage PutProduct(int id, Product product) {&lt;br/&gt;   if (!this._dbContext.Products.Any(p =&amp;gt; p.ProductID == id)) {&lt;br/&gt;      throw new HttpResponseException(HttpStatusCode.NotFound);&lt;br/&gt;   }&lt;br/&gt;   product.ProductID = id;&lt;br/&gt;   this._dbContext.Update(product);&lt;br/&gt;   return new HttpResponseMessage(HttpStatusCode.OK);&lt;br/&gt;}&lt;p&gt;该方法需要两个参数， id 从 URI 中获取， product 从客户端请求消息中获取。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;删除资源&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;根据 HTTP 协议， 删除应当是幂等的， 也就是说一个 URI 上接受到多少个删除请求都是相同的， 如果资源已经被删除， 也不能返回错误的响应代码。&lt;/p&gt;&lt;p&gt;如果成功删除了资源， 可以返回 200 (OK) 响应代码， 以及一个实体进行状态说明， 或者返回 204 (No Content)。&lt;/p&gt;&lt;p&gt;如果删除需要等待事务完成， 则应该返回 202 (Accepted) 。&lt;/p&gt;&lt;p&gt;删除资源的实现代码如下：&lt;/p&gt;public HttpResponseMessage DeleteProduct(int id) {&lt;br/&gt;   var product = this._dbContext.Products.FirstOrDefault(p =&amp;gt; p.ProductID == id);&lt;br/&gt;   this._dbContext.Delete(product);&lt;br/&gt;   return new HttpResponseMessage(HttpStatusCode.NoContent);&lt;br/&gt;}&lt;img src="http://www.cnblogs.com/beginor/aggbug/2406624.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/03/19/2406624.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/02/26/2368984.html</id><title type="text">MonoTouch 在 iOS 上定义的一些特殊目录</title><summary type="text">介绍 MonoTouch 在 iOS 上的一些经常使用的特殊目录。</summary><published>2012-02-26T12:16:00Z</published><updated>2012-02-26T12:16:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/02/26/2368984.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/02/26/2368984.html"/><content type="html">&lt;p&gt;&lt;strong&gt;Environment.SpecialFolder&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;通过对 Environment.SpecialFolder 进行枚举， 可以得到 MonoTouch 在 iOS 设备上定义的特殊目录列表如下：&lt;/p&gt;  &lt;table border="1" cellspacing="2" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;th&gt;SpecialFolder&lt;/th&gt;        &lt;th&gt;iOS 模拟器#&lt;/th&gt;        &lt;th&gt;iOS 设备&lt;/th&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;font size="2" face="console"&gt;Desktop&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;#/Applications/{appid}/Desktop &lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;/private/var/mobile/Applications/{appid}/Desktop &lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;font size="2" face="console"&gt;Personal&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;#/Applications/{appid}/Documents&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;/private/var/mobile/Applications/{appid}/Documents&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;font size="2" face="console"&gt;Favorites&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;#/Applications/{appid}/Library/Favorites&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;/private/var/mobile/Applications/{appid}/Library/Favorites&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;font size="2" face="console"&gt;MyMusic&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;#/Applications/{appid}/Music&lt;/font&gt;&lt;/td&gt;        &lt;td&gt;&lt;font size="2" face="console"&gt;/private/var/mobile/Applications/{appid}/Music&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;MyVideos&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Videos&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Videos&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;DesktopDirectory&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Desktop&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Desktop&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Templates&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Templates&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Templates&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ApplicationData&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Documents/.config&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Documents/.config&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;LocalApplicationData&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Documents&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Documents&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;InternetCache&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Library/Caches&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Library/Caches&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;CommonApplicationData&lt;/td&gt;        &lt;td&gt;/usr/share&lt;/td&gt;        &lt;td&gt;/usr/share&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ProgramFiles&lt;/td&gt;        &lt;td&gt;/Applications&lt;/td&gt;        &lt;td&gt;/Applications&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;MyPictures&lt;/td&gt;        &lt;td&gt;#/Applications/{appid}/Pictures&lt;/td&gt;        &lt;td&gt;/private/var/mobile/Applications/{appid}/Pictures&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;# 表示 iOS 模拟器根目录， 通常为 ~/Library/Application Support/iPhone Simulator/5.0&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Environment.CurrentFolder&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;在程序中调用 Environment.CurrentFolder ， 在 iOS 模拟器上， 得到的值为 #/Applications/{appid}/{AppName}.app ， 在 iOS 设备商， 得到的值是 /private/var/mobile/Applications/{appid}/{AppName}.app 。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IsolatedStorage&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;在 iOS 上也使用 IsolatesStorage 与 Silverlight 大致相同， 不过iOS 上的本地存储只支持用户存储， 不支持机器独立存储， 也就是说只能使用下面三个方法是用本地存储：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;IsolatedStorageFile.GetUserStorage() &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;IsolatedStorageFile.GetUserStoreForAssembly() &lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;IsolatedStorageFile GetUserStoreForDomain() &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;通过跟踪发现， 这几个方法是用的独立存储目录是一样的， 都是存取 Environment.SpecialFolder.ApplicationData 目录。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2368984.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/02/26/2368984.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
