<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>FrankMao.com</title>
	<atom:link href="http://frankmao.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://frankmao.com</link>
	<description>IOC(SM):MOC(RM):TDD(NU):SCC(TFS):ORM(L2S):JSL(Jq):CIS(CC)</description>
	<lastBuildDate>Thu, 23 Feb 2012 17:29:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='frankmao.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>FrankMao.com</title>
		<link>http://frankmao.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://frankmao.com/osd.xml" title="FrankMao.com" />
	<atom:link rel='hub' href='http://frankmao.com/?pushpress=hub'/>
		<item>
		<title>Lookup in db or in code (enum)?</title>
		<link>http://frankmao.com/2012/02/23/lookup-in-db-or-in-code-enum/</link>
		<comments>http://frankmao.com/2012/02/23/lookup-in-db-or-in-code-enum/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 16:48:18 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1605</guid>
		<description><![CDATA[Maybe this is a solved problem already, but I couldn&#8217;t figure it out until today. With massive usage of NHibernate, lookup in db or in code always appear as a puzzle to me. For example, given a lookup dictionary like mime type: text/plain, text/html, image/gif and other stuff. It make sense to save all those [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1605&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Maybe this is a solved problem already, but I couldn&#8217;t figure it out until today. With massive usage of NHibernate, lookup in db or in code always appear as a puzzle to me. For example, given a lookup dictionary like mime type: text/plain, text/html, image/gif and other stuff. It make sense to save all those data into a table then enable foreign key on all referenced tables. But, in code, those mime type id itself will appear like magic number, I don&#8217;t likes this.</p>
<p>So, creating an enum contains all items solve the magic number issue, partly, and introduce another sync concern, what if data in db and enum in code out of sync?</p>
<p><a href="http://openlandscape.net/2011/04/16/hey-nhibernate-dont-mess-with-my-enums/">This post</a> demos a brilliant idea of creating enum on the fly, but mime value has slash in it, this solution doesn&#8217;t work. Also, wrapper class around enum seems unnecessary.</p>
<p>Based on the suggestion from <a href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/290534b6-11e5-4a26-8334-9cbb422337a2/">this post</a>. here comes my solution,</p>
<p><pre class="brush: csharp;">

   public enum MimeType
    {
        [Description(&quot;application/octet-stream&quot;)] ApplicationOctetStream,
        [Description(&quot;text/plain&quot;)] TextPlain = 1,
        [Description(&quot;text/html&quot;)] TextHtml,
        [Description(&quot;application/pdf&quot;)] ApplicationPdf,
        [Description(&quot;application/vnd.ms-excel&quot;)] ApplicationVndMsExcel,
        [Description(&quot;image/gif&quot;)] ImageGif,
        [Description(&quot;image/jpeg&quot;)] ImageJpeg,
        [Description(&quot;application/rtf&quot;)] ApplicationRtf,
        [Description(&quot;application/zip&quot;)] ApplicationZip,
        [Description(&quot;application/msword&quot;)] ApplicationMsword,
        [Description(&quot;application/mspowerpoint&quot;)] ApplicationMspowerpoint
    }

    /// &lt;summary&gt;
    /// Extension methods container for enum used to check synchronization between enum in code and data in db.
    /// see usage in should_fetch_all_mime_types() of EmailQueueRepositoryTest class
    /// &lt;/summary&gt;
    public static class MimeTypeEx
    {
        public static MimeType ToMimeTypeValue(this string value)
        {
            foreach (FieldInfo fi in typeof (MimeType).GetFields())
            {
                if (!fi.IsStatic)
                {
                    continue;
                }

                object[] attrs = fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
                if (attrs == null || attrs.Length &lt;= 0)
                {
                    continue;
                }

                var descr = (DescriptionAttribute) attrs[0];
                if (0 == string.Compare(value.Trim(), descr.Description))
                    // in case varchar type. trim it before compare.
                {
                    return (MimeType) fi.GetValue(null);
                }
            }

            throw new InvalidDataException(value);
            //return MimeType.Unknown;
        }

        public static string ToMimeTypeString(this MimeType value)
        {
            foreach (FieldInfo fi in typeof (MimeType).GetFields())
            {
                if (!fi.IsStatic || (MimeType) fi.GetValue(null) != value)
                {
                    continue;
                }

                object[] attrs = fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
                if (attrs == null || attrs.Length &lt;= 0)
                {
                    continue;
                }

                var descr = (DescriptionAttribute) attrs[0];
                return descr.Description;
            }

            return string.Empty;
        }
    }

    /// &lt;summary&gt;
    /// Used to read mime type from db, then we can check synchronization with defined enum mime type.
    /// &lt;/summary&gt;
    public class MimeTypeInDb
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual bool BinaryInd { get; set; }
    }

</pre></p>
<p>Test code, similar functionality should be done in app start or somewhere static ctor to ensure the synchronization.<br />
<pre class="brush: csharp;">
       [Test]
        public void should_fetch_all_mime_types()
        {
            var results = _repository.FetchAll&lt;MimeTypeInDb&gt;();

            Assert.That(results.Count(), Is.GreaterThan(0));

            foreach (MimeTypeInDb mimeTypeInDb in results)
            {
                Console.WriteLine(mimeTypeInDb.Name.ToMimeTypeValue()); // will throw invalid data exception if enum not found.
            }

            foreach (MimeType mimeType in Enum.GetValues(typeof(MimeType)))
            {
                Console.WriteLine(mimeType.ToMimeTypeString());
                if (! results.Any(x =&gt; x.Name.Trim() == mimeType.ToMimeTypeString()))
                {
                    Assert.Fail(mimeType.ToMimeTypeString() +&quot; not found in db.&quot;);
                }
            }
        }
</pre></p>
<p>About mapping the enum to int in FluentNHibernate:<br />
<pre class="brush: csharp;">
  Map(x =&gt; x.MimeType).Column(&quot;mime_type_id&quot;).CustomType&lt;int&gt;();
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1605/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1605&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/02/23/lookup-in-db-or-in-code-enum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>Cloud means surprise</title>
		<link>http://frankmao.com/2012/02/13/mind-changed-on-coding-with-sqs/</link>
		<comments>http://frankmao.com/2012/02/13/mind-changed-on-coding-with-sqs/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 18:55:23 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SQS]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1598</guid>
		<description><![CDATA[I have been looking for an opportunity to work on queue base project after finishing Udi Dahan&#8217;s Advanced distributed system design course. Because most of my projects are running on Linux OS where NSerivceBus is not applicable, using Amazon SQS became a affordable work around for now. Problem to solve My iClip iOS app recently [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1598&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have been looking for an opportunity to work on queue base project after finishing Udi Dahan&#8217;s Advanced distributed system design course. Because most of my projects are running on Linux OS where NSerivceBus is not applicable, using Amazon SQS became a affordable work around for now.</p>
<h2>Problem to solve</h2>
<p>My <a href="http://itunes.apple.com/us/app/iclip/id463896525?ls=1&amp;mt=8">iClip iOS app</a> recently encountered  unexpected popular requests for unknown reason (listed somewhere on an iOS app category site?). Even I only grant every new client only 3 free requests, with the huge amount of daily downloads, my server becomes slow and unstable gradually.</p>
<p>I could keep bumping up the memory on server, but I don&#8217;t like this solution at all. First, server hosting bill will go up dramatically; second, hosting server memory still has a max limitation of 4GB. Someday the client requests will eventually break this ceiling, then what?</p>
<h2>Solution</h2>
<p>I decided to move my request model to queue based architecture based on Amazon&#8217;s SQS service. Rewriting app didn&#8217;t take very long. After a week of production experience, here are some gotcha I&#8217;ve learned.</p>
<blockquote>
<ol>
<li>Message won&#8217;t be immediately available after send. Amazon actually state this delay will be up to 60 seconds on SQS admin console.</li>
<li>Deleted message might still be visible in queue. Explanation from Amazon is:<br />
<em>It is possible you will receive a message even after you have deleted it. This might happen on rare occasions if one of the servers storing a copy of the message is unavailable when you request to delete the message. The copy remains on the server and might be returned to you again on a subsequent receive request. You should create your system to be idempotent so that receiving a particular message more than once is not a problem.</em></li>
<li>For the similar reason as above, queue processor should really deal with duplicated request very carefully. For me, I use sendtimestamp as the identity of message.</li>
<li>Receiving message must set the visibility time out to a value greater than zero, to allow this message to be deleted successfully afterwards. (To be confirmed)</li>
</ol>
</blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1598/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1598&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/02/13/mind-changed-on-coding-with-sqs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>Re-configure dreamhost evniorment to support Amazon WebService</title>
		<link>http://frankmao.com/2012/01/19/re-configure-dreamhost-evniorment-to-support-amazon-webservice/</link>
		<comments>http://frankmao.com/2012/01/19/re-configure-dreamhost-evniorment-to-support-amazon-webservice/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 20:06:24 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AWS]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1594</guid>
		<description><![CDATA[I was trying to make my dreamhost to support Amazon WebService (aws), the first problem I encountered is, missing libxslt. Following the instruction here, I managed to install libxslt to my custom location. Watch out, the link on http://xmlsoft.org/XSLT/downloads.html is actually pointing to libxml2 which doesn&#8217;t include libxslt. You want to find the correct link from [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1594&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I was trying to make my dreamhost to support Amazon WebService (aws), the first problem I encountered is, missing libxslt.</p>
<p>Following the instruction <a href="http://discussion.dreamhost.com/post-119253.html">here</a>, I managed to install libxslt to my custom location.</p>
<p>Watch out, the link on http://xmlsoft.org/XSLT/downloads.html is actually pointing to libxml2 which doesn&#8217;t include libxslt. You want to find the correct link from ftp://xmlsoft.org/libxslt/</p>
<p>&nbsp;</p>
<p>The next problem is openssl support missing from ruby. I had to re-configure ruby to make it openssl ready. Instruction can be found <a href="http://www.ruby-forum.com/topic/62734">here</a>.</p>
<p>&nbsp;</p>
<p>All aws samples passed, then.</p>
<p>With one minor issue left, I got warning when running ruby:</p>
<blockquote><p>Invalid gemspec in [/home/me/.gems/specifications/openssl-extensions-1.2.0.gemspec]: invalid date format in specification: &#8220;2011-11-03 00:00:00.000000000Z&#8221;</p></blockquote>
<p>Hope I can figure this out later.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1594/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1594/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1594&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/01/19/re-configure-dreamhost-evniorment-to-support-amazon-webservice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>Use log4net filter to dispatch email notification based on string match</title>
		<link>http://frankmao.com/2012/01/06/use-log4net-filter-to-dispatch-email-notification-based-on-string-match/</link>
		<comments>http://frankmao.com/2012/01/06/use-log4net-filter-to-dispatch-email-notification-based-on-string-match/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 21:07:01 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Log]]></category>

		<guid isPermaLink="false">http://maonet.wordpress.com/?p=1589</guid>
		<description><![CDATA[filter type set to log4net.Filter.StringMatchFilter each filter section can only have one stringToMatch element end with a &#8220;log4net.Filter.DenyAllFilter&#8221; filter to switch from the default &#8220;accept all unless instructed otherwise&#8221; filtering behavior to a &#8220;deny all unless instructed otherwise&#8221; behavior.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1589&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<ul>
<li>filter type set to log4net.Filter.StringMatchFilter</li>
<li>each filter section can only have one stringToMatch element</li>
<li>end with a &#8220;log4net.Filter.DenyAllFilter&#8221; filter to switch from the default &#8220;accept all unless instructed otherwise&#8221; filtering behavior to a &#8220;deny all unless instructed otherwise&#8221; behavior.</li>
</ul>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;log4net debug=&quot;false&quot;&gt;

  &lt;appender name=&quot;SmtpAppender_WebTeam&quot; type=&quot;log4net.Appender.SmtpAppender&quot;&gt;
    &lt;to value=&quot;goodguy@me.com&quot; /&gt;
    &lt;from value=&quot;log4net@me.ca&quot; /&gt;
    &lt;subject value=&quot;!!!Web Exception happened!!!&quot; /&gt;
    &lt;smtpHost value=&quot;mail.server.ds&quot; /&gt;
    &lt;bufferSize value=&quot;512&quot; /&gt;
    &lt;lossy value=&quot;true&quot; /&gt;
    &lt;evaluator type=&quot;log4net.Core.LevelEvaluator&quot;&gt;
        &lt;threshold value=&quot;ERROR&quot;/&gt;
    &lt;/evaluator&gt;
    &lt;layout type=&quot;log4net.Layout.PatternLayout&quot;&gt;
        &lt;conversionPattern value=&quot;%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline&quot; /&gt;
    &lt;/layout&gt;
 	&lt;filter type=&quot;log4net.Filter.StringMatchFilter&quot;&gt;
		&lt;stringToMatch value=&quot;RequestManagement&quot; /&gt;
 	&lt;/filter&gt;
 	&lt;filter type=&quot;log4net.Filter.StringMatchFilter&quot;&gt;
		&lt;stringToMatch value=&quot;VineOnLine&quot; /&gt;
 	&lt;/filter&gt;
	&lt;filter type=&quot;log4net.Filter.DenyAllFilter&quot; /&gt;
  &lt;/appender&gt;
  &lt;appender name=&quot;SmtpAppender_VSE&quot; type=&quot;log4net.Appender.SmtpAppender&quot;&gt;
    &lt;to value=&quot;nice@me.ca&quot; /&gt;
    &lt;from value=&quot;log4net@mr.ca&quot; /&gt;
    &lt;subject value=&quot;!!!VSE Exception happened!!!&quot; /&gt;
    &lt;smtpHost value=&quot;mail.server.ds&quot; /&gt;
    &lt;bufferSize value=&quot;512&quot; /&gt;
    &lt;lossy value=&quot;true&quot; /&gt;
    &lt;evaluator type=&quot;log4net.Core.LevelEvaluator&quot;&gt;
        &lt;threshold value=&quot;ERROR&quot;/&gt;
    &lt;/evaluator&gt;
    &lt;layout type=&quot;log4net.Layout.PatternLayout&quot;&gt;
        &lt;conversionPattern value=&quot;%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline&quot; /&gt;
    &lt;/layout&gt;
	&lt;filter type=&quot;log4net.Filter.StringMatchFilter&quot;&gt;
		&lt;stringToMatch value=&quot;VSE&quot; /&gt;
	&lt;/filter&gt;
    &lt;filter type=&quot;log4net.Filter.DenyAllFilter&quot; /&gt;
  &lt;/appender&gt;

  &lt;root&gt;
    &lt;level value=&quot;INFO&quot; /&gt;

    &lt;appender-ref ref=&quot;SmtpAppender_WebTeam&quot; /&gt;
    &lt;appender-ref ref=&quot;SmtpAppender_VSE&quot; /&gt;

  &lt;/root&gt;
  &lt;logger name=&quot;NHibernate&quot;&gt;
    &lt;level value=&quot;ERROR&quot;/&gt;
  &lt;/logger&gt;

&lt;/log4net&gt;

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1589/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1589&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/01/06/use-log4net-filter-to-dispatch-email-notification-based-on-string-match/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>NHibernate Session.Query ignore Fetch Join?</title>
		<link>http://frankmao.com/2012/01/06/nhibernate-session-query-ignore-fetch-join/</link>
		<comments>http://frankmao.com/2012/01/06/nhibernate-session-query-ignore-fetch-join/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 20:51:48 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1585</guid>
		<description><![CDATA[We set up child collection relationship to Fetch as Join in mapping, using fluentNHibernate: HasMany( x =&#62; Details ).Fetch.Join(); It works fine at least for Session.Get&#60;T&#62;(id), we can see only one joined query instead of two separated ones. But it seems  Session.Query&#60;T&#62;() keeps ignoring this join fetch setting, we always got two separated selects when [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1585&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We set up child collection relationship to Fetch as Join in mapping, using fluentNHibernate:</p>
<blockquote><p>HasMany( x =&gt; Details ).Fetch.Join();</p></blockquote>
<p>It works fine at least for Session.Get&lt;T&gt;(id), we can see only one joined query instead of two separated ones.</p>
<p>But it seems  Session.Query&lt;T&gt;() keeps ignoring this join fetch setting, we always got two separated selects when using Session.Query&lt;T&gt;. A Bug?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1585/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1585/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1585&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/01/06/nhibernate-session-query-ignore-fetch-join/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>Share static html in MVC views</title>
		<link>http://frankmao.com/2012/01/04/share-static-html-in-mvc-views/</link>
		<comments>http://frankmao.com/2012/01/04/share-static-html-in-mvc-views/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 17:02:49 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1577</guid>
		<description><![CDATA[PartialView can be used to share page content, but our shared content are purely static and would like to share it among multiple web apps, doesn&#8217;t have to be MVC apps. We have tried SSI (Server side include) on IIS,  but it turns out it doesn&#8217;t work in Razor view. Spuriously, many people said SSI [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1577&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>PartialView can be used to share page content, but our shared content are purely static and would like to share it among multiple web apps, doesn&#8217;t have to be MVC apps.</p>
<p>We have tried SSI (Server side include) on IIS,  but it turns out it doesn&#8217;t work in Razor view. Spuriously, many people said SSI is dead, and by default IIS7 doesn&#8217;t turn SSI on, here is the doc how to install and configure SSI on IIS7. <a href="http://www.iis.net/ConfigReference/system.webServer/serverSideInclude">install it</a>, <a href="http://tech.mikeal.com/blog1.php/server-side-includes-for-html-in-iis7">configure it</a> (if your included file is not named as shtm)</p>
<p>For now the best solution I found is putting this code in Razor view.</p>
<blockquote><p>@MvcHtmlString.Create(File.ReadAllText(Server.MapPath(&#8220;/_shared/footer.htm&#8221;)))</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1577/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1577&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2012/01/04/share-static-html-in-mvc-views/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>Make method parameter strongly typed without if/switch</title>
		<link>http://frankmao.com/2011/12/16/make-method-parameter-strongly-typed-without-ifswitch/</link>
		<comments>http://frankmao.com/2011/12/16/make-method-parameter-strongly-typed-without-ifswitch/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 18:45:10 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Design Patterns]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1573</guid>
		<description><![CDATA[Given a class method can generate report based on the type passed in from method parameter, an easy way to make parameter strongly typed is using enum: The problem here is: enum type in dotnet only supports integer, converting to string has to be done somewhere usually in a place different than the type define [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1573&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Given a class method can generate report based on the type passed in from method parameter, an easy way to make parameter strongly typed is using enum:</p>
<p><pre class="brush: csharp;">

    class ReportGenerator
    {
        string _reportTypeInString;
        enum ReportType
        {
            PDF = 0,
            EXCEL,
            HTML
        }

        void GetReport(ReportType reportType)
        {
            switch (reportType)
            {
                case ReportType.PDF:
                    _reportTypeInString = &quot;PDF&quot;;
                    break;
                case ReportType.EXCEL:
                    _reportTypeInString = &quot;EXCEL&quot;;
                    break;
                case ReportType.HTML:
                    _reportTypeInString = &quot;HTML40&quot;;
                    break;

            }
            // logic to generate real report...
        }
    }

</pre></p>
<p>The problem here is: enum type in dotnet only supports integer, converting to string has to be done somewhere usually in a place different than the type define area, maintenance is problematic. Besides, the evil if/switch code smell.</p>
<p>Here is my way to do the same job:</p>
<p><pre class="brush: csharp;">

        public class ReportFormat
        {
            public string ReportFormatString { get; private set; }

            public static ReportFormat HTML32 = new ReportFormat(&quot;HTML3.2&quot;);
            public static ReportFormat HTML40 = new ReportFormat(&quot;HTML4.0&quot;);
            public static ReportFormat EXCEL = new ReportFormat(&quot;EXCEL&quot;);
            public static ReportFormat CSV = new ReportFormat(&quot;CSV&quot;);
            public static ReportFormat PDF = new ReportFormat(&quot;PDF&quot;);
            public static ReportFormat MHTML = new ReportFormat(&quot;MHTML&quot;);

            ReportFormat(string reportFormatString)
            {
                ReportFormatString = reportFormatString;
            }
        }

//in my report generator class:
        public FileContentResult GetReport(string reportName, ReportFormat reportFormat, IList&lt;ParameterValue&gt; parameters)
        {...}
// how to use
        var fileContentResult = reportingServiceProxy.GetReport(ReportName, ReportingServiceProxy.ReportFormat.HTML40, parameters);

</pre></p>
<p>Work amount is almost same, the type maintenance is in same place, the biggest selling point, no evil if/switch statement anymore.</p>
<p>Which design pattern is used here?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1573/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1573&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2011/12/16/make-method-parameter-strongly-typed-without-ifswitch/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>How to unit-test class has dependency on HttpResponse</title>
		<link>http://frankmao.com/2011/12/16/how-to-unit-test-class-has-dependency-on-httpresponse/</link>
		<comments>http://frankmao.com/2011/12/16/how-to-unit-test-class-has-dependency-on-httpresponse/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 18:23:04 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[ASP]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[web abstraction]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1566</guid>
		<description><![CDATA[When getting report from reporting service through  asmx web service, the proxy class needs to set some custom header to HttpResponse, work can be done, but unit-test it is not easy. Google result indicates that we can take advantage of HttpResponseBase and HttpResponseWrapper from System.Web and System.Web.Abstraction. The class diagram looks like this: Instead of directly [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1566&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When getting report from reporting service through  asmx web service, the proxy class needs to set some custom header to HttpResponse, work can be done, but unit-test it is not easy. Google result indicates that we can take advantage of HttpResponseBase and HttpResponseWrapper from System.Web and System.Web.Abstraction.</p>
<p>The class diagram looks like this:</p>
<p><a href="http://maonet.files.wordpress.com/2011/12/unittesthttpresponse.png"><img class="aligncenter size-full wp-image-1567" title="UnitTestHttpResponse" src="http://maonet.files.wordpress.com/2011/12/unittesthttpresponse.png?w=600" alt=""   /></a></p>
<p>Instead of directly depending on HttpContext.Current.Response, we need to change the dependency to HttpResponseBase class, from which both HttpResponseWrapper (in production) and HttpResponseFake (in unit-test) are derived.</p>
<p>Code example:</p>
<p><pre class="brush: csharp;">
    public class ReportingServiceProxy
    {
        private readonly HttpResponseBase _response;
        public ReportingServiceProxy()
            : this(new HttpResponseWrapper(HttpContext.Current.Response))
        {}
        public ReportingServiceProxy(HttpResponseBase httpResponse)
        {
            _response = httpResponse;
            //...
        }
        public FileContentResult GetReport(string reportName, ReportFormat reportFormat, IList parameters)
        {
            // ...
            _response.AddHeader(&quot;cache-control&quot;, &quot;must-revalidate&quot;);
        }
    }

    public class HttpResponseFake : HttpResponseBase
    {
        public override void AddHeader(string name, string value)
        {
            Console.WriteLine(&quot;Header {0} added with value: {1}&quot;, name, value);
        }
    }

        [Test]
        public void should_get_report_from_test_env()
        {
            var reportingServiceProxy = new ReportingServiceProxy(new HttpResponseFake());
            ...
        }

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1566/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1566&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2011/12/16/how-to-unit-test-class-has-dependency-on-httpresponse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>

		<media:content url="http://maonet.files.wordpress.com/2011/12/unittesthttpresponse.png" medium="image">
			<media:title type="html">UnitTestHttpResponse</media:title>
		</media:content>
	</item>
		<item>
		<title>MPMoviePlayerController</title>
		<link>http://frankmao.com/2011/12/13/mpmovieplayercontroller/</link>
		<comments>http://frankmao.com/2011/12/13/mpmovieplayercontroller/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 17:07:57 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1561</guid>
		<description><![CDATA[I need implement the following two features in most of my iOS apps, e.g., iClip: auto-play-next-episode if available auto resume from the stop point last time stopped/pasued By looking into the developers doc, the first one is easy to do, just observe the MPMoviePlayerPlaybackDidFinishNotification: Notice the finished reason in iOS 4 (bug) is always MPMovieFinishReasonPlaybackEnded, I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1561&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I need implement the following two features in most of my iOS apps, e.g., <a href="http://itunes.apple.com/us/app/iclip/id463896525?ls=1&amp;mt=8">iClip</a>:</p>
<ul>
<li>auto-play-next-episode if available</li>
<li>auto resume from the stop point last time stopped/pasued</li>
</ul>
<p>By looking into the developers doc, the first one is easy to do, just observe the MPMoviePlayerPlaybackDidFinishNotification:</p>
<p><pre class="brush: cpp;">

-(void)playMovieAtURL:(NSURL*)theURL
{

	MPMoviePlayerViewController* mpvc =[[MPMoviePlayerViewController alloc] initWithContentURL:theURL];
	[self presentModalViewController:mpvc animated:NO];

	double stoppedPoint = [[NSUserDefaults standardUserDefaults] doubleForKey:[mpvc.moviePlayer.contentURL absoluteString]];
	if (stoppedPoint &gt; 0.0) {
		mpvc.moviePlayer.initialPlaybackTime = stoppedPoint;
	}

	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(myMovieFinishedCallback:)
												 name:MPMoviePlayerPlaybackDidFinishNotification
											   object:mpvc.moviePlayer];

	if (![self isOS5])
	{
		mpvc.moviePlayer.useApplicationAudioSession = NO;
	}

	self.mpvc = mpvc; //retain it
	[mpvc release];
	return;

}

// When the movie is done,release the controller.
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{

    if ([[aNotification object] isKindOfClass:[MPMoviePlayerController class]])
    {
        MPMoviePlayerController* theMovie=[aNotification object];
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:theMovie];

        [self  dismissModalViewControllerAnimated:NO];

        theMovie = nil;
        [theMovie release];
    }

    NSDictionary *userInfo = [aNotification userInfo];

    int reason = [[userInfo objectForKey:@&quot;MPMoviePlayerPlaybackDidFinishReasonUserInfoKey&quot;] intValue];
    NSLog(@&quot;clip finished because %d. play next one if available.&quot;, reason);
    // ios 4 always return MPMovieFinishReasonPlaybackEnded even it's user exit it, a bug. don't provide play next feature for ios4 users then.
    if ([self isOS5] &amp;&amp; reason == MPMovieFinishReasonPlaybackEnded)
    {
        [self playNextEpisodeIfAvailable];
    }
}
</pre></p>
<p>Notice the finished reason in iOS 4 (bug) is always MPMovieFinishReasonPlaybackEnded, I had to implement the same feature in MPMoviePlayerPlaybackStateDidChangeNotification for iOS 4 users:</p>
<p><pre class="brush: cpp;">

-(void)myMovieStateChangedCallback:(NSNotification*)aNotification
{
    if ([[aNotification object] isKindOfClass:[MPMoviePlayerController class]])
    {
        MPMoviePlayerController* theMovie=[aNotification object];
        if (theMovie.playbackState == MPMoviePlaybackStateStopped &amp;&amp; theMovie.currentPlaybackTime == theMovie.playableDuration) {
            NSLog(@&quot;clip finished!&quot;);

            if ([self isOS5]) {

            }else{
                [self playNextEpisodeIfAvailable];
            }
        }

</pre></p>
<p>For second feature, saving stop point when movie exit, I also use the MPMoviePlayerPlaybackStateDidChangeNotification to catch the currentPlaybackTime, I&#8217;ve tried catch it in MPMoviePlayerPlaybackDidFinishNotification, the value is zero, too late.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1561/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1561/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1561&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2011/12/13/mpmovieplayercontroller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
		<item>
		<title>WIF, ADFS, OIF, OpenSSO/OpenAM</title>
		<link>http://frankmao.com/2011/11/18/wif-adfs-oif-openssoopenam/</link>
		<comments>http://frankmao.com/2011/11/18/wif-adfs-oif-openssoopenam/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 21:42:06 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[ADFS]]></category>
		<category><![CDATA[WIF]]></category>

		<guid isPermaLink="false">http://frankmao.com/?p=1554</guid>
		<description><![CDATA[WIF provide a way to separate security concern out from dotnet applications. Outsource identity/authorization task to a 3rd party IDP/STS really loose the structure of classic web apps, no need to write those user registration / profile management / group assignment common task again and again, and the app is only loose coupled with IDP [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1554&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>WIF provide a way to separate security concern out from dotnet applications. Outsource identity/authorization task to a 3rd party IDP/STS really loose the structure of classic web apps, no need to write those user registration / profile management / group assignment common task again and again, and the app is only loose coupled with IDP through Claims.</p>
<p>The idea is neat, but finding a right STS is not easy.</p>
<p>ADFS 2.0 can handle LDAP user without any problem, the off-shelf features don&#8217;t cover extranet users.</p>
<p>The out-of-box WIF template provides a local STS for dev purpose only, and it&#8217;s using WS-Fe</p>
<p>WIF application is only talking to STS through WS-Federation protocol, (SAML 2.0 Protocol support can be downloaded <a href="http://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=36088">here</a>, I haven&#8217;t try it yet), while Oracle STS speaks WS-Trust, Web Service only?</p>
<p>Right now the solution is use ADFS as gateway between WIF app and 3rd-parth IDP.</p>
<p><img class="alignnone" title="ADFS federation" src="http://www.gliffy.com/pubdoc/3080593/L.png" alt="" width="545" height="556" /></p>
<p>Some difficulties we encountered:</p>
<h3>Not getting home-realm discovery page from ADFS</h3>
<p>This problem was caused by when importing claim provider trust federation metadata into ADFS, the endpoint was not imported, ADFS only accept https endpoint.</p>
<h4>HTTP Error 503 on adfs/services/trust and get the service unavailable after STS login successfully</h4>
<p>This happens to StarterSTS and CustomSTS, for StarterSTS, folloew <a href="http://www.leastprivilege.com/AddingStarterSTSAsAClaimsProviderForADFS2.aspx">this post </a>to add relying party key into StarterSTS and export token decryption certificate. Note the original post missed a key name in configure demo code.</p>
<p>For CustomSTS (WIF test STS), the ADFS replyToAddress needs to set manually based on the Federation Service identifier, an example can be found <a href="http://netpl.blogspot.com/2011/09/quest-for-customizing-adfs-sign-in-web_12.html">here</a> as well.</p>
<p><pre class="brush: csharp;">
public class CustomSecurityTokenService : SecurityTokenService
{
    protected override Scope GetScope( IClaimsPrincipal principal, RequestSecurityToken request )
    {...
        foreach (var key in ConfigurationManager.AppSettings.AllKeys)
        {
            _logger.Debug(string.Format(&quot;checking [{0}] with [{1}]&quot;, scope.AppliesToAddress, key));
            if (string.Equals(scope.AppliesToAddress.ToLower(), key.ToLower()))

                scope.ReplyToAddress = ConfigurationManager.AppSettings[key];
        }

</pre></p>
<p><pre class="brush: xml;">
  &lt;appSettings&gt;
    &lt;add key=&quot;http://adfsserver/adfs/services/trust&quot;
           value=&quot;https://adfsserver/adfs/ls/&quot;/&gt;
  &lt;/appSettings&gt;
</pre></p>
<h4>SP doen&#8217;st support urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</h4>
<p>This happens to OpenSSO, we finally used SAML Tracker addon in Firefox to figure out it&#8217;s in SAML token ADFS sending to IDP. Then followed this <a href="http://social.technet.microsoft.com/wiki/contents/articles/4038.aspx">post</a> to changed the default format from unspecified to something else.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/1554/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/1554/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/1554/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=frankmao.com&amp;blog=431779&amp;post=1554&amp;subd=maonet&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://frankmao.com/2011/11/18/wif-adfs-oif-openssoopenam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>

		<media:content url="http://www.gliffy.com/pubdoc/3080593/L.png" medium="image">
			<media:title type="html">ADFS federation</media:title>
		</media:content>
	</item>
	</channel>
</rss>
