<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-776222647855423698</id><updated>2012-01-27T14:43:29.355+05:30</updated><category term='java 1.5'/><category term='mobile number'/><category term='append pdf'/><category term='flash'/><category term='Fluent API'/><category term='functional test'/><category term='doThrow'/><category term='java 5'/><category term='styles not loading'/><category term='application scope'/><category term='The referenced project does not exist'/><category term='access point'/><category term='production'/><category term='razor view engine'/><category term='htc mytouch 4g'/><category term='aramex'/><category term='bad roads'/><category term='maven'/><category term='selenium'/><category term='integrating NHibernate with MVC3'/><category term='image gallery for mobile'/><category term='Buckingham Fountain'/><category term='maid of the mist'/><category term='http session'/><category term='JDK 32 bit'/><category term='radcombobox'/><category term='html to pdf'/><category term='message'/><category term='white house'/><category term='hidden treasures of IE'/><category term='date range'/><category term='cloud gate'/><category term='redirect'/><category term='image and text insert into pdf'/><category term='BufferedInputStream'/><category term='multiple streams of work'/><category term='java 1.6'/><category term='UIRequiresPersistentWiFi'/><category term='convention over configuration'/><category term='distributed version control system'/><category term='argLine'/><category term='opera'/><category term='labourer'/><category term='baseball'/><category term='how not to do things'/><category term='suppress constructor'/><category term='peace'/><category term='java'/><category term='Subversion'/><category term='wifi'/><category term='cobertura'/><category term='options menu'/><category term='fromJson'/><category term='paged medium'/><category term='aspnet_compiler'/><category term='verifyStatic'/><category term='government'/><category term='Seperation of Concerns'/><category term='lincoln memorial'/><category term='web developer'/><category term='rocks'/><category term='toJson'/><category term='time bomb'/><category term='jquery-ui'/><category term='FlushedInputStream'/><category term='security laps'/><category term='script tag'/><category term='edit commit'/><category term='controller'/><category term='lohagad'/><category term='BitmapFactory'/><category term='joda time'/><category term='windows firewall'/><category term='full screen gallery with navigation links'/><category term='unit testing'/><category term='NHibernate'/><category term='asp.net'/><category term='PermGen space'/><category term='4095 CSS Selectors'/><category term='cash on delivery'/><category term='what are ivory tower architects'/><category term='json'/><category term='flying saucer'/><category term='partial mock'/><category term='31 styles sheets'/><category term='doNothing'/><category term='OutOfMemoryError'/><category term='removeMetaClass'/><category term='ruby'/><category term='change background color of options menu'/><category term='washington d.c.'/><category term='one-to-many'/><category term='void method'/><category term='lenient date'/><category term='fort'/><category term='packt publishing'/><category term='InputStream'/><category term='wise decisions'/><category term='static method'/><category term='web page'/><category term='reorder commits'/><category term='final method'/><category term='how to run ie6 on windos 7'/><category term='asmx'/><category term='flip side'/><category term='problems with telerik controls'/><category term='tomcat'/><category term='IE 8'/><category term='ICICI'/><category term='untestable code'/><category term='git svn crash course'/><category term='skia decoder'/><category term='mvc3 and web forms in one project'/><category term='active programming'/><category term='JsonDeserializer'/><category term='windows 7 xp mode'/><category term='virtual path'/><category term='tax payers'/><category term='spy'/><category term='Grails 1.2'/><category term='programmer'/><category term='31 reasons to hate IE'/><category term='ios'/><category term='IE 7'/><category term='suppress method'/><category term='bad experience'/><category term='orientation'/><category term='integrating spring.net with asmx webservices'/><category term='delhi airport'/><category term='jasper'/><category term='circular file references are not allowed'/><category term='argument matchers'/><category term='invoke'/><category term='menu'/><category term='external merge tool'/><category term='IsPostBack'/><category term='mobile image gallery'/><category term='driver'/><category term='web project'/><category term='sears tower'/><category term='interaction based testing'/><category term='enlist transaction'/><category term='telerik controls'/><category term='Lokmanya Tilak'/><category term='tools and framework'/><category term='stored procedures'/><category term='strict date'/><category term='stub'/><category term='how to use git over svn'/><category term='howto'/><category term='intent'/><category term='output parameters'/><category term='blocked mysql port'/><category term='git difftool'/><category term='JSON to object'/><category term='bad infrastructure'/><category term='hudson'/><category term='existing pdf'/><category term='touchgallery'/><category term='worst customer care'/><category term='unpatched IE'/><category term='issue'/><category term='grant privilege'/><category term='squash commits'/><category term='private'/><category term='onRestoreInstanceState'/><category term='powermock'/><category term='suppress static initializer'/><category term='jquery'/><category term='technical problems'/><category term='user control'/><category term='operator precedence'/><category term='validate date'/><category term='web forms'/><category term='powermocks'/><category term='visual studio 2010'/><category term='onRetainNonConfigurationInstance'/><category term='architect'/><category term='serializer'/><category term='htc desire hd'/><category term='property-ref'/><category term='selenium features'/><category term='getLastNonConfigurationInstance'/><category term='filthy rivers'/><category term='git tutorial'/><category term='TimeZone'/><category term='working on two things at a time with GIT'/><category term='photoswipe'/><category term='JDK 64 bit'/><category term='IconMenuItemView'/><category term='love concepts'/><category term='No View State'/><category term='weird url'/><category term='productive from day 1'/><category term='Single Responsibility Principle'/><category term='letsbuy.com'/><category term='onSaveInstanceState'/><category term='continuous integration'/><category term='activity is destroyed and recreated when screen orientation changes'/><category term='DNS'/><category term='pom.xml'/><category term='stored procedure with out parameters'/><category term='html5'/><category term='different browsers on windows 7'/><category term='washington monument'/><category term='symptoms of ivory tower architect'/><category term='session scope'/><category term='junit'/><category term='mysql remote access'/><category term='visibility'/><category term='invalid date'/><category term='no internet'/><category term='problems with SVN'/><category term='change text color of options menu'/><category term='capitol building'/><category term='msbuild'/><category term='date'/><category term='HttpClient'/><category term='power mock'/><category term='windows 7'/><category term='grails'/><category term='dont love one language'/><category term='travel'/><category term='doReturn'/><category term='GIT'/><category term='css'/><category term='rejuvenate'/><category term='easiest way to run ie 6 on windows 7'/><category term='30 minutes'/><category term='reword commit'/><category term='JsonSerializer'/><category term='web service'/><category term='team anna'/><category term='criteria api'/><category term='css 2.1'/><category term='.net'/><category term='finding the real culprit'/><category term='GIT over SVN'/><category term='web image'/><category term='date validation'/><category term='Driving Directions'/><category term='Handler'/><category term='turn by turn directions'/><category term='out parameters'/><category term='git bisect'/><category term='integrating spring.net with web forms'/><category term='state based testing'/><category term='niagara falls'/><category term='QueryOver'/><category term='out of memory error'/><category term='google maps'/><category term='deserializer'/><category term='Selenium 1.0 Testing Tools: Beginner’s Guide'/><category term='power mockito'/><category term='evil constructor'/><category term='max path length'/><category term='legacy database'/><category term='void static method'/><category term='mvc3'/><category term='git mergetool'/><category term='maven2'/><category term='india'/><category term='uses-permission'/><category term='radtextbox'/><category term='IE 6'/><category term='convert html to pdf'/><category term='oracle'/><category term='jarjar'/><category term='is your bank account safe'/><category term='anna hazare'/><category term='MAVEN_OPTS'/><category term='ClassNotFoundException'/><category term='android'/><category term='update existing pdf'/><category term='git svn tutorial'/><category term='firefox 3'/><category term='wifi connection closed after 30 minutes'/><category term='spoon.net'/><category term='mockDomain'/><category term='verifyPrivate'/><category term='distributed teams'/><category term='book review'/><category term='session'/><category term='one dll per folder'/><category term='weblogic'/><category term='external diff tool'/><category term='configChanges'/><category term='259'/><category term='composite primary key'/><category term='mockFor'/><category term='testing'/><category term='aspx rendering engine'/><category term='virginia beach'/><category term='object to JSON'/><category term='verify'/><category term='NHibernate LINQ provider'/><category term='good solutions'/><category term='ganesh festival'/><category term='cave of the winds'/><category term='web qa'/><category term='DVCS'/><category term='poor'/><category term='powermockito'/><category term='firefox 2'/><category term='create user'/><category term='javascript'/><category term='PowerMockIgnore'/><category term='Calendar'/><category term='JVM_OPTS'/><category term='adding remote SVN branch to GIT'/><category term='strongly typed session'/><category term='jenkins'/><category term='fixing'/><category term='ipad'/><category term='mock'/><category term='Bitmap'/><category term='CI'/><category term='online shopping'/><category term='navy pier'/><category term='lookahead downloader'/><category term='skip method'/><category term='rewrite history'/><category term='remove commits'/><category term='android emulator'/><category term='Microsoft.WebApplication.targets'/><category term='trek'/><category term='heap space'/><category term='pdf creator'/><category term='vm image'/><category term='portrait'/><category term='ivory tower architect'/><category term='itext'/><category term='jquery does not work with telerik controls'/><category term='InvalidCastException'/><category term='browser'/><category term='natural beauty'/><category term='final class'/><category term='chicago'/><category term='proxy settings'/><category term='merge commits'/><category term='integrating spring.net with mvc3'/><category term='PathClassLoader'/><category term='suppress field'/><category term='mockito'/><category term='be a programmer'/><category term='partial URL'/><category term='memory leak'/><category term='LayoutInflater.Factory'/><category term='debug'/><category term='dependency injection'/><category term='ugly cities'/><category term='evil method'/><category term='MockClassLoader'/><category term='ICICI Bank'/><category term='india against corruption'/><category term='convert'/><category term='minneapolis'/><category term='decode returned false'/><category term='catalina'/><category term='unblock mysql port'/><category term='kdiff with git'/><category term='jquery lightbox'/><category term='letsbuy review'/><category term='Gson'/><category term='constructor'/><category term='security problem'/><category term='ietester'/><category term='C#'/><category term='how to handle screen orientation changes'/><category term='interactive rebase'/><category term='datepicker'/><category term='non standard SVN repositories'/><category term='wow moment'/><category term='modelAndView'/><category term='static initializer'/><category term='stay in touch with coding'/><category term='razor view'/><category term='spring.net'/><category term='SVN'/><category term='landscape'/><category term='mvc vs web forms'/><category term='ImageView'/><category term='fiddler'/><category term='deadlock'/><title type='text'>Deep Shah's Blog</title><subtitle type='html'>Coding is an art. Not everyone is an Artist!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.gitshah.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>86</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-4039010525964030024</id><published>2012-01-22T13:56:00.001+05:30</published><updated>2012-01-22T14:04:38.378+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='cash on delivery'/><category scheme='http://www.blogger.com/atom/ns#' term='bad experience'/><category scheme='http://www.blogger.com/atom/ns#' term='online shopping'/><category scheme='http://www.blogger.com/atom/ns#' term='letsbuy review'/><category scheme='http://www.blogger.com/atom/ns#' term='aramex'/><category scheme='http://www.blogger.com/atom/ns#' term='worst customer care'/><category scheme='http://www.blogger.com/atom/ns#' term='letsbuy.com'/><title type='text'>LetsBuy.com A Perfect Example of How Not to Run an Online Shopping Website</title><content type='html'>Today I am going to narrate a story, A real story.&lt;br /&gt;&lt;br /&gt;In this story, lead role is played by &lt;a href="http://www.gitshah.com/"&gt;Deep Shah&lt;/a&gt; (&lt;b&gt;name not changed&lt;/b&gt;) and His Friends.  Every story has good guys and the bad guys right, in this story the bad guys are &lt;a href="http://www.letsbuy.com/"&gt;LetsBuy.com&lt;/a&gt; (&lt;b&gt;name not changed&lt;/b&gt;) as a company (nothing personal against anyone).  There are some side hero's in the story as well, I will introduce them as and when they appear.I am all exited to tell the story to you guys, so here it goes!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Plot:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There was a guy called Deep Shah - A Software engineer living in Pune.&amp;nbsp; He wanted to buy a new mobile, specs he wanted were: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Android OS&lt;/li&gt;&lt;li&gt;Dual core CPU&lt;/li&gt;&lt;li&gt;Minimum 4" Screen&lt;/li&gt;&lt;li&gt;1GB RAM&lt;/li&gt;&lt;li&gt;Budget max Rs. 20K (approx&amp;nbsp; $400)&lt;/li&gt;&lt;/ul&gt;For a very long time none of the phones met all his criteria.&amp;nbsp; &lt;a href="http://www.samsung.com/in/consumer/mobile-phone/mobile-phone/smartphone/GT-I9103MAAINU/index.idx?pagetype=prd_detail"&gt;Samsung Galaxy R&lt;/a&gt; (around Rs. 25K), Samsung &lt;a href="http://www.samsung.com/in/consumer/mobile-phone/mobile-phone/smartphone/GT-I9100LKAINU/index.idx?pagetype=prd_detail"&gt;Galaxy S-II&lt;/a&gt; (around Rs. 28K) and &lt;a href="http://www.samsung.com/in/galaxynote/"&gt;Samsung Galaxy Note&lt;/a&gt; (around Rs. 33K) would match the technical specs but were totally out of his budget.&lt;br /&gt;&lt;br /&gt;Then one day, one of his friend pointed out that prices of Samsung Galaxy R have fallen to about Rs. 21K.&amp;nbsp; He decided to go for it!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Buy - The Good:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Just like any other middle class person, he decided to get the best deal (read that as &lt;b&gt;cheapest deal&lt;/b&gt;) for his Samsung Galaxy R.&amp;nbsp; He checked out the prices at a few local stores, but the best deal he could find was around Rs. 22K.&lt;br /&gt;&lt;br /&gt;The online price for Samsung Galaxy R was around Rs. 21K.&amp;nbsp; Deep Shah had ordered quite a few things (some of them expensive as well) online in foreign countries and they all were delivered just fine without any problems.&amp;nbsp; But in India, his online shopping experience was limited to books and some not so expensive stuff.&amp;nbsp; He really wanted to give Indian Online Shopping websites a go (actually he really wanted to save the 1000 bucks!).&lt;br /&gt;&lt;br /&gt;Hence, he checked out few online shopping websites, that were selling The Samsung Galaxy R.&amp;nbsp; I am not going to mention other online shopping websites names (since this post is not about them).&amp;nbsp; He decided to order the phone from a website called &lt;a href="http://www.letsbuy.com/"&gt;LetsBuy.com&lt;/a&gt; who were selling the Samsung Galaxy R at Rs. 20990.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why did he choose LetsBuy.com? &lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;They had a decent web site&lt;/li&gt;&lt;li&gt;They had a call center where one could call for enquirers between 8 am to 9 pm, 7 days a week&lt;/li&gt;&lt;li&gt;They were giving away free branded accessories worth Rs. 1200 absolutely free&lt;/li&gt;&lt;li&gt;He had found a discount coupon for LetsBuy.com which would give him an additional Rs. 1000 off!&lt;/li&gt;&lt;/ul&gt;Obviously, the last two reasons were the most important reasons to choose LetsBuy.com, the phone was costing Rs. 19990 after all the discount!&lt;br /&gt;&lt;br /&gt;OK so the choice of the website was made, now it was time to actually place an order.&amp;nbsp; The moment of choosing the payment mode had arrived.&amp;nbsp; There were mainly two options &lt;a href="http://en.wikipedia.org/wiki/Collect_on_delivery"&gt;&lt;b&gt;Cash on Delivery&lt;/b&gt;&lt;/a&gt; and &lt;b&gt;Pay by Credit Card&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The choice was simple, it was &lt;b&gt;Cash On Delivery&lt;/b&gt;, however, there was a catch, the discount coupon wont work for the Cash on Delivery payment mode.&amp;nbsp; Damn, if he choose Cash On Delivery the phone would cost 1000 bucks more.&amp;nbsp; You guys must have guessed his choice of Payment Mode by now, yes he choose Pay be Credit Card.&amp;nbsp; Unfortunately to save 1000 bucks he risked loosing Rs. 19990!&lt;br /&gt;&lt;br /&gt;The order was placed on LetsBuy.com on &lt;b&gt;30th December 2011 a Friday&lt;/b&gt; -&amp;nbsp;&amp;nbsp; Lets buy order number: &lt;b&gt;LSB-757065 (actual order number).&lt;/b&gt;&amp;nbsp; LetsBuy.com claimed that they will delivery the phone in 2-4 business days.&amp;nbsp; Deep Shah was expecting the delivery latest by Thursday.&amp;nbsp; Now it was time to wait anxiously for the delivery.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Confusion - The Bad:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;He checked the order status on LetsBuy.com and found that that, the order was going to be dispatched in two parts, one was the actual phone and other was the accessories.&amp;nbsp; Over the weekend he saw that his order was partly dispatched from LetsBuy.com.&amp;nbsp; The phone was on its way!&lt;br /&gt;&lt;br /&gt;By &lt;b&gt;Monday (02/01/2012)&lt;/b&gt;, LetsBuy.com had updated the shipment number and the courier company's name on the order.&amp;nbsp; The phone was being dispatched by a company called &lt;b&gt;&lt;a href="http://www.aramex.com/"&gt;Aramex&lt;/a&gt; (&lt;/b&gt;&lt;b&gt;name not changed)&lt;/b&gt;, the shipment number was &lt;b&gt;6273338610 (actual shipment number).&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Checking the current status on the shipment on &lt;a href="http://aramex.com/"&gt;Aramex.com&lt;/a&gt;, showed that shipment was on its way to Pune.&amp;nbsp; However, one thing caught his attention, the shipment was to be delivered in &lt;b&gt;Pune - 411013&lt;/b&gt;, but, when Deep Shah had placed the order the address mentioned as &lt;b&gt;Pune - 411016.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Hmm, how could the pin code be different.&amp;nbsp; He and His Friends smell something fishy.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;He decided to call up the courier company to find out whats wrong with the order.&amp;nbsp; The courier company Aramex was pretty prompt and accurate in their response.&amp;nbsp; He could talk to an executive within 30 seconds.&amp;nbsp; Deep Shah asked the executive to track the shipment 6273338610, to his surprise (&lt;b&gt;read that as "shock"&lt;/b&gt;), executive informed that, the Order was in the name of Mr. Amer (name changed) and order was to be delivered in Magarpatta, Pune - 411013.&lt;br /&gt;&lt;br /&gt;Clearly, something was messed up.&amp;nbsp; Initial guess about the problem with Deep Shah's order was:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Probably incorrect shipment number was updated against the order on LetsBuy.com&lt;/i&gt;&lt;b&gt;&lt;i&gt; &lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;He asked the courier company executive to find any shipment against his phone number (the number that he had given while booking the order).&amp;nbsp; But unfortunately no shipment was found against his phone number.&lt;br /&gt;&lt;br /&gt;Next, he decided to call LetsBuy.com call center to get some clarification.&amp;nbsp; This was the first time that Deep Shah would talk to LetsBuy.com call center executive.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;He had to wait a full 7 minutes before he could actually speak to someone at LetsBuy.com.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Deep Shah explained the situation with his order and asked for an explanation.&amp;nbsp; The executive calmly said that may be an incorrect shipment number was updated for his order (which was his guess anyways).&amp;nbsp; Executive requested Deep Shah to wait for 24-48 hrs and he will get this error resolved.&amp;nbsp; Executive registered a complaint &lt;b&gt;(no: cc120139286&lt;/b&gt; - &lt;b&gt;actual complaint number).&lt;/b&gt;&amp;nbsp; &lt;b&gt;This was on 02/01/2012&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Followup - The Ugly:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next day (&lt;b&gt;Tuesday 03/01/2012 - i.e. after 24 hrs&lt;/b&gt;), he logged on to LetsBuy.com to see if the shipment number was updated.&amp;nbsp; But, there was no change in the shipment number.&amp;nbsp; He decided to wait for one more day.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Next day (&lt;b&gt;Wednesday - 04/01/2012&lt;/b&gt;), ditto, no change in the order information.&lt;br /&gt;&lt;br /&gt;He decided to call LetsBuy.com again to find out whats going on for his complaint.&amp;nbsp; Again, &lt;span style="font-size: large;"&gt;it was a long wait for 9 minutes before which he could speak to someone at LetsBuy.com.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Deep Shah &lt;span style="font-size: large;"&gt;had to repeat the entire story again to this new person.&lt;/span&gt;&amp;nbsp; Executive informed that they were working on Deep Shah complaint and he has no update on the status of the complaint.&amp;nbsp; Executive requested Deep Shah to wait for another 24 hrs.&amp;nbsp; On this day, Deep Shah received the free accessories (not the phone).&lt;br /&gt;&lt;br /&gt;Next day (&lt;b&gt;Thursday - 05/01/2012&lt;/b&gt;), there was an unpleasant change on the order status, &lt;span style="font-size: large;"&gt;the Order status showing as &lt;i&gt;&lt;b&gt;Delivered &lt;/b&gt;&lt;/i&gt;on LetsBuy.com.&lt;/span&gt;&amp;nbsp; That freaked out Deep Shah a bit.&lt;br /&gt;&lt;br /&gt;He tracked the &lt;b&gt;shipment no: 6273338610 &lt;/b&gt;on &lt;a href="http://aramex.com/"&gt;Aramex.com&lt;/a&gt; website.&amp;nbsp; Turned out that it was actually delivered to Mr. Amer.&amp;nbsp; But no, Deep Shah had not received the phone yet.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HcQqjd69sVs/Txu2LzCd0YI/AAAAAAAAB1Q/8pqf9Rhxb3c/s1600/AramexShipmentDetails.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-HcQqjd69sVs/Txu2LzCd0YI/AAAAAAAAB1Q/8pqf9Rhxb3c/s320/AramexShipmentDetails.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Shipment Delivery to Mr. Amer&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;He called LetsBuy.com, &lt;span style="font-size: large;"&gt;after a long wait for 8 minutes, he could speak to someone at LetsBuy.com.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;He had to explain the entire story again (which was very frustrating).&amp;nbsp; &lt;/span&gt;You must have guessed the result of this conversation by now, executive asked Deep Shah to wait for another 24 hrs as they had no update on his complaint/order.&amp;nbsp; Executive even assured him that by the next day, in most likelihood Deep Shah should receive the product.&lt;br /&gt;&lt;br /&gt;Next day (&lt;b&gt;Friday - 06/01/2012&lt;/b&gt;) nothing happened.&amp;nbsp; &lt;span style="font-size: large;"&gt;Following up with LetsBuy.com was frustrating and pointless.&lt;/span&gt;&amp;nbsp; Every time, Deep Shah had to &lt;span style="font-size: large;"&gt;wait for long durations and then explain someone the same problem all over again and get the same response&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;LetsBuy.com executives would not give their direct contact numbers or their email address.&amp;nbsp; This means&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Long wait before one could speak to a LetsBuy.com executive&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Explaining the situation all over again (to different executives) and eventually get the same response - &lt;i&gt;Please wait for 24 hrs.&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Wait for 24hrs and do what?&amp;nbsp; Expect some miracle?&lt;br /&gt;&lt;br /&gt;On &lt;b&gt;Sunday - 08/01/2012&lt;/b&gt;, i.e. Full 10 days after placing the order, Deep Shah still didn't have any trace of his phone.&lt;br /&gt;&lt;br /&gt;He had received the free accessories, as one of my friend keeps saying,&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Its like giving an hungry dog a rubber bone!&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Deep Shah called up LetsBuy.com again and this time demanded to speak to some manager.&amp;nbsp; He got to speak with &lt;b&gt;Mr. Laxman Patil (&lt;/b&gt;&lt;b&gt;name changed) &lt;/b&gt;a supervisor at LetsBuy.com.&amp;nbsp; He seemed like a nice guy, heard Deep Shah out, understood the situation and promised to look into the matter himself.&amp;nbsp; By this time all Deep Shah wanted was a regular feedback on his order.&lt;br /&gt;&lt;br /&gt;Being a software engineer, he understands that all systems are pron to programming/human bugs/errors.&amp;nbsp; &lt;span style="font-size: large;"&gt;But customers should be given regular feedback on what action was taken to rectify the mistake.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;Even after contacting LetsBuy.com, like 10 times, LetsBuy.com didn't have enough &lt;span class="st"&gt;courtesy &lt;/span&gt;to call Deep Shah and update him with the complaint status.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;BTW the order status on LetsBuy.com was &lt;b&gt;&lt;i&gt;Delivered&lt;/i&gt;&lt;/b&gt;, they didn't bother to change it, even after they agreed that it not yet delivered.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-iScomvbP5Eo/Txu8_5vrbvI/AAAAAAAAB1Y/cBY4Wn261vU/s1600/OrderDetailsWithTrackingNo.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://1.bp.blogspot.com/-iScomvbP5Eo/Txu8_5vrbvI/AAAAAAAAB1Y/cBY4Wn261vU/s320/OrderDetailsWithTrackingNo.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Order Status is Delivered Even though no phone was delivered&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Next day (&lt;b&gt;Monday - 09/01/2012&lt;/b&gt;), no news from LetsBuy.com, no news from Mr. Laxman Patil.&amp;nbsp; During this period Deep Shah wrote numerous mails on &lt;a href="mailto:customercare@letsbuy.com"&gt;customercare@letsbuy.com&lt;/a&gt; but LetsBuy.com didn't respond to even one.&lt;br /&gt;&lt;br /&gt;During these days, Deep Shah and His Friends tried our different (random) tracking numbers, which were around the tracking number that was given to Deep Shah.&amp;nbsp; They found quite a few tracking numbers that had funny shipment history.&amp;nbsp; For e.g. &lt;span style="font-size: large;"&gt;Tracking Number &lt;b&gt;6273338621 &lt;/b&gt;was delivered twice once in Panji, India and once in Bombay India.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-kMjiiwj5yVY/Txu92p533AI/AAAAAAAAB1g/ac0jbma67bU/s1600/AramexShipmentDeliveredTwice.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://4.bp.blogspot.com/-kMjiiwj5yVY/Txu92p533AI/AAAAAAAAB1g/ac0jbma67bU/s320/AramexShipmentDeliveredTwice.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Shipment Delivered Twice&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;What did this signify?&lt;/b&gt;&amp;nbsp; &lt;b&gt;Does this mean Aramex was reusing shipment numbers?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We called up Aramex to ask whether they were reusing shipment number?&amp;nbsp; Of course they said shipment numbers are unique.&amp;nbsp; They cannot be duplicate.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Deep Shah and his friends could find multiple instances where there were two deliveries made on one shipment number.&lt;/span&gt;&amp;nbsp; If you notice the tracking history of Deep Shah's shipment number you can see, even that one has two shipments moving.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;One shipment arrived in Pune on 31/12/2011 at about 1845 hrs and went on hold.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Other shipment started from Banglore on 02/01/2012 and was delivered on 05/01/2012 to Mr. Amer&lt;/li&gt;&lt;/ul&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-nCH6mYs0MkU/Txu_M1dtcRI/AAAAAAAAB1o/9ZblvP9dvQs/s1600/AramexShipmentDetailsWithHighlight.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://3.bp.blogspot.com/-nCH6mYs0MkU/Txu_M1dtcRI/AAAAAAAAB1o/9ZblvP9dvQs/s320/AramexShipmentDetailsWithHighlight.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Notice two shipments moving on one shipment number&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;In this shipment, notice that, &lt;span style="font-size: large;"&gt;there are two products involved but only one delivery was made.&lt;/span&gt;&amp;nbsp; While in all other shipments we noticed that two products were moving on the same shipment number but two deliveries were also made.&lt;br /&gt;&lt;br /&gt;By this time, Deep Shah and His Friends were sure that his shipment was lying in Aramex Pune office but was never delivered.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What was so special about this shipment?&amp;nbsp; Why others got delivered but this one was not delivered?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The interesting thing to notice about all other shipments with duplicate shipment numbers was that, &lt;span style="font-size: large;"&gt;they were to be delivered in different cities.&lt;/span&gt;&amp;nbsp; for e.g. in the image shown above, one product was to be delivered in Panji Goa and other one in Bombay.&amp;nbsp; But, &lt;span style="font-size: large;"&gt;in Deep Shah's case both the shipments were to be delivered in Pune.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This was the turning point.&amp;nbsp; After some motivation from Deep Shah's Friends, they decided to visit Aramex Pune office and figure out if their theory was correct.&lt;br /&gt;&lt;br /&gt;On &lt;b&gt;Wednesday - 11/01/2012&lt;/b&gt;, There was still no updates from LetsBuy.com.&amp;nbsp; &lt;span style="font-size: large;"&gt;Even after giving numerous calls to LetsBuy.com no one would every get back to give any update.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Deep Shah would call LetsBuy.com and insists to speak to Mr. Laxman Patil, &lt;span style="font-size: large;"&gt;he would have to wait for full 15-20 minutes, eventually Mr. Laxman Patil would inform that, he has escalated the case to higher authorities and action will be taken.&lt;/span&gt;&amp;nbsp; It was too late and too little and very very frustrating.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Deep Shah and His Friends visited the Aramex office in the evening and explained them the situation.&amp;nbsp; Initially they had tough time explaining them that two shipments were moving on one shipment number.&amp;nbsp; If they looked up the shipment number in their system it would always bring up details of Mr. Amer's shipment.&amp;nbsp; As there cannot be two shipments with same shipment number.&amp;nbsp; Entire logistics business is based on this assumption.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Once a logistics expert (who had around 15 years of experience in Logistics) told me that,&lt;br /&gt;&lt;br /&gt;&lt;i&gt;We cannot have duplicate shipment number being generated in production, this would have catastrophic effects.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now, I truly understand what he meant by that!&lt;br /&gt;&lt;br /&gt;Anyways, In Aramex Pune office one guy (A very good guy) did agree that, two shipments were moving on one shipment number.&amp;nbsp; He and his team manually checked all the shipments that were present in his warehouse.&lt;br /&gt;&lt;br /&gt;Guess what, &lt;span style="font-size: large;"&gt;they did find a box that was shipped by LetsBuy.com and was with the same shipment number i.e. 6273338610.&amp;nbsp; One very smart person at Aremex Pune office had kept this shipment aside since he saw two similar shipments with same shipment number had landed in his warehouse.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It seemed like the mystery was getting resolved, it was clear that the box had the phone for Deep Shah, but, Aramex would not deliver it to Deep Shah since, in their system, this shipment belonged to Mr. Amer.&amp;nbsp; Funny part was, the shipment was already delivered to Mr. Amer.&lt;br /&gt;&lt;br /&gt;Aramex guys requested Deep Shah to wait for one last day so that they could get a confirmation from LetsBuy.com about the shipment and delivery it to him.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Next day, &lt;b&gt;Thursday - 12/01/2012&lt;/b&gt; - Deep Shah called up LetsBuy.com to inform them about what he had found out, he had also written an email to inform about this new development.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Again as usual they asked Deep Shah to wait for 24-48 hrs.&amp;nbsp; LetsBuy.com call center is like an IVR system which is programmed to listen to what customer has to say and always respond by saying we will get back to you in 24-48 hrs and never bother call the customer back.&lt;/span&gt;&amp;nbsp; Worst part is they will ask &lt;b&gt;&lt;i&gt;whether they can help with anything else?&lt;/i&gt;&lt;/b&gt;, what a joke!&lt;br /&gt;&lt;br /&gt;In the evening at about 1730 hrs, the smart guy from Aramex Pune office called up Deep Shah and asked him to come and collect his phone.&amp;nbsp; Finally a sign of relief, Deep Shah did get his phone after 14 days of placing his order!&amp;nbsp; Aramex Pune office folks actually managed to resolve the issue within 24 hrs as promised by them.&amp;nbsp; They really were the people who saved the day in the end.&lt;br /&gt;&lt;br /&gt;Out of curiosity, Deep Shah the smart guy at Aramex, Why duplicate shipment numbers are getting generated?&lt;br /&gt;&lt;br /&gt;Turned out, a range of shipment numbers have been allotted to LetsBuy.com and they are not supposed to repeat them.&amp;nbsp; But, &lt;span style="font-size: large;"&gt;because of a bug in LetsBuy.com's system, same shipment numbers were getting used for two different shipments.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, I can understand that mistakes do occur when you are running a business, &lt;span style="font-size: large;"&gt;but the quality of service is judged by how well you handle those erroneous cases.&amp;nbsp; Letsbuy.com failed miserably in handling this case.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;On a scale of 1 to 5, I would rate my shopping experience with LetsBuy.com at -5.&lt;/span&gt;&amp;nbsp; I hope not every customer is treated like this at LetsBuy.com else its just a matter of time before which they perish!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What Should have been done:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Customers should not suffer because of some goof up in the system&lt;/li&gt;&lt;li&gt;Customers should always be keep informed about the status of their complaint&lt;/li&gt;&lt;li&gt;Customers should not be waiting for 7-15 min before which they can speak to a customer care executive&lt;/li&gt;&lt;li&gt;Customers should not be speaking to different executives every time they call.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;I am sure LetsBuy.com knows much better how to run an online shopping website.&amp;nbsp; However, things that I have pointed out are just common sense items which should not have been ignored.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;End Result:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Deep Shah and His Friends promised themselves never to buy any thing from LetsBuy.com and hopefully people who read this post would do the same.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Moral of the story:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Never judge a website by the amount of discount they are offering on a product&lt;/li&gt;&lt;li&gt;Choose the one that has a better reputation and better and responsive customer care&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Always always always opt for Cash On Delivery payment method&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt; &lt;span style="font-size: small;"&gt;&lt;b&gt;Standard Disclaimer:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Every incident mentioned in this story is &lt;b&gt;real&lt;/b&gt;.&amp;nbsp; All order numbers and shipment number are real order/shipment numbers.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-4039010525964030024?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/4039010525964030024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2012/01/letsbuycom-perfect-example-of-how-not.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4039010525964030024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4039010525964030024'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2012/01/letsbuycom-perfect-example-of-how-not.html' title='LetsBuy.com A Perfect Example of How Not to Run an Online Shopping Website'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-HcQqjd69sVs/Txu2LzCd0YI/AAAAAAAAB1Q/8pqf9Rhxb3c/s72-c/AramexShipmentDetails.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-6936160395783109467</id><published>2011-12-31T01:36:00.001+05:30</published><updated>2011-12-31T01:36:57.311+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='InvalidCastException'/><category scheme='http://www.blogger.com/atom/ns#' term='composite primary key'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='property-ref'/><category scheme='http://www.blogger.com/atom/ns#' term='one-to-many'/><title type='text'>NHibernate throws InvalidCastException in DEBUG mode for entities with composite keys</title><content type='html'>Recently we faced a very weird issue with &lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt;.&amp;nbsp; The issue was, on one developer's machine, when we ran an Integration test to fetch an entity (using its primary key), &lt;span style="font-size: large;"&gt;NHibernate threw an &lt;i&gt;InvalidCastException &lt;/i&gt;exception. &lt;/span&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[NHibernate.Exceptions.GenericADOException : could not load an entity: [x.y.z.EmpDept#component[UserID,DeptID]{'UserID'='123', 'DeptID'='1121212'} [SQL: select EmpDept0_.UserID, user1.DeptID, EmpDept0_.Email from [EmpDept] EmpDept0_ WHERE EmpDept0_.UserID=? and EmpDept0_.DeptID=?]  ----&gt; System.InvalidCastException : System.Stringat NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister)at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)at NHibernate.Impl.SessionImpl.Get(String entityName, Object id)at NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id)at NHibernate.Impl.SessionImpl.Get(Object id)--InvalidCastExceptionat NHibernate.Type.ComponentType.ToLoggableString(Object value, ISessionFactoryImplementor factory)at NHibernate.Impl.MessageHelper.InfoString(ICollectionPersister persister, Object id, ISessionFactoryImplementor factory)at NHibernate.Engine.Loading.LoadContexts.LocateLoadingCollection(ICollectionPersister persister, Object ownerKey)at NHibernate.Type.CollectionType.GetCollection(Object key, ISessionImplementor session, Object owner)at NHibernate.Type.CollectionType.ResolveIdentifier(Object key, ISessionImplementor session, Object owner)at NHibernate.Engine.TwoPhaseLoad.InitializeEntity(Object entity, Boolean readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent)at NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session, Boolean readOnly)at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) ]]&gt;&lt;/script&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;The &lt;span style="font-size: large;"&gt;issue was *not* reproducible on any other developer's machine.&lt;/span&gt;&amp;nbsp; This got me thinking, there must be some issue with the mappings which is causing NHibernate to throw the exception.&amp;nbsp; The developer must have made some local changes to the mapping files, that is causing the exception.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Investigation:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I tried various things to figure out what was causing the problem.&amp;nbsp; Here is the list of things that I tried.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check mapping files for modifications:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I checked and rechecked the mapping files for any local modifications, but, No, there was no local modification.&amp;nbsp; I even checked-out all the mapping files just to be sure that there was no modification.&amp;nbsp; But still no luck, the issue was reproducible on her machine and not on any other machine.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tried to reproduce the issue on my machine by connecting to other developers Database:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;After the first failed attempt, next thought that crossed my mind was, may be, there was something wrong with entity data which is causing the exception.&amp;nbsp; I decided to run the same test on my machine by connecting to other developers database.&lt;br /&gt;&lt;br /&gt;Surprisingly, I was still not able to reproduce the issue.&amp;nbsp; This was totally weird.&amp;nbsp; I was 99% positive that, issue would get reproduced once I connect to the order developers database.&lt;br /&gt;&lt;br /&gt;I was running out of options.&amp;nbsp; How do proceed further?&amp;nbsp; What should be the next step?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Stick to basics - Debug with Elimination:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I was back to the drawing board.&amp;nbsp; Decided to use Elimination to narrow down the issue. The question that was bothering me was, Whats so special about the entity we are trying to load?&lt;br /&gt;&lt;br /&gt;The entity we were trying to load was called EmpDept, it represents the Employee Department information (actual names of the entities have been changed).&amp;nbsp; So what was so special about this table?&lt;br /&gt;&lt;br /&gt;This table was a legacy table, it did not have a primitive primary key, &lt;span style="font-size: large;"&gt;it had a composite key made of UserID and DeptID.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So what?&amp;nbsp; A lot of legacy databases have composite keys, &lt;span style="font-size: large;"&gt;NHibernate works well when it comes to mapping the composite keys, in fact, NHibernate has no problems loading the same entity on my machine!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I decided to, removed all other mapped properties and just kept the mappings for the composite key and try to fetch the entity.&amp;nbsp; This time, &lt;span style="font-size: large;"&gt;it did fetch the entity without any problems on the other developers machine!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We were starting to get somewhere now!&lt;br /&gt;&lt;br /&gt;I started adding back the mappings to find out which one was causing the issue.&amp;nbsp; Finally, we did find the minimal possible mapping that would reproduce the issue.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Cause:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We deduced that, the issue occurs when the following conditions are satisfied&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Entity is mapped with composite primary key&lt;/li&gt;&lt;li&gt; Entity has a one-to-many relationship with other entity&amp;nbsp;&lt;/li&gt;&lt;li&gt;The one-to-many relationship is not based on the composite primary key, instead its with &lt;b&gt;property-ref&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;And the data type of &lt;b&gt;property-ref &lt;/b&gt;is different from the id property&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;Wow!&amp;nbsp; I know, those are too many conditions to be true at one time!&lt;br /&gt;&lt;br /&gt;Let's look at the minimal mapping file that reproduced the issue&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                    default-access="property" auto-import="true"                    default-cascade="none" default-lazy="true"                   namespace="NHibernate.Test.CompositeId"               assembly="NHibernate.Test"&gt;  &lt;class xmlns="urn:nhibernate-mapping-2.2" mutable="false"          name="NHibernate.Test.CompositeId.EmpDept, NHibernate.Test"          table="EmpDepts"&gt;    &lt;composite-id name="EmpDeptIdentifier"           mapped="true" unsaved-value="undefined"&gt;      &lt;key-property name="UserID" type="System.Int64" /&gt;      &lt;key-property name="DeptID" type="System.Int64" /&gt;    &lt;/composite-id&gt;    &lt;set cascade="all-delete-orphan"          inverse="true" lazy="true" name="Tasks" mutable="true"&gt;      &lt;key property-ref="Email" /&gt;      &lt;one-to-many class="NHibernate.Test.CompositeId.Task, NHibernate.Test" /&gt;    &lt;/set&gt;    &lt;property name="Email" type="string" /&gt;  &lt;/class&gt;&lt;/hibernate-mapping&gt;&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"                    default-access="property" auto-import="true"                    default-cascade="none" default-lazy="true"                          namespace="NHibernate.Test.CompositeId"              assembly="NHibernate.Test"&gt;  &lt;class xmlns="urn:nhibernate-mapping-2.2"          mutable="true"          name="NHibernate.Test.CompositeId.Task, NHibernate.Test"          table="addljob"&gt;    &lt;id name="TaskID" type="System.Int64"&gt;      &lt;generator class="identity" /&gt;    &lt;/id&gt;    &lt;property name="Email" type="System.String"&gt;    &lt;/property&gt;  &lt;/class&gt;&lt;/hibernate-mapping&gt;]]&gt;&lt;/script&gt;What do we have here?&amp;nbsp; We have a very simple mapping between two entities.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Entity &lt;i&gt;&lt;b&gt;EmpDept &lt;/b&gt;&lt;/i&gt;is mapped to a table called &lt;i&gt;&lt;b&gt;EmpDepts&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;EmpDept &lt;/b&gt;&lt;/i&gt;uses a composite primary key to class &lt;i&gt;&lt;b&gt;EmpDeptIdentifier&lt;/b&gt;&lt;/i&gt; &lt;/li&gt;&lt;li&gt;The composite primary key consists of &lt;i&gt;&lt;b&gt;UserID &lt;/b&gt;&lt;/i&gt;and &lt;i&gt;&lt;b&gt;DeptID&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;EmpDept&lt;/b&gt;&lt;/i&gt; entity as another property called &lt;i&gt;&lt;b&gt;Email&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;There is a one-to-many relationship between &lt;i&gt;&lt;b&gt;EmpDept &lt;/b&gt;&lt;/i&gt;and &lt;i&gt;&lt;b&gt;Task &lt;/b&gt;&lt;/i&gt;entity i.e. &lt;i&gt;&lt;b&gt;One EmpDept &lt;/b&gt;&lt;/i&gt;can have &lt;i&gt;&lt;b&gt;Many Tasks&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Note&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;that the relationship is not based on the composite primary key&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;The relationship is based on a non identifier property called &lt;i&gt;&lt;b&gt;Email&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;The&lt;/span&gt; data type of the &lt;i&gt;&lt;b&gt;Email &lt;/b&gt;&lt;/i&gt;property is &lt;i&gt;&lt;b&gt;string &lt;/b&gt;&lt;/i&gt;while the data type of the composite primary key is &lt;i&gt;&lt;b&gt;EmpDeptIdentifier&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;By now, it must be clear that all of the required conditions for NHibernate to throw an exception have been satisfied, because of this NHibernate throws the &lt;i&gt;&lt;b&gt;InvalidCastException.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;So far we had figured out, what conditions were required for NHibernate to throw the exception.&amp;nbsp; However the real mystery was, &lt;span style="font-size: large;"&gt;Why was the exception occurring only on one developers machine?&amp;nbsp; Why not on other developers machines?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Enlightenment:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Our curiosity levels were at all time high!&amp;nbsp; We decided to debug the NHibernate code to figure out why was exact same code working perfectly fine on one machine and failing on other.&lt;br /&gt;&lt;br /&gt;After some intense NHibernate code debugging we found the NHibernate code that was throwing the exception.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public override string ToLoggableString(object value,                          ISessionFactoryImplementor factory){ if (value == null) {  return "null"; } IDictionary&lt;string, string&gt; result =                            new Dictionary&lt;string, string&gt;(); EntityMode? entityMode =                            tuplizerMapping.GuessEntityMode(value); if (!entityMode.HasValue) {  throw new InvalidCastException(value.GetType().FullName); } object[] values = GetPropertyValues(value, entityMode.Value); for (int i = 0; i &lt; propertyTypes.Length; i++) {  result[propertyNames[i]] =                        propertyTypes[i].ToLoggableString(values[i], factory); } return StringHelper.Unqualify(Name)                        + CollectionPrinter.ToString(result);}]]&gt;&lt;/script&gt;Notice the line that throws the &lt;i&gt;&lt;b&gt;InvalidCastException &lt;/b&gt;&lt;/i&gt;in the above code?&amp;nbsp; This is where the exception occurs.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The above method is called to build a string that will be used for logging.&amp;nbsp; We traced back the call to this method, it was getting called from the &lt;i&gt;&lt;b&gt;MessageHelper.InfoString&lt;/b&gt;&lt;/i&gt; method, which in-turn was getting called from the &lt;i&gt;&lt;b&gt;LoadContexts.LocateLoadingCollection&lt;/b&gt;&lt;/i&gt; method.&lt;br /&gt;&lt;br /&gt;We now knew the place from where the exception was thrown, but we still didn't know why it was thrown only on one machine.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Looking through the NHibernate code we realized that, &lt;span style="font-size: large;"&gt;the method &lt;i&gt;&lt;b&gt;MessageHelper.InfoString &lt;/b&gt;&lt;/i&gt;is only called if NHibernate is running with &lt;i&gt;&lt;b&gt;DEBUG &lt;/b&gt;&lt;/i&gt;log level.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;That ladies and gentlemen, was the "Aha Moment!" for us.&amp;nbsp; This was the missing piece of the puzzle. &amp;nbsp; &lt;/span&gt;The developer on whose machine the test was failing was running NHibernate at log level DEBUG, while I was running the test at log level INFO.&amp;nbsp; Because of this the method &lt;span style="font-size: large;"&gt;&lt;i&gt;&lt;b&gt;MessageHelper.InfoString &lt;/b&gt;&lt;/i&gt;&lt;span style="font-size: small;"&gt;was never invoked on my machine and thus no exception!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;We Googled a little and found that there is an &lt;a href="https://nhibernate.jira.com/browse/NH-2779"&gt;official bug&lt;/a&gt; reported for this scenario.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Eventually it turned out that, what we initially though as a big issue was really a non issue, since NHibernate will not be configured in DEBUG mode 99% of the time (because it logs hell lot of information).&amp;nbsp; The issue we were facing is very unlikely in real systems.&amp;nbsp; Although it was not such a big issue after all, this experience taught us quite a few things about NHibernate!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-6936160395783109467?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/6936160395783109467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/12/nhibernate-throws-invalidcastexception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6936160395783109467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6936160395783109467'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/12/nhibernate-throws-invalidcastexception.html' title='NHibernate throws InvalidCastException in DEBUG mode for entities with composite keys'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3224451474014268175</id><published>2011-11-13T12:55:00.001+05:30</published><updated>2011-11-13T13:29:58.499+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='asmx'/><category scheme='http://www.blogger.com/atom/ns#' term='web service'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with asmx webservices'/><title type='text'>Integrating Spring.NET with ASMX WebServices</title><content type='html'>In one of the previous post, we saw how easily we can &lt;a href="http://www.gitshah.com/2011/10/enabling-dependency-injection-in-web.html"&gt;Enable Dependency Injection for Web Forms Web Pages and User Controls&lt;/a&gt;.&amp;nbsp; In this post we will cover the last topic in the Dependency Injection series i.e. Enabling Dependency injection in ASMX WebServices using &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Its not at all difficult to Enable Dependency Injection in ASMX WebServices.&amp;nbsp; Lets look at the steps we will need to it&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configure the &lt;b&gt;&lt;i&gt;Spring Context&lt;/i&gt;&lt;/b&gt; in &lt;i&gt;&lt;b&gt;web.config&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the &lt;b&gt;&lt;i&gt;Spring WebSupportModule Module&lt;/i&gt;&lt;/b&gt; to the list of &lt;i&gt;&lt;b&gt;httpModules&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Configure the &lt;i&gt;&lt;b&gt;WebServiceHandlerFactory &lt;/b&gt;&lt;/i&gt;to intercept any path that matches the pattern &lt;i&gt;&lt;b&gt;*.asmx&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Configure the &lt;i&gt;&lt;b&gt;WebService &lt;/b&gt;&lt;/i&gt;class in spring config file with its dependencies&lt;/li&gt;&lt;/ul&gt;Let's look at each step in a little more detail.&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Step - 1 - Configure the spring context in web.config&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First we need to add spring config section handler in the &lt;i&gt;&lt;b&gt;configSections.&lt;/b&gt;&amp;nbsp;&lt;/i&gt; The updated &lt;i&gt;&lt;b&gt;web.config &lt;/b&gt;&lt;/i&gt;looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;configsections&gt;    &lt;sectiongroup name="spring"&gt;      &lt;section name="context"                type="Spring.Context.Support.WebContextHandler, Spring.Web"/&gt;    &lt;/sectionGroup&gt;  &lt;/configSections&gt;]]&gt;&lt;/script&gt;Next we need to add the &lt;i&gt;&lt;b&gt;spring&lt;/b&gt;&lt;/i&gt; config section in &lt;i&gt;&lt;b&gt;web.config&lt;/b&gt;&lt;/i&gt;.  This section will inform Spring.NET as to where should it look for its configuration file.  Add the following section to &lt;i&gt;&lt;b&gt;web.config&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;spring&gt;    &lt;context&gt;      &lt;resource uri="~/Config/webservice.xml" /&gt;    &lt;/context&gt;  &lt;/spring&gt;]]&gt;&lt;/script&gt;Nothing special about the above piece of configuration.  We are informing Spring.NET that its configuration file is located in &lt;i&gt;&lt;b&gt;~/Config/&lt;/b&gt;&lt;/i&gt; directory and its called &lt;i&gt;&lt;b&gt;webservice.xml&lt;/b&gt;&lt;b&gt;.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Step - 2 - We need to add the Spring WebSupportModule module to the list of httpModules&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In this step, we will need to add the &lt;i&gt;&lt;b&gt;WebSupportModule &lt;/b&gt;&lt;/i&gt;to the list of &lt;i&gt;&lt;b&gt;httpModules in the web.config.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This is how the updated web.config looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;httpmodules&gt;  &lt;add name="SpringModule"        type="Spring.Context.Support.WebSupportModule, Spring.Web"/&gt;&lt;/httpModules&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Step - 3 - Configure the WebServiceHandlerFactory to intercept any path that matches the pattern *.asmx&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Again, all we need to do here is add an &lt;i&gt;&lt;b&gt;Handler &lt;/b&gt;&lt;/i&gt;in the &lt;i&gt;&lt;b&gt;httpHandlers section in web.config.&lt;/b&gt;&lt;/i&gt;  Update &lt;i&gt;&lt;b&gt;web.config &lt;/b&gt;&lt;/i&gt;looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;httphandlers&gt;  &lt;add verb="*"        path="*.asmx"        type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/&gt;&lt;/httpHandlers&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Step - 4 - Configure the WebService class in spring config file with its dependencies&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We are almost there.  All that is left now is to configure the &lt;i&gt;&lt;b&gt;WebService &lt;/b&gt;&lt;b&gt;class &lt;/b&gt;&lt;/i&gt;in the &lt;i&gt;&lt;b&gt;Spring.NET &lt;/b&gt;&lt;/i&gt;configuration file &lt;i&gt;&lt;b&gt;webservice.xml&lt;/b&gt;&lt;b&gt;.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;Let's say that we want to develop a &lt;i&gt;&lt;b&gt;HelloWorld webservice, &lt;/b&gt;&lt;/i&gt;that has one method called &lt;i&gt;&lt;b&gt;GreetUser.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This method takes in the user name as argument.&amp;nbsp; We will inject the greeting to be used using Spring.NET.&lt;br /&gt;&lt;br /&gt;The code of the &lt;i&gt;&lt;b&gt;HelloWorld webservice &lt;/b&gt;&lt;/i&gt;looks like&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public interface IHelloWorldService    {        string GreetUser(string userName);    }    public class HelloWorldServiceImpl : IHelloWorldService    {        public string Greeting { set; get; }        public string GreetUser(string userName)        {            return Greeting + userName;        }    }]]&gt;&lt;/script&gt;Nothing to explain here, all we are doing is prepending the &lt;i&gt;&lt;b&gt;Greeting Property &lt;/b&gt;&lt;/i&gt;to the &lt;i&gt;&lt;b&gt;userName &lt;/b&gt;&lt;/i&gt;passed and returning the value as the result.&lt;br /&gt;&lt;br /&gt;Notice that this &lt;i&gt;&lt;b&gt;HelloWorldService class is a POCO &lt;/b&gt;&lt;/i&gt;and there is nothing web service specific to it.&lt;br /&gt;&lt;br /&gt;The spring configuration that will inject the &lt;i&gt;&lt;b&gt;Greeting &lt;/b&gt;&lt;/i&gt;into the &lt;i&gt;&lt;b&gt;HelloWorldService &lt;/b&gt;&lt;/i&gt;looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;?xml version="1.0" encoding="utf-8" ?&gt;&lt;objects xmlns="http://www.springframework.net"&gt;  &lt;object       id="HelloWorldServiceImpl"      type="aspnetwebFormsWithMvc3App.HelloWorldServiceImpl, aspnetwebFormsWithMvc3App"&gt;    &lt;property name="Greeting" value="Welcome "/&gt;  &lt;/object&gt;  &lt;object       id="HelloWorldService"       type="Spring.Web.Services.WebServiceExporter, Spring.Web"&gt;    &lt;property name="TargetName"               value="HelloWorldServiceImpl"/&gt;    &lt;property name="Namespace"               value="http://myCompany/services"/&gt;    &lt;property name="Description"               value="My First web service"/&gt;  &lt;/object&gt;&lt;/objects&gt;]]&gt; &lt;/script&gt;Notice that, we are configuring the implementation of WebService with the ID &lt;i&gt;&lt;b&gt;HelloWorldServiceImpl&lt;/b&gt;&lt;/i&gt;&lt;b&gt;.&lt;/b&gt;&amp;nbsp; However, the actual WebService is exposed via Spring.NET.&amp;nbsp; The &lt;i&gt;&lt;b&gt;Spring.Web.Services.WebServiceExporter&lt;/b&gt;&lt;/i&gt; acts as a proxy over the actual WebService implementation.&lt;br /&gt;&lt;br /&gt;All set!&lt;br /&gt;&lt;br /&gt;Lets run the server and browser the URL which would look like &lt;i&gt;&lt;b&gt;http://localhost:&amp;lt;your-port-number&amp;gt;/HelloWorldService.asmx?op=GreetUser&lt;/b&gt;&lt;b&gt;.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This should open up a page which looks like this &lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-erYyFvMAll4/Tr93XszH42I/AAAAAAAABh0/wpnO9Zi6RwY/s1600/webserviceHelloServiceWithUserNameInput.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://4.bp.blogspot.com/-erYyFvMAll4/Tr93XszH42I/AAAAAAAABh0/wpnO9Zi6RwY/s320/webserviceHelloServiceWithUserNameInput.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Page which will let us invoke the HelloWroldService.GreeUser WebService&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This is the page from which we could invoke the &lt;i&gt;&lt;b&gt;HelloWorldService.GreetUser WebService.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let's type in &lt;i&gt;&lt;b&gt;Git Shah&lt;/b&gt;&lt;/i&gt; in the user name field and click Invoke.&amp;nbsp; Here is what we get&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;string&gt;Good Morning Git Shah&lt;/string&gt;]]&gt;&lt;/script&gt;As you can see, the greeting message &lt;i&gt;&lt;b&gt;Good Morning&lt;/b&gt;&lt;/i&gt; was injected in the &lt;i&gt;&lt;b&gt;HelloWorldServiceImpl class &lt;/b&gt;&lt;/i&gt;via Spring.NET.&lt;br /&gt;&lt;br /&gt;That's all folks, we have successfully Integrated &lt;i&gt;&lt;b&gt;Spring.NET&lt;/b&gt;&lt;/i&gt; with &lt;i&gt;&lt;b&gt;ASMX WebServices&lt;/b&gt;&lt;b&gt;!&lt;/b&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3224451474014268175?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3224451474014268175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/11/integrating-springnet-with-asmx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3224451474014268175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3224451474014268175'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/11/integrating-springnet-with-asmx.html' title='Integrating Spring.NET with ASMX WebServices'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-erYyFvMAll4/Tr93XszH42I/AAAAAAAABh0/wpnO9Zi6RwY/s72-c/webserviceHelloServiceWithUserNameInput.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-6349590123332017229</id><published>2011-11-06T13:03:00.002+05:30</published><updated>2011-11-06T13:05:47.876+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='criteria api'/><category scheme='http://www.blogger.com/atom/ns#' term='operator precedence'/><category scheme='http://www.blogger.com/atom/ns#' term='fixing'/><category scheme='http://www.blogger.com/atom/ns#' term='QueryOver'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate LINQ provider'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Making operator precidence more explicit with NHibernate Linq Provider</title><content type='html'>Recently, while writing one of the &lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt; queries, using the NHibernate LINQ provider we faced a very interesting problem.&lt;br /&gt;&lt;br /&gt;The issue was the &lt;span style="font-size: large;"&gt;NHibernate LINQ provider was not adding appropriate parenthesis to make the operator precedence more explicit.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The query was simple enough, we wanted to get a list of records based on certain condition.  Let's say, for the sake of this post, consider that there is an &lt;i&gt;&lt;b&gt;employees table with ID, Name and Salary columns.&lt;/b&gt;&lt;/i&gt;  The DDL to create the &lt;i&gt;&lt;b&gt;employees tables &lt;/b&gt;&lt;/i&gt;on SQLServer looks like&lt;br /&gt;&lt;script class="brush: sql" type="syntaxhighlighter"&gt;&lt;![CDATA[create table employees (id int identity(1, 1) not null primary key,                                    name varchar(10),                                    salary float);]]&gt;&lt;/script&gt;NHibernate class against which this table is mapped is called Employee.  The Employee class and its mapping file looks like&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class Employee    {        public virtual long Id { get; private set; }        public virtual string Name { get; set; }        public virtual double Salary { get; set; }    }    public class EmployeeMap : ClassMap&lt;employee&gt;    {        public EmployeeMap()        {            Table("employees");            Id(x =&gt; x.Id);            Map(x =&gt; x.Name);            Map(x =&gt; x.Salary);        }    }]]&gt;&lt;/script&gt;As you can see there is nothing fancy about the table or the mapping.&lt;br /&gt;&lt;br /&gt;Let's talk a bit about the query we want to fire against the &lt;i&gt;&lt;b&gt;employees table&lt;/b&gt;&lt;/i&gt;.&amp;nbsp; We want to get list of &lt;i&gt;&lt;b&gt;employees whose name equals "Git" OR whose salary is between 1000 and 10000&lt;/b&gt;&lt;/i&gt;&lt;b&gt;.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The SQL that would do the job for us would look like: &lt;br /&gt;&lt;br /&gt;&lt;script class="brush: sql" type="syntaxhighlighter"&gt;&lt;![CDATA[select * from employees e where e.name='Git'                    or (e.salary &gt;= 1000 and e.salary &lt;= 10000);]]&gt;&lt;/script&gt;Again nothing remotely fancy about the SQL.&lt;br /&gt;&lt;br /&gt;Let's try and write the same query using, NHibernate LINQ provider and lets look at the generated SQL.&amp;nbsp; The NHibernate LINQ query to get similar results would look like:&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[var employees = session    .Query&lt;employee&gt;()    .Where(x =&gt; x.Name == "Git"          || (x.Salary &gt;= 1000 &amp;&amp; x.Salary &lt;= 10000))    .ToList();]]&gt;&lt;/script&gt;The &lt;i&gt;&lt;b&gt;where condition &lt;/b&gt;&lt;/i&gt;is the exact replica of the &lt;i&gt;&lt;b&gt;SQL where condition &lt;/b&gt;&lt;/i&gt;that we had seen earlier.&amp;nbsp; Only difference this time around is, we are using the LINQ syntax.&lt;br /&gt;&lt;br /&gt;So far so good, the problem starts when we look at the SQL that is generated.  The simplified version of the SQL generated from the above LINQ query looks like&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: sql" type="syntaxhighlighter"&gt;&lt;![CDATA[select * from employees employee0_ where employee0_.name='Git'                    or employee0_.salary&gt;=1000 and employee0_.salary&lt;=10000;]]&gt;&lt;/script&gt;I have removed all the named parameters that NHibernate adds, but essentially the query looks like the one shown above.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Whats wrong with the query?&amp;nbsp; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Notice that there are no parenthesis to enforce the operator precedence!&amp;nbsp; Because of this, &lt;span style="font-size: large;"&gt;it might get confusing to identify the order in which the operators will be process.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Consider a case when you have a complex query with many conditions and if proper parenthisis are not applied then it could get confusing.&lt;br /&gt;&lt;br /&gt;I tried various permution and combination to force the NHibernate LINQ provider to spitout the parenthesis correctly, however I was not successful in doing so.&lt;br /&gt;&lt;br /&gt;Finally, I decided to &lt;span style="font-size: large;"&gt;switch to the &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx"&gt;QueryOver API&lt;/a&gt; provided by NHibernate.&amp;nbsp; QueryOver API is a Fluent wrapper over the &lt;a href="http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-criteria"&gt;NHibernate Criteria API&lt;/a&gt;.&lt;/span&gt;&amp;nbsp; Using the QueryOver API the above code would look like&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[var employees = session    .QueryOver&lt;employee&gt;()    .Where(x =&gt; x.Name == "Git"         || (x.Salary &gt;= 1000 &amp;&amp; x.Salary &lt;= 10000))    .List();]]&gt;&lt;/script&gt;As you can see the nothing much has changed.&amp;nbsp; The only changes are, &lt;i&gt;&lt;b&gt;.Query() &lt;/b&gt;&lt;/i&gt;call has been changed to &lt;i&gt;&lt;b&gt;.QueryOver() &lt;/b&gt;&lt;/i&gt;and instead of &lt;i&gt;&lt;b&gt;.ToList()&lt;/b&gt;&lt;/i&gt; we have to call &lt;i&gt;&lt;b&gt;.List()&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Let's look at the generated SQL Query:&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[SELECT * FROM employees this_ WHERE (this_.name = 'Git'                           or (this_.salary &gt;= 1000 and this_.salary &lt;= 10000));]]&gt; &lt;/script&gt;&lt;br /&gt;As you can see, &lt;span style="font-size: large;"&gt;it correctly adds the parenthesis to make the operator precedence more explicit!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-6349590123332017229?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/6349590123332017229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/11/making-operator-precidence-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6349590123332017229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6349590123332017229'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/11/making-operator-precidence-more.html' title='Making operator precidence more explicit with NHibernate Linq Provider'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-5156438783348349510</id><published>2011-10-28T16:08:00.000+05:30</published><updated>2011-10-28T16:19:33.902+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='web forms'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with web forms'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='user control'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='web page'/><title type='text'>Enabling Dependency Injection In Web Forms Pages and User Controls using Spring.NET</title><content type='html'>In one of the &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;previous post&lt;/a&gt;, I mentioned, How &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3&lt;/a&gt; and &lt;a href="http://www.asp.net/web-forms"&gt;Web Forms&lt;/a&gt; can exist side by side in one project.&amp;nbsp; We also saw, how we could &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;Enable Dependency Injection using Spring.NET in an MVC3 Application&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But, &lt;span style="font-size: large;"&gt;What about the old Web Form pages and user controls?&amp;nbsp; Can we Enable Dependency Injection in them, so that we can create loosely coupled code?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Surely there is a way of doing this using &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt;.&amp;nbsp; In this post we will carry on from where we left and we will try to enable Dependency Injection even for Web Pages and User Controls.&amp;nbsp; Before moving any further, if you have not already seen my previous post of integrating &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;Spring.NET with MVC3 Application&lt;/a&gt;, now is a good time to see it.&lt;br /&gt;&lt;br /&gt;Without wasting any more time, let's see how we can enable Dependency Injection in Web Forms and User Controls using Spring.NET&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How Do they Do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For sake of this post, let's say we have a web page called &lt;b&gt;&lt;i&gt;Default.aspx&lt;/i&gt;&lt;/b&gt; under the Pages directory.&amp;nbsp; The structure of the project looks somewhat like this&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-JzBzR37NCEo/Tqp8MMiIx4I/AAAAAAAABhc/EPXrxCxpTPY/s1600/projectStructure.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="133" src="http://2.bp.blogspot.com/-JzBzR37NCEo/Tqp8MMiIx4I/AAAAAAAABhc/EPXrxCxpTPY/s320/projectStructure.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The project structure with Default.aspx&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Our task is to inject the &lt;i&gt;&lt;b&gt;AccountService&lt;/b&gt;&lt;/i&gt; into the &lt;i&gt;&lt;b&gt;Default.aspx&lt;/b&gt;&lt;/i&gt; page.&amp;nbsp; As mentioned in the previous post &lt;i&gt;&lt;b&gt;AccountService &lt;/b&gt;&lt;/i&gt;is a class that was already configured in &lt;i&gt;&lt;b&gt;Spring.NET&lt;/b&gt;&lt;/i&gt;, it has one method &lt;i&gt;&lt;b&gt;UserCount &lt;/b&gt;&lt;/i&gt;and we are going to show the user count on the &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;page.&lt;br /&gt;&lt;br /&gt;The steps to enabled dependency injection in web-forms web pages using Spring.NET are as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add &lt;b&gt;HttpHandler, called Spring.Web.Support.PageHandlerFactory for path *.aspx&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Make code changes to &lt;b&gt;Default.aspx to fetch the UserCount from AccountService&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Configure the dependencies of &lt;/b&gt;&lt;b&gt;Default.aspx in web.xml &lt;/b&gt;(web.xml is a spring config file which we created in the previous post)&lt;/li&gt;&lt;/ul&gt;Let look at each step in more detail.&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Step - 1 - Add HttpHandler Spring.Web.Support.PageHandlerFactory for path *.aspx&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This step is pretty straight forward all we need to do is, Add an HttpHandler, called &lt;b&gt;Spring.Web.Support.PageHandlerFactory.&amp;nbsp; &lt;/b&gt;We need to configure it against the path *.aspx.&amp;nbsp; This is required so that, &lt;span style="font-size: large;"&gt;Spring.NET gets an opportunity to perform Dependency Injection when a request comes for any web-forms web page.&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;We need to add the handler to the &lt;b&gt;&amp;lt;httpHandlers&amp;gt; &lt;/b&gt;tag in the web.config.&amp;nbsp; Updated web.config looks like&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;system.web&gt; &lt;!-- Some other configuration here... --&gt;    &lt;httphandlers&gt;   &lt;!-- Some other handlers here... --&gt;       &lt;add verb="*" path="*.aspx"               type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/&gt;    &lt;/httpHandlers&gt;  &lt;/system.web&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Step - 2 - Make code changes to Default.aspx to fetch the UserCount from AccountService&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Lets look at the &lt;i&gt;&lt;b&gt;Default.aspx&lt;/b&gt;&lt;/i&gt; page&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;%@ Page Title="Home Page"     Language="C#" MasterPageFile="~/Site.master"     AutoEventWireup="true"    CodeBehind="Default.aspx.cs"     Inherits="aspnetwebFormsWithMvc3App._Default" %&gt;&lt;asp:Content ID="HeaderContent" runat="server"                     ContentPlaceHolderID="HeadContent"&gt;&lt;/asp:Content&gt;&lt;asp:Content ID="BodyContent" runat="server"                     ContentPlaceHolderID="MainContent"&gt;    &lt;h2&gt;        Welcome to ASP.NET!    &lt;/h2&gt;    &lt;p&gt;     The Number of users of this application are            &lt;label runat="server" id="userCount" /&gt;    &lt;/p&gt;&lt;/asp:Content&gt;]]&gt;&lt;/script&gt;As you can see the html code of &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;is very simple.  It just has a label called &lt;i&gt;&lt;b&gt;userCount &lt;/b&gt;&lt;/i&gt;which will hold the value of number of users in the system.&lt;br /&gt;&lt;br /&gt;We will get the value of &lt;i&gt;&lt;b&gt;userCount &lt;/b&gt;&lt;/i&gt;from &lt;i&gt;&lt;b&gt;AccoutService.&lt;/b&gt;&lt;/i&gt;  Let's look at the code of &lt;i&gt;&lt;b&gt;Default.aspx.cs &lt;/b&gt;&lt;/i&gt;file&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public partial class _Default : Page    {        public IAccountService AccountService { get; set; }        protected void Page_Load(object sender, EventArgs e)        {            userCount.InnerText = AccountService.UserCount().ToString();        }    }]]&gt;&lt;/script&gt;The code of &lt;i&gt;&lt;b&gt;Default.aspx.cs &lt;/b&gt;&lt;/i&gt;has no surprises, it has a property &lt;i&gt;&lt;b&gt;AccoutService.&lt;/b&gt;&lt;/i&gt;  We will plan to injet an implementation of &lt;i&gt;&lt;b&gt;AccoutService &lt;/b&gt;&lt;/i&gt;using &lt;i&gt;&lt;b&gt;Spring.NET.&amp;nbsp; &lt;/b&gt;&lt;/i&gt;In the &lt;i&gt;&lt;b&gt;Page_Load method,&lt;/b&gt;&lt;/i&gt; we simply set the &lt;i&gt;&lt;b&gt;userCount label &lt;/b&gt;&lt;/i&gt;with the value returned by the &lt;i&gt;&lt;b&gt;UserCount &lt;/b&gt;&lt;/i&gt;method of &lt;i&gt;&lt;b&gt;AccoutService.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The only question left to answer is, how do we inject the &lt;i&gt;&lt;b&gt;AccoutService &lt;/b&gt;&lt;/i&gt;into the &lt;i&gt;&lt;b&gt;Default.aspx.cs&lt;/b&gt;&lt;/i&gt;.&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 3 - Configure the dependencies of Page Default.aspx in web.xml&lt;/b&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;For configuring the &lt;i&gt;&lt;b&gt;AccoutService &lt;/b&gt;&lt;/i&gt;dependency in &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;we have to add the following object declaration in &lt;i&gt;&lt;b&gt;web.xml&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;object type="~/Pages/Default.aspx"&gt;    &lt;property name="AccountService" ref="AccountService" /&gt;      &lt;/object&gt;]]&gt;&lt;/script&gt;Notice that we simply have to add the declaration of &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;with proper path in &lt;i&gt;&lt;b&gt;web.xml.  &lt;/b&gt;&lt;/i&gt;Since, &lt;i&gt;&lt;b&gt;Default.aspx&lt;/b&gt;&lt;/i&gt; is located in the &lt;i&gt;&lt;b&gt;Pages directory, &lt;/b&gt;&lt;/i&gt;we have to refer it as &lt;i&gt;&lt;b&gt;~/Pages/Default.aspx.&lt;/b&gt;&lt;/i&gt;  We have to add all the dependencies for the page, just like how we d&lt;b&gt;o i&lt;/b&gt;t for other &lt;i&gt;&lt;b&gt;Spring.NET&lt;/b&gt;&lt;/i&gt; objects.&lt;br /&gt;&lt;br /&gt;All set, lets test our setup and browser the page &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;to see the result. &lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-0KJr7kGtmmw/TqqBHj-4pyI/AAAAAAAABhk/x-gxdzf6-0A/s1600/Default.aspx_With_UserCount.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://1.bp.blogspot.com/-0KJr7kGtmmw/TqqBHj-4pyI/AAAAAAAABhk/x-gxdzf6-0A/s320/Default.aspx_With_UserCount.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Enabled Dependency Injection in web.forms using Spring.NET&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As you can see, we are able to see the user count value on the page.&amp;nbsp; We have successfully Enabled Dependency Injection in Web-Forms Web Pages.&lt;br /&gt;&lt;br /&gt;Lets quickly see how we can enable dependency injection in User Controls.&amp;nbsp; Steps to do that are as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a user control called &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;that invokes &lt;i&gt;&lt;b&gt;AccountService&lt;/b&gt;&lt;/i&gt; to get the user count&lt;/li&gt;&lt;li&gt;Update the &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;to use the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;user control&lt;/li&gt;&lt;li&gt;Configure the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;in &lt;i&gt;&lt;b&gt;web.xml&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Step - 1 - Create a user control called UserCount.ascx that invokes AccountService to get the user count&amp;nbsp; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We are going to create a very simple user control.&amp;nbsp; Let's call it &lt;i&gt;&lt;b&gt;UserCont.ascx.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This user control will simply fetch the user count using the &lt;i&gt;&lt;b&gt;AccountService &lt;/b&gt;&lt;/i&gt;and show it on the UI.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;%@ Control Language="C#"           AutoEventWireup="true"           CodeBehind="UserCount.ascx.cs"           Inherits="aspnetwebFormsWithMvc3App.Controls.UserCount" %&gt;           &lt;p&gt;    The Number of users in the system from user control           &lt;label runat="server" id="userCount" /&gt;   &lt;/p&gt;]]&gt;&lt;/script&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public partial class UserCount : UserControl    {        public IAccountService AccountService { get; set; }        protected void Page_Load(object sender, EventArgs e)        {            userCount.InnerText = AccountService.UserCount().ToString();        }    }]]&gt;&lt;/script&gt;The code of &lt;i&gt;&lt;b&gt;UserCount.ascx&lt;/b&gt;&lt;/i&gt; is very simillar to what we have already seen in &lt;i&gt;&lt;b&gt;Default.aspx.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; We are setting the value of &lt;i&gt;&lt;b&gt;userCount label &lt;/b&gt;&lt;/i&gt;by invoking the &lt;i&gt;&lt;b&gt;UserCount() method of AccountService &lt;/b&gt;&lt;/i&gt;instance.&lt;br /&gt;&lt;br /&gt;Notice that, we are not instantiating &lt;i&gt;&lt;b&gt;AccountService &lt;/b&gt;&lt;/i&gt;anywhere in the user control.  We will inject it using &lt;i&gt;&lt;b&gt;Spring.NET.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Before we look at, how exactly we do that lets update the &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;to make use of the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;user control.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 2 - Update the Default.aspx to use the UserCount.ascx user control&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Let look at the updated &lt;i&gt;&lt;b&gt;Default.aspx&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;%@ Page Title="Home Page" Language="C#"                   MasterPageFile="~/Site.master"                   AutoEventWireup="true"                   CodeBehind="Default.aspx.cs"                   Inherits="aspnetwebFormsWithMvc3App._Default" %&gt;&lt;%@ Register TagPrefix="uc"                       TagName="UserCount"                       Src="~/Controls/UserCount.ascx" %&gt;&lt;asp:Content ID="HeaderContent" runat="server"                     ContentPlaceHolderID="HeadContent"&gt;&lt;/asp:Content&gt;&lt;asp:Content ID="BodyContent" runat="server"                     ContentPlaceHolderID="MainContent"&gt;    &lt;h2&gt;        Welcome to ASP.NET!    &lt;/h2&gt;    &lt;p&gt;    The Number of users of this application are           &lt;label runat="server" id="userCount" /&gt;    &lt;/p&gt;   &lt;uc:UserCount runat="server" ID="ucUserCount"/&gt;&lt;/asp:Content&gt;]]&gt;&lt;/script&gt;Nothing very alarming here.  We simply are including the user control &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;and showing it on the html.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 3 - Configure the UserCount.ascx in web.xml&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;The final step is to configure the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;in &lt;i&gt;&lt;b&gt;web.xml.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Here is how we do it.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;object type="~/Pages/Default.aspx"&gt;    &lt;property name="AccountService" ref="AccountService" /&gt;      &lt;/object&gt;  &lt;object type="~/Controls/UserCount.ascx" abstract="true"&gt;    &lt;property name="AccountService" ref="AccountService" /&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt;Notice that we registered the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;in &lt;i&gt;&lt;b&gt;Spring.NET configuration file.&lt;/b&gt;&lt;/i&gt;  We simply have to specify the complete path of the &lt;i&gt;&lt;b&gt;UserCount.ascx.&amp;nbsp; &lt;/b&gt;&lt;/i&gt;Notice that we didn't have to change the configuration for &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;at all.&amp;nbsp; &lt;i&gt;&lt;b&gt;Spring.NET &lt;/b&gt;&lt;/i&gt;is smart enought to inject the correct instance of &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;in &lt;i&gt;&lt;b&gt;Default.aspx.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Another important thing to notice is that we have to &lt;span style="font-size: large;"&gt;add &lt;b&gt;abstract="true" &lt;/b&gt;to the declaration of &lt;b&gt;UserCount.ascx.&lt;/b&gt;&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;All set, let's see the setup in action&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-0OBoDOdNA9w/TqqBK5ABD_I/AAAAAAAABhs/lnXccHKFhaM/s1600/Default.aspx_With_UserCount_UserControl.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-0OBoDOdNA9w/TqqBK5ABD_I/AAAAAAAABhs/lnXccHKFhaM/s320/Default.aspx_With_UserCount_UserControl.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Enabled Dependency Injection in user controls using Spring.NET&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As we can see, we see two lines on the page showing the &lt;i&gt;&lt;b&gt;UserCount&lt;/b&gt;&lt;/i&gt;, first one is getting the user count directly from &lt;i&gt;&lt;b&gt;Default.aspx &lt;/b&gt;&lt;/i&gt;web page, while the second line is coming from the &lt;i&gt;&lt;b&gt;UserCount.ascx &lt;/b&gt;&lt;/i&gt;user control.&lt;br /&gt;&lt;br /&gt;Mission Accomplished!&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-5156438783348349510?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/5156438783348349510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/10/enabling-dependency-injection-in-web.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5156438783348349510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5156438783348349510'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/10/enabling-dependency-injection-in-web.html' title='Enabling Dependency Injection In Web Forms Pages and User Controls using Spring.NET'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-JzBzR37NCEo/Tqp8MMiIx4I/AAAAAAAABhc/EPXrxCxpTPY/s72-c/projectStructure.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-5084547546616362499</id><published>2011-10-22T12:32:00.004+05:30</published><updated>2011-10-22T12:32:59.393+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicago'/><category scheme='http://www.blogger.com/atom/ns#' term='capitol building'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='white house'/><category scheme='http://www.blogger.com/atom/ns#' term='niagara falls'/><category scheme='http://www.blogger.com/atom/ns#' term='maid of the mist'/><category scheme='http://www.blogger.com/atom/ns#' term='lincoln memorial'/><category scheme='http://www.blogger.com/atom/ns#' term='washington d.c.'/><category scheme='http://www.blogger.com/atom/ns#' term='cave of the winds'/><category scheme='http://www.blogger.com/atom/ns#' term='washington monument'/><category scheme='http://www.blogger.com/atom/ns#' term='virginia beach'/><title type='text'>2300 Miles US Road Trip - Part - 2</title><content type='html'>As mentioned in the &lt;a href="http://www.gitshah.com/2011/10/2300-miles-us-road-trip-part-1.html"&gt;previous post&lt;/a&gt;, we recently took a vacation in the US.&amp;nbsp; The previous post is about, my experiences on the trip in the first week.&amp;nbsp; In this post, I plan to share my experiences on the trip for the second week.&lt;br /&gt;&lt;br /&gt;On a nice Sunday morning we decided to start our road trip.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Destination &lt;a href="http://en.wikipedia.org/wiki/Niagara_Falls"&gt;Niagara&lt;/a&gt;:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We started our road trip from &lt;a href="http://en.wikipedia.org/wiki/Chicago"&gt;Chicago&lt;/a&gt; towards Niagara.&amp;nbsp; The distance of about 570 miles.&amp;nbsp; We were 4 adults and one kid traveling in an &lt;a href="http://en.wikipedia.org/wiki/Honda_Odyssey_%28international%29"&gt;Honda Odyssey&lt;/a&gt;.&amp;nbsp; The drive took around 10 hours.&amp;nbsp; On the way we saw some very beautiful landscapes.&amp;nbsp; Here are a few images&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-NyY3ubmPgrc/TqJS4inKTsI/AAAAAAAABZA/X8ARQhM9Qig/s1600/DSC_0053.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-NyY3ubmPgrc/TqJS4inKTsI/AAAAAAAABZA/X8ARQhM9Qig/s320/DSC_0053.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Giant White cloud&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-mm11mU3-Y5A/TqJS7TXM8JI/AAAAAAAABZM/rijzAP1Uy5A/s1600/DSC_0080+%25282%2529.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-mm11mU3-Y5A/TqJS7TXM8JI/AAAAAAAABZM/rijzAP1Uy5A/s320/DSC_0080+%25282%2529.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Moon in all its glory&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-8A-4ymAH13g/TqJS8kd-XZI/AAAAAAAABZQ/m7GkSss0T4I/s1600/DSC_0119.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-8A-4ymAH13g/TqJS8kd-XZI/AAAAAAAABZQ/m7GkSss0T4I/s320/DSC_0119.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Metal Bridge on the way&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Finally, at about 2030 hrs we reached our hotel at Niagara Falls.&amp;nbsp; I was really exited to finally see the Niagara Falls, I had read about them seen them on Discovery Channel, but as they say&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;span style="font-size: large;"&gt;Seeing is believing!&lt;/span&gt;&lt;/i&gt;&lt;/blockquote&gt;We decided to freshen up and grab a quick dinner and go straight to the falls to enjoy the night view of the falls.&amp;nbsp; I could hear the falls when we were at a distance of 0.5 miles (approx), simply thinking about the force of the falls was making me even more curious and exited.&lt;br /&gt;&lt;br /&gt;When we reached the falls, I could not believe my eyes!&amp;nbsp; &lt;span style="font-size: large;"&gt;The falls were Beautiful, Gigantic, Fast and I don't have enough adjectives to describe them.&lt;/span&gt;&amp;nbsp; During the night, the falls are illuminated with lights of different color.&amp;nbsp; The lights, along with the mist created by the falls, make falls an amazing site to see.&amp;nbsp; Here are a few images&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-1k-Nh82Q0J4/TqJTBVwqviI/AAAAAAAABZg/g3e-BgrbxaU/s1600/DSC_0146+%25282%2529.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-1k-Nh82Q0J4/TqJTBVwqviI/AAAAAAAABZg/g3e-BgrbxaU/s320/DSC_0146+%25282%2529.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fast moving falls along with very powerful floodlights&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-1loAV6CtC2s/TqJTCtqE-FI/AAAAAAAABZk/H0MuAVj-SHY/s1600/DSC_0149.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-1loAV6CtC2s/TqJTCtqE-FI/AAAAAAAABZk/H0MuAVj-SHY/s320/DSC_0149.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The lights keep changing their color which makes the scene even more beautiful.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-yFu3dFUiCpM/TqJTFHP9FdI/AAAAAAAABZw/EnFLVMR94Ts/s1600/DSC_0159.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-yFu3dFUiCpM/TqJTFHP9FdI/AAAAAAAABZw/EnFLVMR94Ts/s320/DSC_0159.JPG" width="212" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;On the other side where you see a tower like structure is &lt;a href="http://en.wikipedia.org/wiki/Canada"&gt;Canada&lt;/a&gt;.&amp;nbsp; The two friendly countries are seperated by one bridge of around 0.2 miles.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-LREh12k3_z0/TqJTjXBDOVI/AAAAAAAABbM/fnzkMDt8Kdk/s1600/DSC_0347.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-LREh12k3_z0/TqJTjXBDOVI/AAAAAAAABbM/fnzkMDt8Kdk/s320/DSC_0347.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Bridge That connects US and Canada&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tpJzwba1C08/TqJTGC0xe1I/AAAAAAAABZ0/SAomHiG-Ds0/s1600/DSC_0173.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-tpJzwba1C08/TqJTGC0xe1I/AAAAAAAABZ0/SAomHiG-Ds0/s320/DSC_0173.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The side from where the lights are flashed is Canada&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-J_kXq317H8Q/TqJTIV7Ev4I/AAAAAAAABZ8/V4L2YPG3eCk/s1600/DSC_0189.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-J_kXq317H8Q/TqJTIV7Ev4I/AAAAAAAABZ8/V4L2YPG3eCk/s320/DSC_0189.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The big tower on the Canadian side is a revolving hotel&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;After spending quite some time at the falls, we decided to head back to the hotel so that we can catchup on some sleep, the next day was going to be a long day&lt;br /&gt;&lt;br /&gt;The next day, we start on a mission to explore Niagara Falls.&amp;nbsp; We decided to see a documentary on the history and mystery of Niagara Falls.&amp;nbsp; It was quite an interesting movie, did you know that, One &lt;a href="http://en.wikipedia.org/wiki/Annie_Edson_Taylor"&gt;Ms. Annie Edson Taylor&lt;/a&gt;, locked herself and her pet cat in a barrel and fell over the Niagara Falls and survived the fall! The movie was well scripted and was a fun watch!&lt;br /&gt;&lt;br /&gt;Next we took a ride on the &lt;a href="http://en.wikipedia.org/wiki/Maid_of_the_Mist"&gt;Maid of the Mist&lt;/a&gt;.&amp;nbsp; Its basically a boat ride that takes you very near the falls so that you can enjoy the view of the falls from its basin.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-a1GqkbsOCT0/TqJToDaA5pI/AAAAAAAABbc/SAbpu75RgkM/s1600/DSC_0375.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-a1GqkbsOCT0/TqJToDaA5pI/AAAAAAAABbc/SAbpu75RgkM/s320/DSC_0375.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Maid of the Mist boat that takes you near the fall&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-2P48YQk7hyo/TqJTfg4tptI/AAAAAAAABbA/nJSNijoJIc0/s1600/DSC_0319.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-2P48YQk7hyo/TqJTfg4tptI/AAAAAAAABbA/nJSNijoJIc0/s320/DSC_0319.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The American Falls And Bridal Veil Falls &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-JO32Ly3qdUQ/TqJTeQpbA-I/AAAAAAAABa8/K_OTHnXUzrI/s1600/DSC_0275+%25282%2529.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-JO32Ly3qdUQ/TqJTeQpbA-I/AAAAAAAABa8/K_OTHnXUzrI/s320/DSC_0275+%25282%2529.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Horseshoe Falls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-bEt1gls4xGU/TqJUP736C-I/AAAAAAAABdA/EhNDO9L__OM/s1600/DSC_0695.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-bEt1gls4xGU/TqJUP736C-I/AAAAAAAABdA/EhNDO9L__OM/s320/DSC_0695.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Horseshoe Falls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&amp;nbsp;The boat ride was fun not only because we got to enjoy the beauty of the falls from very near but also because of hundreads of seagulls were flying around the falls.  The entire landscape was really beautiful!&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-tsbzwFQA36s/TqJTdKOmSkI/AAAAAAAABa4/RdJXkLia5Ww/s1600/DSC_0262.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-tsbzwFQA36s/TqJTdKOmSkI/AAAAAAAABa4/RdJXkLia5Ww/s320/DSC_0262.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Seagulls flying around the falls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Next adventure was to go as near the fall as possible.&amp;nbsp; This time, a walk in the &lt;a href="http://en.wikipedia.org/wiki/Cave_of_the_Winds_%28New_York%29"&gt;Cave of the Winds&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Americans have build a wooden platform, just about 3 meters away from the falls, once you are there, you are bound to get completely drenched.&amp;nbsp; We experienced the force of falls pounding on top of our heads even when we were 3 meters away!&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-CfJzJHYiSR4/TqJTpyS0lOI/AAAAAAAABbg/7VK0Tqivb6c/s1600/DSC_0379.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-CfJzJHYiSR4/TqJTpyS0lOI/AAAAAAAABbg/7VK0Tqivb6c/s320/DSC_0379.JPG" width="212" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Cave of the Winds - The wooden platform 3 meters from the falls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-apdvZJwgP8A/TqJTrBn3avI/AAAAAAAABbk/b84xhcdhEEg/s1600/DSC_0382.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-apdvZJwgP8A/TqJTrBn3avI/AAAAAAAABbk/b84xhcdhEEg/s320/DSC_0382.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-0JC7QpUry1Q/TqJTw9C9ahI/AAAAAAAABb0/62j5elIXrVY/s1600/DSC_0433.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-0JC7QpUry1Q/TqJTw9C9ahI/AAAAAAAABb0/62j5elIXrVY/s320/DSC_0433.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Nearest point - You can't go any closer to the falls.&amp;nbsp; The force of falls was enormous.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As you can see from the images there is no way one can get out dry even with a raincoat on.&amp;nbsp; It was total fun!&lt;br /&gt;&lt;br /&gt;We decided to spend the evening at the falls and enjoy its beauty, did a nature trail around the falls, overall had a fun filled day.&amp;nbsp; Here are some evening snaps of the Niagara Falls.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-FJ_nt-dSwQc/TqJUQmfDhmI/AAAAAAAABdE/LBMCawqRypY/s1600/DSC_0710.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-FJ_nt-dSwQc/TqJUQmfDhmI/AAAAAAAABdE/LBMCawqRypY/s320/DSC_0710.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-HOeYBq6UMls/TqJUTogESHI/AAAAAAAABdQ/smLLSG1av2o/s1600/DSC_0733.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-HOeYBq6UMls/TqJUTogESHI/AAAAAAAABdQ/smLLSG1av2o/s320/DSC_0733.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;You can even see the dark spots on the moon &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;b&gt;Destination &lt;a href="http://en.wikipedia.org/wiki/Virginia_Beach,_Virginia"&gt;Virginia Beach&lt;/a&gt;:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next day, we decided to continue our trip.&amp;nbsp; Today's destination was Virginia Beach.&amp;nbsp; The distance of Virginia Beach from Niagara Falls was about 640 miles.&amp;nbsp; The journey took around 12 hours.&lt;br /&gt;&lt;br /&gt;Our Hotel room had an awesome view.&amp;nbsp; The hotel was right in front of the beach.&amp;nbsp; There was nothing in between the hotel room and the beach!&amp;nbsp; We could see the beach from our hotel room terrace.&amp;nbsp; It was an amazing site!&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--WVYbNd4iA8/TqJVKkdgqjI/AAAAAAAABd8/Gg31WVvuRgQ/s1600/DSC_0091.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/--WVYbNd4iA8/TqJVKkdgqjI/AAAAAAAABd8/Gg31WVvuRgQ/s320/DSC_0091.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Snap click from the hotel terrace&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;We could hear the waves from our room, the feeling was fabulous!&amp;nbsp; Next morning, I woke up early so that I could click some snaps of the sunrise&amp;nbsp; &lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Vc7ZZY5jTYQ/TqJVHEA8AZI/AAAAAAAABd0/P2E5AHDwKMg/s1600/DSC_0042.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-Vc7ZZY5jTYQ/TqJVHEA8AZI/AAAAAAAABd0/P2E5AHDwKMg/s320/DSC_0042.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Beautiful dawn at Sea&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-FjBNo4JzLHk/TqJVL73Lc2I/AAAAAAAABeA/-fur3PP5SVk/s1600/DSC_0101.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-FjBNo4JzLHk/TqJVL73Lc2I/AAAAAAAABeA/-fur3PP5SVk/s320/DSC_0101.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The sunrise and the reflection of sun in the ocean&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Watched people feeding the seagulls, cycling at the beach, we even saw a few dolphins&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-FdLmSKJtOsk/TqJVN0CelgI/AAAAAAAABeE/1Bbd7qn-dJ4/s1600/DSC_0104.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-FdLmSKJtOsk/TqJVN0CelgI/AAAAAAAABeE/1Bbd7qn-dJ4/s320/DSC_0104.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The lady feeding the Seagulls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/--JI6JrtjQiM/TqJVPnfSEsI/AAAAAAAABeI/fVNZpweYR80/s1600/DSC_0118.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/--JI6JrtjQiM/TqJVPnfSEsI/AAAAAAAABeI/fVNZpweYR80/s320/DSC_0118.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;People cycling by the beach side&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-vM90MjeWJBM/TqJVQzZ1xtI/AAAAAAAABeM/r2lzgiP7s0U/s1600/DSC_0131.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-vM90MjeWJBM/TqJVQzZ1xtI/AAAAAAAABeM/r2lzgiP7s0U/s320/DSC_0131.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The small black spots that you see, are dolphins&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I was pretty interested in doing some adventure activities at the beach, one activity that I wanted to do since a long time was &lt;a href="http://en.wikipedia.org/wiki/Parasailing"&gt;Parasailing&lt;/a&gt;, we found a place and went for it.&amp;nbsp; The best part of Parasailing activity was when they dip you into the ocean!&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-amISSqOtdOk/TqJVcLUlDVI/AAAAAAAABes/gEz3UXeA-dA/s1600/DSC_0330.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-amISSqOtdOk/TqJVcLUlDVI/AAAAAAAABes/gEz3UXeA-dA/s320/DSC_0330.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Getting our feet wet while parasailing&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-uOISvVH1rOA/TqJVc5-MGII/AAAAAAAABew/hskrgPPCex4/s1600/DSC_0348.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-uOISvVH1rOA/TqJVc5-MGII/AAAAAAAABew/hskrgPPCex4/s320/DSC_0348.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Once we were back on solid ground, I saw my second love&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-CrpOfSGSg-o/TqJVeWRfxiI/AAAAAAAABe0/aZPc0PFzBxM/s1600/DSC_0374.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-CrpOfSGSg-o/TqJVeWRfxiI/AAAAAAAABe0/aZPc0PFzBxM/s320/DSC_0374.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Nice and Shining Harley Davidson&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Yes, Harley Davidson, I had an opportunity to ride this bike once and from there on, I have fallen in love with it!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Destination &lt;a href="http://en.wikipedia.org/wiki/Washington,_D.C."&gt;Washington D.C.&lt;/a&gt;:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On the same day at about 1700 hrs we started our journey towards Washington D.C.&amp;nbsp; A journey of about 230 miles took us around 5 hours (caught in a jam on our way).&lt;br /&gt;&lt;br /&gt;Next day we had a big list of places to visit.&amp;nbsp; We started early we saw the &lt;a href="http://en.wikipedia.org/wiki/United_States_Capitol"&gt;Capitol Building&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/White_House"&gt;White House&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Lincoln_Memorial"&gt;Lincoln Memorial&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/World_war_ii_memorial"&gt;World war II Memorial&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Washington_Monument"&gt;Washington Monument&lt;/a&gt; and finally the &lt;a href="http://en.wikipedia.org/wiki/National_Air_and_Space_Museum"&gt;Air and Space Museum&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;All these places are pretty close to each other.&amp;nbsp; One can easily walk and visit them.&amp;nbsp; But at the end of the day, I felt like I had no legs, I was dead tired.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-kKlgHai-7R8/TqJWNV0lCnI/AAAAAAAABgg/fef51NcAiRg/s1600/DSC_0736.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-kKlgHai-7R8/TqJWNV0lCnI/AAAAAAAABgg/fef51NcAiRg/s320/DSC_0736.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Capitol Building&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-8HbyveJZunE/TqJVuV4XYkI/AAAAAAAABfc/PF2q6JlrhiI/s1600/DSC_0505.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-8HbyveJZunE/TqJVuV4XYkI/AAAAAAAABfc/PF2q6JlrhiI/s320/DSC_0505.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The White House&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-LISoDBRMbLo/TqJV_2aW4qI/AAAAAAAABgA/FQVFFzCXwZY/s1600/DSC_0615.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-LISoDBRMbLo/TqJV_2aW4qI/AAAAAAAABgA/FQVFFzCXwZY/s320/DSC_0615.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Lincoln Memorial&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-BlO2WSU6Sqc/TqJWBJw186I/AAAAAAAABgE/ND2vhhlAIFU/s1600/DSC_0623.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-BlO2WSU6Sqc/TqJWBJw186I/AAAAAAAABgE/ND2vhhlAIFU/s320/DSC_0623.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Big Statue of Abraham Lincoln in the Lincoln Memorial&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-r-eOKQaCd1w/TqJWChEvQeI/AAAAAAAABgI/OuEyCxKXL9g/s1600/DSC_0659.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-r-eOKQaCd1w/TqJWChEvQeI/AAAAAAAABgI/OuEyCxKXL9g/s320/DSC_0659.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;World War - II Memorial&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Ui4v3GSSOKg/TqJWI6M_aEI/AAAAAAAABgU/XwsSLywDjeY/s1600/DSC_0698.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-Ui4v3GSSOKg/TqJWI6M_aEI/AAAAAAAABgU/XwsSLywDjeY/s320/DSC_0698.JPG" width="212" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Washington Monument&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Fn9hqv9fxSI/TqJWKSqhBJI/AAAAAAAABgY/Fnl6z63DEUs/s1600/DSC_0721.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-Fn9hqv9fxSI/TqJWKSqhBJI/AAAAAAAABgY/Fnl6z63DEUs/s320/DSC_0721.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-xONV5_b_JgE/TqJWO7ZNW_I/AAAAAAAABgk/Tqo_aJo4_ng/s1600/DSC_0751.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-xONV5_b_JgE/TqJWO7ZNW_I/AAAAAAAABgk/Tqo_aJo4_ng/s320/DSC_0751.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Air and Space Museum&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Out of all these places, I liked the Capitol building and Air and Space Museum.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;End of Journey:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Could not believe that it was already time to head home.&amp;nbsp; After a week of fantastic trip and wonderful memories it was time we start our journey towards Chicago.&amp;nbsp; A journey of about 750 miles took us around 13 hours.&amp;nbsp; On the way back, we also got a ticket for not wearing seat belts!&lt;br /&gt;&lt;br /&gt;Had lots of fun with some very different/beautiful experiences (one of the "different" experience on the way back was, I lost my checked-in bag!)&lt;br /&gt;&lt;br /&gt;Overall it was a fantastic and memorable trip!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-5084547546616362499?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/5084547546616362499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/10/2300-miles-us-road-trip-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5084547546616362499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5084547546616362499'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/10/2300-miles-us-road-trip-part-2.html' title='2300 Miles US Road Trip - Part - 2'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-NyY3ubmPgrc/TqJS4inKTsI/AAAAAAAABZA/X8ARQhM9Qig/s72-c/DSC_0053.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-2881760525894661951</id><published>2011-10-09T17:48:00.000+05:30</published><updated>2011-10-09T18:02:37.507+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicago'/><category scheme='http://www.blogger.com/atom/ns#' term='delhi airport'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='minneapolis'/><category scheme='http://www.blogger.com/atom/ns#' term='Buckingham Fountain'/><category scheme='http://www.blogger.com/atom/ns#' term='opera'/><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><category scheme='http://www.blogger.com/atom/ns#' term='navy pier'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud gate'/><category scheme='http://www.blogger.com/atom/ns#' term='sears tower'/><title type='text'>2300 Miles US Road Trip - Part - 1</title><content type='html'>Recently me and my family had an opportunity to visit the US for two weeks.  I had some official work for about 4 days.  We had planned a vacation for the rest of the time.  Naturally, I wanted to visit lots of places, do lots of stuff when I was in the US.  Some of the top places I wanted to visit were &lt;a href="http://en.wikipedia.org/wiki/Niagara_Falls"&gt;Niagara Falls&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/The_White_House"&gt;The White House&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Virginia_Beach,_Virginia"&gt;Virginia Beach&lt;/a&gt;, &lt;a href="http://www.google.co.in/search?hl=en&amp;amp;cp=17&amp;amp;gs_id=20&amp;amp;xhr=t&amp;amp;q=autumn+colors+pennsylvania&amp;amp;gs_sm=&amp;amp;gs_upl=&amp;amp;bav=on.2,or.r_gc.r_pw.,cf.osb&amp;amp;biw=1525&amp;amp;bih=767&amp;amp;wrapid=tljp1318147140464025&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;tbm=isch&amp;amp;source=og&amp;amp;sa=N&amp;amp;tab=wi"&gt;&lt;span class="rg_ctlv"&gt;Pennsylvania&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Florida"&gt;Florida&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Yellowstone_National_Park"&gt;Yellowstone National Park&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Hoover_Dam"&gt;Hoover Dam&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Las_Vegas,_Nevada"&gt;Las Vegas&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Grand_Canyon"&gt;The Grand Canyon&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Willis_Tower"&gt;Sears Tower (Willis Tower)&lt;/a&gt; etc.&lt;br /&gt;&lt;br /&gt;The list was endless and I knew we cannot cover all these places in just seven days.  We had to decide on places that were practically possible and onces that I wanted to visit the most.We decided to do a road trip to some of the most appealing places (read that as places that were practically possible :)).  We ended up doing a 2300 miles fantastic road trip, here is a post that summarizes my experiences on the entire trip and things that I loved the most.&lt;br /&gt;&lt;br /&gt;Our journey started from the Pune airport.&amp;nbsp; We were supposed to fly from Pune to Delhi to Chicago.&amp;nbsp; We were visiting the Delhi Airport for the first, we had approximately 5 hours between flights, I thought that will be a good time to see the Delhi Airport.&amp;nbsp; I had heard lots of good things about it and boy, I was in for a surprise. &lt;br /&gt;&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Indira_Gandhi_International_Airport"&gt;Delhi Airport&lt;/a&gt; is one of the best International Airport that I have ever been to.&amp;nbsp; By the way, I have been to a lot of international airports (&lt;a href="http://en.wikipedia.org/wiki/Dubai_International_Airport"&gt;Dubai&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Bahrain_International_Airport"&gt;Bharain&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Addis_Ababa"&gt;Addis Ababa&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Ben_Gurion_International_Airport"&gt;Israel&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Frankfurt_Airport"&gt;Frankfurt&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Paris-Charles_de_Gaulle_Airport"&gt;Paris&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Berlin_Tegel_Airport"&gt;Berlin&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Zurich_Airport"&gt;Zurich&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/O%27Hare_International_Airport"&gt;Chicago&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Minneapolis%E2%88%92Saint_Paul_International_Airport"&gt;Minneapolis&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Amsterdam_Airport_Schiphol"&gt;Amsterdam&lt;/a&gt; etc.) and I can be sure that, this one was one of the best.&lt;br /&gt;&lt;br /&gt;There were things to do, places to visit, shops to be explored, right at the Airport itself.&amp;nbsp; There are huge corridors, walkways, benches with palm trees around them, tint of indian culture etc.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XGrUEyPgBr4/TpFXhTEOaxI/AAAAAAAABQg/xeyWUev7AsI/s1600/DSC_0009.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-XGrUEyPgBr4/TpFXhTEOaxI/AAAAAAAABQg/xeyWUev7AsI/s320/DSC_0009.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Benches with palm trees around them&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-fam34Za8Y5Q/TpFXzqcp8DI/AAAAAAAABQk/-MRcd3rOOBU/s1600/DSC_0012.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-fam34Za8Y5Q/TpFXzqcp8DI/AAAAAAAABQk/-MRcd3rOOBU/s320/DSC_0012.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Huge corridors, walkways&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Vfr7_4V_Z6M/TpFYG1TD7YI/AAAAAAAABQo/SPdhugVdjYU/s1600/DSC_0014.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-Vfr7_4V_Z6M/TpFYG1TD7YI/AAAAAAAABQo/SPdhugVdjYU/s320/DSC_0014.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Hand postures representing a dance form called Kathak&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Out of all the shops at the Airport one that appealed the most to me had a healing pool in it.&amp;nbsp; Its like a small pool which has water till your ankles, people are supposed to remove their footwear and walk inside the pool.&amp;nbsp; The tiles in the pool would pressurize certain areas on your sole which gives you a very refreshing feeling.&amp;nbsp; This science is called &lt;a href="http://en.wikipedia.org/wiki/Acupuncture"&gt;Acupressure&lt;/a&gt;.&amp;nbsp; I did try it and felt totally incredible, felt really energized.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-0Vca20Gcpro/TpGDbEgoQZI/AAAAAAAABQs/NANdd4ochG4/s1600/DSC_0018.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-0Vca20Gcpro/TpGDbEgoQZI/AAAAAAAABQs/NANdd4ochG4/s320/DSC_0018.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The healing pool with lots of bells hanging&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-6O6_m601VqY/TpGDvHZw2MI/AAAAAAAABQw/BiXyWeXUuJQ/s1600/DSC_0017.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-6O6_m601VqY/TpGDvHZw2MI/AAAAAAAABQw/BiXyWeXUuJQ/s320/DSC_0017.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;As you can see people could walk in the pool and get rejuvenated &lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;In the same shop there was live entertainment going on.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-9RJhLkJfbXk/TpGG6dAgiCI/AAAAAAAABSo/DvJbLJnNQXc/s1600/DSC_0026.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-9RJhLkJfbXk/TpGG6dAgiCI/AAAAAAAABSo/DvJbLJnNQXc/s320/DSC_0026.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Person on left is playing flute and the other guy is playing tabla&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The person with a long bamboo stick is playing a musical instrument called &lt;a href="http://en.wikipedia.org/wiki/Flute"&gt;Flute&lt;/a&gt; and the other guy is playing a traditional Indian instrument called &lt;a href="http://en.wikipedia.org/wiki/Tabla"&gt;Tabla&lt;/a&gt;.&amp;nbsp; The sound of these instruments is very soothing and relaxing.&lt;br /&gt;&lt;br /&gt;All around the Airport, there are huge beautiful metal sculptures which depict Indian culture&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-JXGOxaZrMjQ/TpGG-ri7d_I/AAAAAAAABS0/Q4m-o-o3KRk/s1600/DSC_0034.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-JXGOxaZrMjQ/TpGG-ri7d_I/AAAAAAAABS0/Q4m-o-o3KRk/s320/DSC_0034.JPG" width="212" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Sculpture of lord Shiva&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Delhi Airport had a western look as well.&amp;nbsp; There were recliner chairs with charging pods in the chair itself.&amp;nbsp; Nice, Shiny Mercedes was also lying around at the airport.&amp;nbsp; Over all it was a surprising experience.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-oe5RHl1d44s/TpGG9BETJHI/AAAAAAAABSw/rFrVMZ_Q_AY/s1600/DSC_0032.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-oe5RHl1d44s/TpGG9BETJHI/AAAAAAAABSw/rFrVMZ_Q_AY/s320/DSC_0032.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Mercedes at the Delhi Airport&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;b&gt;Next stop &lt;a href="http://en.wikipedia.org/wiki/Chicago"&gt;Chicago&lt;/a&gt;:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;At Chicago on Monday - Labor Day - morning we visited a Swami Narayan temple near by.&amp;nbsp; The temple had a rich white facade with lush green lawn and blue fountains.&amp;nbsp; Under the clear blue sky with sparse white cloud cover it looked really beautiful!&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-N0o3xCtU_T8/TpGG_6PARwI/AAAAAAAABS4/AY9IebU05MY/s1600/DSC_0067.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-N0o3xCtU_T8/TpGG_6PARwI/AAAAAAAABS4/AY9IebU05MY/s320/DSC_0067.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Swami Narayan Temple with white facade and lush green lawns&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-E3LRYXaaUTo/TpGHBoa7_9I/AAAAAAAABS8/cP5-1_xQAH8/s1600/DSC_0080.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-E3LRYXaaUTo/TpGHBoa7_9I/AAAAAAAABS8/cP5-1_xQAH8/s320/DSC_0080.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Blue colored fountains&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;Next stop &lt;a href="http://en.wikipedia.org/wiki/Minneapolis"&gt;Minneapolis&lt;/a&gt;:&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;As I mentioned earlier I had 4 days of official work.&amp;nbsp; I had to leave for Minneapolis on Monday.&amp;nbsp; But my trip does not stop here.&amp;nbsp; Even when I was at Minneapolis, my friends at work took me to some very nice restaurants in the evenings.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2lPhXwig8BY/TpGH4iCpQ6I/AAAAAAAABVI/YeSGV5Jogrk/s1600/DSC_0109.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-2lPhXwig8BY/TpGH4iCpQ6I/AAAAAAAABVI/YeSGV5Jogrk/s320/DSC_0109.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Pat sitting on the left hand side and Paul on the right&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6XgoMhrQR_Y/TpGH3j9kdeI/AAAAAAAABVE/Sc38nz8j2OU/s1600/DSC_0108.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-6XgoMhrQR_Y/TpGH3j9kdeI/AAAAAAAABVE/Sc38nz8j2OU/s320/DSC_0108.JPG" width="212" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But by far the single biggest attraction of my stay at Minneapolis was the Base ball game!&amp;nbsp; My friends at Minneapolis had arranged tickets for a Base Ball game! &lt;br /&gt;&lt;br /&gt;The game was between the home team i.e. &lt;a href="http://en.wikipedia.org/wiki/Minnesota_Twins"&gt;Twins&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Chicago_White_Sox"&gt;Chicago White Sox&lt;/a&gt;.&amp;nbsp; Although the home team was not having a great phase they did win this game!&amp;nbsp; We had a very good view, our seats were right behind the batter, I could click some very good snaps&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-n_Tf9zaztHs/TpGIAwkIpxI/AAAAAAAABVg/opmO7opfdgk/s1600/DSC_0164.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-n_Tf9zaztHs/TpGIAwkIpxI/AAAAAAAABVg/opmO7opfdgk/s320/DSC_0164.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-0z7_UZhgDHs/TpGH_f50J9I/AAAAAAAABVc/oPxDeuF3Ok4/s1600/DSC_0146.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-0z7_UZhgDHs/TpGH_f50J9I/AAAAAAAABVc/oPxDeuF3Ok4/s320/DSC_0146.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The road to the office was scenic, our office was around an artificial lake because of this the entire area had very good green cover with beautiful flowers and lovely trees!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-G9Ni1vpF1Bw/TpGIDqTQnnI/AAAAAAAABVo/COLMqg6fD-M/s1600/DSC_0196.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-G9Ni1vpF1Bw/TpGIDqTQnnI/AAAAAAAABVo/COLMqg6fD-M/s320/DSC_0196.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-pf-tI8YjJr4/TpGIFH46URI/AAAAAAAABVs/l-Y2rmMBcwk/s1600/DSC_0202.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-pf-tI8YjJr4/TpGIFH46URI/AAAAAAAABVs/l-Y2rmMBcwk/s320/DSC_0202.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Path way to the office&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Lzi--8w5li0/TpGIIV4XzdI/AAAAAAAABV0/0A4clw6z8Rk/s1600/DSC_0228.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-Lzi--8w5li0/TpGIIV4XzdI/AAAAAAAABV0/0A4clw6z8Rk/s320/DSC_0228.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;One evening one of my friend took me to the &lt;a href="http://en.wikipedia.org/wiki/Mall_of_America"&gt;Mall of America&lt;/a&gt;!&amp;nbsp; Its supposed to be the second largest mall in the world and boy it was big!&amp;nbsp; There were hundreads of shops in fact it was so big that they had a mini amuzement part right inside the mall!&amp;nbsp; I did sit in one of the roller coster which looked the most scary roller coster it had a drop of around 93 degrees!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/wLJm0IC3lQk/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/wLJm0IC3lQk&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/wLJm0IC3lQk&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;b&gt;Back to Chicago:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;After fishing my work in Minneapolis, I came back to Chicago on Saturday morning, we decided to visit Chicago down town in the evening.&amp;nbsp; Chicago downtown is just like any other city with lots of big buildings and beautiful lake near by.&lt;br /&gt;&lt;br /&gt;We visited the &lt;a href="http://en.wikipedia.org/wiki/Silver_bean"&gt;Cloud Gate&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Buckingham_Fountain"&gt;Buckingham Fountain&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Sears_Tower"&gt;Sears Tower&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Navy_Pier"&gt;Navy Pier&lt;/a&gt; and oh yes, saw the fireworks at Navy Pier&lt;br /&gt;&lt;br /&gt;The Cloud Gate is like a giant silver bean, it was quite a popular spot, we saw at least 6-7 newly wed couples near it.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-TsSkNigmTHk/TpGHH2rmc6I/AAAAAAAABTM/DzdmsTqyzDY/s1600/DSC_0283.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-TsSkNigmTHk/TpGHH2rmc6I/AAAAAAAABTM/DzdmsTqyzDY/s320/DSC_0283.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Cloud Gate&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-zoXyk_IMgm0/TpGHGOKqRiI/AAAAAAAABTI/GVbganZKOI4/s1600/DSC_0275.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-zoXyk_IMgm0/TpGHGOKqRiI/AAAAAAAABTI/GVbganZKOI4/s320/DSC_0275.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-RvXOINrfpUM/TpGHJPY4CwI/AAAAAAAABTQ/4Ba4W0URO6Q/s1600/DSC_0291.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-RvXOINrfpUM/TpGHJPY4CwI/AAAAAAAABTQ/4Ba4W0URO6Q/s320/DSC_0291.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-rK7hiHQZPkQ/TpGHNjx9l7I/AAAAAAAABTg/V66aix6jo3U/s1600/DSC_0313.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-rK7hiHQZPkQ/TpGHNjx9l7I/AAAAAAAABTg/V66aix6jo3U/s320/DSC_0313.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-VGqKiSdl9n0/TpGHVc5aydI/AAAAAAAABT4/eyOWotmkwKU/s1600/DSC_0405.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-VGqKiSdl9n0/TpGHVc5aydI/AAAAAAAABT4/eyOWotmkwKU/s320/DSC_0405.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-WiT1ooTQnnY/TpGHOof0FyI/AAAAAAAABTk/R5Y1WrK9nRU/s1600/DSC_0314.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-WiT1ooTQnnY/TpGHOof0FyI/AAAAAAAABTk/R5Y1WrK9nRU/s320/DSC_0314.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Snaps from the &lt;a href="http://en.wikipedia.org/wiki/Buckingham_Fountain"&gt;Buckingham Fountain&lt;/a&gt;, sears tower and navy pears&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-N22r3b1WbFs/TpGHW-I7WJI/AAAAAAAABT8/Rwlr2TAbIf0/s1600/DSC_0408.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-N22r3b1WbFs/TpGHW-I7WJI/AAAAAAAABT8/Rwlr2TAbIf0/s320/DSC_0408.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Buckingham Fountain&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6cJ6ljOUy_w/TpGHXlnIVPI/AAAAAAAABUA/msaGnKpHupw/s1600/DSC_0427.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-6cJ6ljOUy_w/TpGHXlnIVPI/AAAAAAAABUA/msaGnKpHupw/s320/DSC_0427.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XIU_CplNSq0/TpGHZzp3qWI/AAAAAAAABUI/IxNKlVbuxtg/s1600/DSC_0435.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-XIU_CplNSq0/TpGHZzp3qWI/AAAAAAAABUI/IxNKlVbuxtg/s320/DSC_0435.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;View from the Sears Tower&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-FQCfo5uxFvk/TpGHl4f1M4I/AAAAAAAABUk/u0hYVBcSgm0/s1600/DSC_0502.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-FQCfo5uxFvk/TpGHl4f1M4I/AAAAAAAABUk/u0hYVBcSgm0/s320/DSC_0502.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-t5UOewnmtNk/TpGHm9ow79I/AAAAAAAABUo/PLNdfUh59ag/s1600/DSC_0507.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-t5UOewnmtNk/TpGHm9ow79I/AAAAAAAABUo/PLNdfUh59ag/s320/DSC_0507.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0iSve6qaFSM/TpGHs4CZ46I/AAAAAAAABU8/NaLrVDXNRXo/s1600/DSC_0590.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-0iSve6qaFSM/TpGHs4CZ46I/AAAAAAAABU8/NaLrVDXNRXo/s320/DSC_0590.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Fireworks at Navy Pier&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-9TvmBEIyNGE/TpGHrRmr_gI/AAAAAAAABU4/qd2WDygVOPc/s1600/DSC_0571.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-9TvmBEIyNGE/TpGHrRmr_gI/AAAAAAAABU4/qd2WDygVOPc/s320/DSC_0571.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;At Sears Tower, there is glass compartment which is suspended, which means there is nothing below it - The Sky Deck!&amp;nbsp; You are standing on glass 110 stories high with nothing below you, Scary!&lt;br /&gt;&lt;br /&gt;While heading home we even saw a opera it was quite interesting actually!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-W-hM4ZJi3GU/TpGQt_p9BmI/AAAAAAAABWY/B0Gk7wCa6kg/s1600/DSC_0539.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-W-hM4ZJi3GU/TpGQt_p9BmI/AAAAAAAABWY/B0Gk7wCa6kg/s320/DSC_0539.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;By this time one week had already passed.&amp;nbsp; I had lot of fun and some very first experiences in this memorable one week.&lt;br /&gt;&lt;br /&gt;Next day we were supposed to leave for our road trip.&amp;nbsp; In my next post I will share my experiences about the places that we visited in the coming week!&lt;br /&gt;&lt;br /&gt;Stay tuned folks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-2881760525894661951?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/2881760525894661951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/10/2300-miles-us-road-trip-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2881760525894661951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2881760525894661951'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/10/2300-miles-us-road-trip-part-1.html' title='2300 Miles US Road Trip - Part - 1'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-XGrUEyPgBr4/TpFXhTEOaxI/AAAAAAAABQg/xeyWUev7AsI/s72-c/DSC_0009.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-789698158169444714</id><published>2011-10-02T15:26:00.000+05:30</published><updated>2011-10-02T15:35:25.150+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='strongly typed session'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='http session'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='application scope'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='session'/><title type='text'>Strongly Typed Session Using MVC3 and Spring.NET - Part - 3</title><content type='html'>This is the last post in the series of posts to show How we can achieve &lt;a href="http://www.gitshah.com/2011/09/strongly-typed-session-with-mvc3-and.html"&gt;Strongly Typed Session using MVC3 and Spring.NET&lt;/a&gt;.&amp;nbsp; In previous two posts (&lt;a href="http://www.gitshah.com/2011/09/strongly-typed-session-with-mvc3-and.html"&gt;first&lt;/a&gt; and &lt;a href="http://www.gitshah.com/2011/09/strongly-typed-session-using-mvc3-and.html"&gt;second&lt;/a&gt;) we saw what were the benefits of strongly typed session and how we could enable the session scope using &lt;a href="http://www.springframework.net/"&gt;Spring.NET 1.3.1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The question that we had left unanswered in the &lt;a href="http://www.gitshah.com/2011/09/strongly-typed-session-using-mvc3-and.html"&gt;previous post&lt;/a&gt; was: &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is "session" scope supposed to do with Strongly typed sessions?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Well the session scope is the key, in this post we will see how it enables us to create a strongly typed session.&lt;br /&gt;&lt;br /&gt;The session scope enables us, to register objects with &lt;i&gt;&lt;b&gt;scope=session.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;Spring.NET will create one instance per user Session for objects that are configured with scope=session.&lt;/span&gt;&amp;nbsp; This means effectively &lt;span style="font-size: large;"&gt;we can use such an object to hold information that would otherwise be saved in the HTTP Session.&lt;/span&gt;&amp;nbsp; Since, these objects are configured in Spring.NET, they can be injected as dependencies in any other class.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where would we want to inject such a class?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;MVC Controllers are a good place to do so.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why?&amp;nbsp; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Because, controllers are the class that would do some business processing and then would want to set some information in the HTTP Session.&lt;br /&gt;&lt;br /&gt;For e.g. Lets consider this scenario, we have a &lt;i&gt;&lt;b&gt;AuthenticationController &lt;/b&gt;&lt;/i&gt;which has a &lt;i&gt;&lt;b&gt;Login action.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This method takes in the &lt;i&gt;&lt;b&gt;username and password &lt;/b&gt;&lt;/i&gt;as argument.&amp;nbsp; This method calls the &lt;i&gt;&lt;b&gt;AuthenticationService &lt;/b&gt;&lt;/i&gt;to find whether the &lt;i&gt;&lt;b&gt;username and password &lt;/b&gt;&lt;/i&gt;combination is valid.&amp;nbsp; If the &lt;i&gt;&lt;b&gt;username and password &lt;/b&gt;&lt;/i&gt;are valid, &lt;i&gt;&lt;b&gt;AuthenticationController &lt;/b&gt;&lt;/i&gt;wants to set the &lt;i&gt;&lt;b&gt;username &lt;/b&gt;&lt;/i&gt;in the session so that it could be used by other pages to show user information on the page. &lt;br /&gt;&lt;br /&gt;In our case we do not want to use the HTTP Session.&amp;nbsp; &lt;span style="font-size: large;"&gt;Hence, our &lt;i&gt;&lt;b&gt;Authentication&lt;/b&gt;&lt;b&gt;Controller &lt;/b&gt;&lt;/i&gt;will put the &lt;i&gt;&lt;b&gt;username &lt;/b&gt;&lt;/i&gt;in some object, let's call it &lt;i&gt;&lt;b&gt;UserContext, &lt;/b&gt;&lt;/i&gt;which has been configured in Spring.NET with &lt;b&gt;scope="session"&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But wait,&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What if two users are trying to login at the same time?&amp;nbsp; Will one thread overwrite the username saved in the &lt;i&gt;UserContext &lt;/i&gt;by the other thread?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;As the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;object is configured with &lt;i&gt;&lt;b&gt;scope="session", &lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-size: large;"&gt;Spring.NET is smart enough to understand that, two requests are coming&amp;nbsp; to &lt;i&gt;&lt;b&gt;AuthenticationController &lt;/b&gt;&lt;/i&gt;are coming from two different user sessions, it injects &lt;b&gt;two different instances &lt;/b&gt;of &lt;i&gt;UserContext&lt;/i&gt; in the &lt;i&gt;AutheticationController &lt;/i&gt;for two different user sessions.&lt;/span&gt;&amp;nbsp; Hence, one thread will &lt;b&gt;*not*&lt;/b&gt; overwrite the username set in the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;by the other thread.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;So far so good.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What happens when, user who had logged in earlier (i.e. UserContext has the UserName property set), sends another request to the server?&lt;/b&gt;&amp;nbsp; &lt;b&gt;How do we ensure that correct UserContext instance is injected in the Controller so that previously set UserName could be retrieved?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Again, &lt;span style="font-size: large;"&gt;Spring.NET is smart enough to understand that, for the given user session an instance of &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;was already created, Spring.NET will find the correct &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;instance associated with the user session and injects it in other Controllers/objects that need it.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;This effectively eleminates the direct use of HTTP Session for us.&amp;nbsp; &lt;/span&gt;We can be sure that, whatever information we set in &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;will be specific for a given User Session and correct &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;instance will be injected in the controller whenever we need it.&lt;br /&gt;&lt;br /&gt;I know, at first it all looks very confusing, but lets look at the code to make things clear.&lt;br /&gt;&lt;br /&gt;These are the steps required to configure the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;and &lt;i&gt;&lt;b&gt;AuthenticationController&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Register the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;in Spring.NET configuration file with &lt;i&gt;&lt;b&gt;scope="session"&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Write the implementation for the &lt;i&gt;&lt;b&gt;UserContext&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Register the &lt;i&gt;&lt;b&gt;AuthenticationController&lt;/b&gt;&lt;/i&gt; in Spring.NET configuration flie with &lt;i&gt;&lt;b&gt;singleton="false".&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Add to this the dependency of &lt;i&gt;&lt;b&gt;UserContext. &lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Write implementation of &lt;i&gt;&lt;b&gt;Login Action&lt;/b&gt;&lt;/i&gt; to set the &lt;i&gt;&lt;b&gt;UserName Property in the UserContext.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Write another action method let's call it &lt;i&gt;&lt;b&gt;UserInfo &lt;/b&gt;&lt;/i&gt;which will retrieve the &lt;i&gt;&lt;b&gt;UserName Property from the UserContext object &lt;/b&gt;&lt;/i&gt;and display it on the UI&lt;/li&gt;&lt;li&gt;Write the &lt;i&gt;&lt;b&gt;RazorIndex view &lt;/b&gt;&lt;/i&gt;to show the &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;from the &lt;i&gt;&lt;b&gt;ViewBag&lt;/b&gt;&lt;/i&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Test that the setup is working with two different browser windows trying to &lt;i&gt;&lt;b&gt;Login &lt;/b&gt;&lt;/i&gt;and access the &lt;i&gt;&lt;b&gt;UserInfo &lt;/b&gt;&lt;/i&gt;at the same time.&amp;nbsp; We should see correct user names being displayed based on where the request is coming from&lt;/li&gt;&lt;/ul&gt;Lets look at individual steps in detail&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Register the &lt;i&gt;UserContext&lt;/i&gt; in Spring.NET configuration file with &lt;i&gt;scope="session"&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Update the web.xml and add the configuration for &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;as follows &lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;object type="aspnetwebFormsWithMvc3App.Context.UserContext, aspnetwebFormsWithMvc3App"               id="UserContext" scope="session" singleton="true"&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt; Notice that we have registered the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;object with &lt;i&gt;&lt;b&gt;scope="session".&lt;/b&gt;&lt;/i&gt;  Spring.NET will understand that the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;object is registered with &lt;i&gt;&lt;b&gt;singleton but in session scope &lt;/b&gt;&lt;/i&gt;i.e. &lt;span style="font-size: large;"&gt;One UserContext object per user session.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Write the implementation for the &lt;i&gt;UserContext&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;&lt;/b&gt;&lt;/i&gt;The &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;class would be simple enough.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// &lt;summary&gt;    /// The UserContext interface which has two simple methods     /// to set and get the UserName.    /// &lt;/summary&gt;    public interface IUserContext    {        /// &lt;summary&gt;        /// The method that will set the userName         /// into the UserName property.        /// &lt;/summary&gt;        /// &lt;param name="userName"&gt;The user name to set.&lt;/param&gt;       void SetUserName(string userName);        /// &lt;summary&gt;        /// The readonly property to get the         /// UserName held by the UserContext.        /// &lt;/summary&gt;        string UserName { get; }    }    public class UserContext : IUserContext    {        /// &lt;summary&gt;        /// This method does nothing just sets the UserName property         /// with the value passed in.        /// Although we could have exposed the UserName properties         /// setter as a public setter but        /// I preffer to expose it as a method.          /// In real life this method will set more properties         /// than just the UserName        /// &lt;/summary&gt;        /// &lt;param name="userName"&gt;The User name to set.&lt;/param&gt;        public void SetUserName(string userName)        {            UserName = userName;        }        /// &lt;summary&gt;        /// The auto property for the UserName.          /// Exposing the getter only.        /// &lt;/summary&gt;        public string UserName { get; private set; }    }]]&gt;&lt;/script&gt;&lt;b&gt;Register the AuthenticationController in Spring.NET configuration flie with singleton="false"&lt;/b&gt;.&amp;nbsp; &lt;b&gt;Add to this the dependency of UserContext&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Update the web.xml to add the configuration for AuthenticationController as follows.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;object type="aspnetwebFormsWithMvc3App.Controllers.AuthenticationController, aspnetwebFormsWithMvc3App"              singleton="false" id="Authentication"&gt;    &lt;property name="UserContext" ref="UserContext"/&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Write implementation of &lt;i&gt;Login Action &lt;/i&gt;to set the &lt;i&gt;UserName Property &lt;/i&gt;in the &lt;i&gt;UserContext&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt; &lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;AuthenticationController &lt;/b&gt;&lt;/i&gt;will have a &lt;i&gt;&lt;b&gt;Login Action &lt;/b&gt;&lt;/i&gt;and &lt;i&gt;&lt;b&gt;UserInfo Action&lt;/b&gt;&lt;/i&gt;.&amp;nbsp; &lt;i&gt;&lt;b&gt;Login Action&lt;/b&gt;&lt;/i&gt; will set the &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;in the &lt;i&gt;&lt;b&gt;UserContext.&amp;nbsp; &lt;/b&gt;&lt;/i&gt;For demonstration purpose we will append the &lt;i&gt;&lt;b&gt;SessionId &lt;/b&gt;&lt;/i&gt;to the &lt;i&gt;&lt;b&gt;UserName.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This will show us that, when we request the &lt;span style="font-size: large;"&gt;login action method from two different browser windows we will see different user name on the UI.&lt;/span&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// &lt;summary&gt;    /// The Authentication controller will have simple methods to set the     /// UserName in the UserContext and then show the UserInfo on the page.    /// &lt;/summary&gt;    public class AuthenticationController : Controller    {        /// &lt;summary&gt;        /// The UserContext Reference this object is a spring object         /// which will be singleton across one user session.  This means        /// each user session will have a different instance of         /// UserContext injected in them.        /// &lt;/summary&gt;        public IUserContext UserContext { get; set; }        /// &lt;summary&gt;        /// This Action method will set the User Name as         /// Git Shah with a sessionID added to it.          /// This is done to show that when,         /// requests are sent via two different threads         /// i.e. two different browser windows will generate         /// unique session ids would be generated        /// and unique UserNames will be set in UserContext object.        /// &lt;/summary&gt;        /// &lt;returns&gt;Redirects the user to UserInfo action.&lt;/returns&gt;        public ActionResult Login()        {            UserContext.SetUserName(                   "Git Shah With SessionID: " + Session.SessionID);            return RedirectToAction("UserInfo");        }        /// &lt;summary&gt;        /// This guy does simply gets the UserName property from the UserContext         /// and sets it in the ViewBag.          /// It then renders the RazorIndex view.        /// &lt;/summary&gt;        /// &lt;returns&gt;View called RazorIndex.          /// Which will show the user name on the page.&lt;/returns&gt;        public ActionResult UserInfo()        {            ViewBag.UserName = UserContext.UserName;            return View("RazorIndex");        }    }]]&gt;&lt;/script&gt;&lt;b&gt;Write the RazorIndex view to show the UserName from the ViewBag&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;&lt;b&gt;RazorIndex.cshtml &lt;/b&gt;&lt;/i&gt;will simply show the &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;from the &lt;i&gt;&lt;b&gt;ViewBag &lt;/b&gt;&lt;/i&gt;if its not null.  Else it will show no user logged in yet message.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;    &lt;title&gt;The MVC Page Using the Razor Syntax&lt;/title&gt;&lt;/head&gt;&lt;body&gt;    @if (ViewBag.UserName != null)    {        &lt;h1&gt;This is a page that is rendered via the Razor View Engine.                 Hello @ViewBag.UserName Welcome to MVC3!&lt;/h1&gt;    }    else     {         &lt;h1&gt;No User logged in yet!&lt;/h1&gt;    }&lt;/body&gt;&lt;/html&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Test that the setup is working with two different browser windows trying to login and access the &lt;i&gt;UserInfo &lt;/i&gt;at the same time&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Enough theory, lets see the setup in action.&amp;nbsp; As they say,&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Real test is in the real world!&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let's try and browse the URL &lt;i&gt;&lt;b&gt;Authentication&lt;/b&gt;&lt;b&gt;/UserInfo&lt;/b&gt;&lt;/i&gt; from FireFox and Internet Explorer and see what happens&lt;br /&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jPVVuJfq2Tk/Togq-aqs4SI/AAAAAAAABQQ/lccTb8HN6BI/s1600/userinfoWithoutUserNameSet.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-jPVVuJfq2Tk/Togq-aqs4SI/AAAAAAAABQQ/lccTb8HN6BI/s320/userinfoWithoutUserNameSet.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;User not logged in - FireFox&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-gd1VMAixDjY/Togq_AsMzTI/AAAAAAAABQU/HLABdH2x-Ok/s1600/userinfoWithoutUserNameSetIE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-gd1VMAixDjY/Togq_AsMzTI/AAAAAAAABQU/HLABdH2x-Ok/s320/userinfoWithoutUserNameSetIE.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;User not logged in -IE&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As the &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;is not set in &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;we see no user name set message.&lt;br /&gt;&lt;br /&gt;Now in IE, lets browse the URL &lt;i&gt;&lt;b&gt;Authentication/Login &lt;/b&gt;&lt;/i&gt;and see what happens.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-X95U0l9UZ3g/TogrAvcze5I/AAAAAAAABQc/MZm6PF0sRX8/s1600/UserNameWithSessionIdShownIE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://3.bp.blogspot.com/-X95U0l9UZ3g/TogrAvcze5I/AAAAAAAABQc/MZm6PF0sRX8/s320/UserNameWithSessionIdShownIE.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;User Successfully Logged in.&amp;nbsp; UserName and SessionID shown - IE &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As we can see, the page redirect to the &lt;i&gt;&lt;b&gt;Authentication/UserInfo&lt;/b&gt;&lt;/i&gt; User name with session id is shown.&lt;br /&gt;&lt;br /&gt;Lets reload the &lt;i&gt;&lt;b&gt;Authentication/UserInfo&lt;/b&gt;&lt;/i&gt; the page on FireFox.&amp;nbsp; Remember that, we have not yet visited the Login page on FireFox, but we have visited the Login page on IE.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jPVVuJfq2Tk/Togq-aqs4SI/AAAAAAAABQQ/lccTb8HN6BI/s1600/userinfoWithoutUserNameSet.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-jPVVuJfq2Tk/Togq-aqs4SI/AAAAAAAABQQ/lccTb8HN6BI/s320/userinfoWithoutUserNameSet.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Even after user is logged in on IE, he/she is not logged in on FireFox&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Yep even though we have set the &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;in the user session started from IE, it does not effect the &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;reference in the User Session started from FireFox.&lt;br /&gt;&lt;br /&gt;Now lets visit the &lt;i&gt;&lt;b&gt;Authentication/Login&lt;/b&gt;&lt;/i&gt; URL in FireFox as well to see what happens.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-rwoOIdBCrOY/Togq_9eWHCI/AAAAAAAABQY/ZskF8x08IUI/s1600/UserNameWithSessionIdShownFF.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://3.bp.blogspot.com/-rwoOIdBCrOY/Togq_9eWHCI/AAAAAAAABQY/ZskF8x08IUI/s320/UserNameWithSessionIdShownFF.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Now user is logged in even in FireFox&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As you can see it redirects to &lt;i&gt;&lt;b&gt;Authentication/UserInfo &lt;/b&gt;&lt;/i&gt;with &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;set.&amp;nbsp; Notice that the session id in FireFox window is different from the session id in IE.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-X95U0l9UZ3g/TogrAvcze5I/AAAAAAAABQc/MZm6PF0sRX8/s1600/UserNameWithSessionIdShownIE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://3.bp.blogspot.com/-X95U0l9UZ3g/TogrAvcze5I/AAAAAAAABQc/MZm6PF0sRX8/s320/UserNameWithSessionIdShownIE.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Notice that the Http SessionId are different in two images&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This effectively proves that &lt;i&gt;&lt;b&gt;UserContext &lt;/b&gt;&lt;/i&gt;reference plugged in by Spring.NET when request comes from IE is different from the one that gets plugged in when request comes in from FireFox i.e. &lt;span style="font-size: large;"&gt;We have successfully injected different &lt;i&gt;&lt;b&gt;UserContext&lt;/b&gt;&lt;/i&gt; reference per &lt;b&gt;&lt;i&gt;User Session&lt;/i&gt;&lt;/b&gt;.  UserContext object can now be used to hold any information that would have be placed in HTTP Session.  This effectively eliminates the use of HTTP Session and gets us a strongly typed object which can be used as a replacement to the HTTP Session.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's it!  we have successfully achieved Strongly Typed Session in an MVC3 application using Spring.NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-789698158169444714?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/789698158169444714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/10/strongly-typed-session-using-mvc3-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/789698158169444714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/789698158169444714'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/10/strongly-typed-session-using-mvc3-and.html' title='Strongly Typed Session Using MVC3 and Spring.NET - Part - 3'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-jPVVuJfq2Tk/Togq-aqs4SI/AAAAAAAABQQ/lccTb8HN6BI/s72-c/userinfoWithoutUserNameSet.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3272819103640337346</id><published>2011-09-27T05:00:00.000+05:30</published><updated>2011-10-02T15:28:34.824+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='strongly typed session'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='http session'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='application scope'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='session'/><category scheme='http://www.blogger.com/atom/ns#' term='session scope'/><title type='text'>Strongly Typed Session Using MVC3 And Spring.NET - Part - 2</title><content type='html'>In my &lt;a href="http://www.gitshah.com/2011/09/strongly-typed-session-with-mvc3-and.html"&gt;previous post&lt;/a&gt;, we saw why its a good idea to have strongly typed HTTP Session.  In this post we will do the real thing (well at least first part of the real thing).&lt;br /&gt;&lt;br /&gt;Using &lt;a href="http://www.springframework.net/"&gt;Sping.NET&lt;/a&gt; we can control the objects lifecycle.  By default the &lt;span style="font-size: large;"&gt;Objects configured in Spring.NET are Singleton for the entire application (singleton for scope="application").&lt;/span&gt;  Singleton for the entire application means, &lt;span style="font-size: large;"&gt;Spring.NET will create only one instance of the given object for the life-cycle of the application.&lt;/span&gt;&amp;nbsp; Service classes, DAO classes etc are a good fit for &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;Singleton Pattern&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;However, there are other &lt;a href="http://www.springframework.net/doc-latest/reference/html/web.html#web-objectscope"&gt;Object Scopes&lt;/a&gt; that can be configured in Spring.NET.&amp;nbsp; These Scope's tell Spring.NET that, &lt;span style="font-size: large;"&gt;A given object is singleton but in a given scope.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the interesting scope is &lt;b&gt;&lt;i&gt;session&lt;/i&gt;&lt;/b&gt;.&amp;nbsp; &lt;i&gt;&lt;b&gt;Session scope &lt;/b&gt;&lt;/i&gt;is only available &lt;i&gt;&lt;b&gt;if we use a web-aware Spring &lt;a href="http://www.springframework.net/doc/sdk/1.1/html/Spring.Core%7ESpring.Context.IApplicationContext.html"&gt;IApplicationContext&lt;/a&gt; implementation.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; For such objects, &lt;span style="font-size: large;"&gt;Spring.NET would create one instance per HTTP Session.&lt;/span&gt;&amp;nbsp; In this post we will see how we could take advante of the session scope, to create Strongly typed session in an MVC3 application.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enough blabber.&amp;nbsp; Let see how exactly its done.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do they do it!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As we had seen in one of the previous post to &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;Integrate Spring.NET with MVC3&lt;/a&gt; application, we had used the &lt;i&gt;&lt;b&gt;Spring.Context.Support.MvcContextHandler.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This class instantiates &lt;i&gt;&lt;b&gt;Spring.Context.Support.MvcApplicationContext&lt;/b&gt;&lt;b&gt;,&lt;/b&gt;&lt;/i&gt; which in turn initializes the spring application context.&lt;br /&gt;&lt;br /&gt;Support for &lt;i&gt;&lt;b&gt;session scope &lt;/b&gt;&lt;/i&gt;is porivded by &lt;i&gt;&lt;b&gt;spring.web.dll.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Unfortunately, &lt;span style="font-size: large;"&gt;as of Spring.NET 1.3.1, spring.web.mvc.dll does not depend on spring.web.dll, &lt;/span&gt;which effectively means, &lt;span style="font-size: large;"&gt;MvcApplicationContext is unaware of the session scope.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hence, using just the &lt;i&gt;&lt;b&gt;MvcApplicationContext &lt;/b&gt;&lt;/i&gt;there is no way we can eable the session scope for a certain objects.&amp;nbsp; Its a bug you can find more details &lt;a href="https://jira.springsource.org/browse/SPRNET-1450"&gt;here&lt;/a&gt;.&amp;nbsp; But where there is will, there is a way!&amp;nbsp; There is obviously a way around this problem.&lt;br /&gt;&lt;br /&gt;Here are the steps to enable full session scope support for any object in Spring.NET 1.3.1&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Update the &lt;i&gt;&lt;b&gt;web.config &lt;/b&gt;&lt;/i&gt;to use a custom &lt;i&gt;&lt;b&gt;WebContextHandler&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Register the spring &lt;i&gt;&lt;b&gt;WebSupportModule &lt;/b&gt;&lt;/i&gt;in &lt;i&gt;&lt;b&gt;web.config &lt;/b&gt;&lt;/i&gt;under the &lt;b&gt;&amp;lt;httpModule&amp;gt; section for IIS6 and under the &amp;lt;modules&amp;gt; section for IIS7+&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Implement the custom &lt;i&gt;&lt;b&gt;WebcontextHandler.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Override the property &lt;i&gt;&lt;b&gt;DefaultApplicationContextType.&amp;nbsp; &lt;/b&gt;&lt;/i&gt;This property informs Spring.NET about the class type of &lt;i&gt;&lt;b&gt;ApplicationContext &lt;/b&gt;&lt;/i&gt;that &lt;i&gt;&lt;b&gt;Spring.NET &lt;/b&gt;&lt;/i&gt;should instantiate.&amp;nbsp; This will be again a custom class that extends from &lt;i&gt;&lt;b&gt;Spring.Context.Support.MvcApplicationContext.&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Implement the custom class that inherits from &lt;i&gt;&lt;b&gt;Spring.Context.Support.MvcApplicationContext.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; This class will basically override two methods&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;CreateXmlObjectDefinitionReader&lt;/b&gt;&lt;/i&gt; to return the instance of &lt;i&gt;&lt;b&gt;WebObjectDefinitionReader&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;CreateObjectFactory&lt;/b&gt;&lt;/i&gt; to return the instance of &lt;i&gt;&lt;b&gt;WebObjectFactory&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;That's it!&amp;nbsp; We have now successfully enabled the session scope for Spring.NET 1.3.1.&amp;nbsp; Let look at the actual code. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 1 - Update the web.config to use a custom WebContextHandler&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Update the &lt;i&gt;&lt;b&gt;web.config configSection &lt;/b&gt;&lt;/i&gt;to look like &lt;br /&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;configsections&gt;    &lt;sectiongroup name="spring"&gt;      &lt;section name="context"        type="aspnetwebFormsWithMvc3App.Context.MvcWebContextHandler, aspnetwebFormsWithMvc3App"/&gt;    &lt;/sectionGroup&gt;  &lt;/configSections&gt;]]&gt;&lt;/script&gt;The class &lt;i&gt;&lt;b&gt;aspnetwebFormsWithMvc3App.Context.MvcWebContextHandler &lt;/b&gt;&lt;/i&gt;is our custom class where we will override the property &lt;i&gt;&lt;b&gt;DefaultApplicationContextType.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 2 - Register the spring WebSupportModule in web.config under the &amp;lt;httpModule&amp;gt; section for IIS6 and under the &amp;lt;modules&amp;gt; section for IIS7+&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Adding the spring module for IIS6 and IIS7&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;!-- IIS6 --&gt;&lt;system.web&gt;    &lt;httpmodules&gt;      &lt;add name="Spring"               type="Spring.Context.Support.WebSupportModule, Spring.Web" /&gt;    &lt;/httpModules&gt;&lt;/system.web&gt;&lt;!-- IIS7 --&gt;&lt;system.webServer&gt;    &lt;validation validateIntegratedModeConfiguration="false"/&gt;    &lt;modules runAllManagedModulesForAllRequests="true" &gt;        &lt;add name="Spring"                 type="Spring.Context.Support.WebSupportModule, Spring.Web"/&gt;    &lt;/modules&gt;&lt;/system.webServer&gt;]]&gt;&lt;/script&gt;&lt;b&gt;Step - 3 - Implement the custom WebcontextHandler&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Lets look at the custom &lt;b&gt;WebcontextHadler class aspnetwebFormsWithMvc3App.Context.MvcWebContextHandler &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class MvcWebContextHandler : MvcContextHandler    {        protected override Type DefaultApplicationContextType        {            get { return typeof(MvcWebApplicationContext); }        }                      }]]&gt;&lt;/script&gt;As you can see this class is pretty simple, it just overrides the property &lt;i&gt;&lt;b&gt;DefaultApplicationContextType &lt;/b&gt;&lt;/i&gt;to return the class type of custom &lt;i&gt;&lt;b&gt;WebApplicationContext.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 4 - Implement the custom class that inherits from Spring.Context.Support.MvcApplicationContext&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is the class where the real work is done.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class MvcWebApplicationContext : MvcApplicationContext    {        public MvcWebApplicationContext(string name,                                        bool caseSensitive,                                        params string[] configurationLocations)            : this(                     new MvcApplicationContextArgs(name,                                        null, configurationLocations,                                        null, caseSensitive))        { }        public MvcWebApplicationContext(string name,                                        bool caseSensitive,                                        IApplicationContext parentContext,                                        params string[] configurationLocations)            : this(new MvcApplicationContextArgs(name,                                        parentContext, configurationLocations,                                        null, caseSensitive))        { }        public MvcWebApplicationContext(MvcApplicationContextArgs args)            : base(args)        { }        public MvcWebApplicationContext(string name, bool caseSensitive,                                          string[] configurationLocations,                                          IResource[] configurationResources)            : this(new MvcApplicationContextArgs(name,                                          null, configurationLocations,                                          configurationResources, caseSensitive))        { }        public MvcWebApplicationContext(params string[] configurationLocations)            : this(new MvcApplicationContextArgs(string.Empty,                                           null, configurationLocations,                                           null, false))        { }        /// &lt;summary&gt;        /// Overriding the method CreateXmlObjectDefinitionReader          /// to return the instance of WebObjectDefinitionReader.        /// &lt;/summary&gt;        /// &lt;param name="objectFactory"&gt;        /// &lt;/param&gt;        /// &lt;returns&gt;&lt;/returns&gt;                protected override XmlObjectDefinitionReader                 CreateXmlObjectDefinitionReader(                        DefaultListableObjectFactory objectFactory)        {            return                     new WebObjectDefinitionReader(                                 GetContextPathWithTrailingSlash(),                                  objectFactory,                                  new XmlUrlResolver());        }        /// &lt;summary&gt;        /// Returning the instance of WebObjectFactory         /// so that it recognizes the session scope attribute.        /// &lt;/summary&gt;        /// &lt;returns&gt;&lt;/returns&gt;        protected override DefaultListableObjectFactory CreateObjectFactory()        {            return                     new WebObjectFactory(                                 GetContextPathWithTrailingSlash(),                                  IsCaseSensitive);        }        private string GetContextPathWithTrailingSlash()        {            string contextPath = Name;            if (contextPath == DefaultRootContextName)            {                contextPath = "/";            }            else            {                contextPath = contextPath + "/";            }            return contextPath;        }    }]]&gt;&lt;/script&gt;&lt;span style="font-size: large;"&gt;That's it! We have successfully enabled the session scope in MVC3 application using Spring.NET.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Question is: What is all this supposed to do with Strongly typed sessions?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the next and the final post in this series, we will see how we can take advantage of &lt;b&gt;session scoped objects &lt;/b&gt;to create the &lt;b&gt;Strongly Typed Session in an MVC3 application using Spring.NET.&amp;nbsp;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3272819103640337346?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3272819103640337346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/09/strongly-typed-session-using-mvc3-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3272819103640337346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3272819103640337346'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/09/strongly-typed-session-using-mvc3-and.html' title='Strongly Typed Session Using MVC3 And Spring.NET - Part - 2'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-2270975688744761452</id><published>2011-09-21T23:38:00.000+05:30</published><updated>2011-10-02T15:28:34.800+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='strongly typed session'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='http session'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='session'/><category scheme='http://www.blogger.com/atom/ns#' term='time bomb'/><title type='text'>Strongly typed Session with MVC3 and Spring.NET - Part - 1</title><content type='html'>In every Web project I have worked so far, always there is a need to store some or the other information in HTTP Session.&lt;br /&gt;&lt;br /&gt;I am very finicky about putting things in the HTTP Session.&amp;nbsp; IMHO HTTP Session should be kept as light as possible.&amp;nbsp; &lt;span style="font-size: large;"&gt;There should be a very very strong and compelling reason to put a certain value in the HTTP Session.&lt;/span&gt;&amp;nbsp; Having said that, I do agree that there are times when we want to put certain information in the HTTP Session like user name, user id, etc.&lt;br /&gt;&lt;br /&gt;With me so far?&amp;nbsp; Till now we understand that, &lt;span style="font-size: large;"&gt;we do not like to put things in HTTP Session, however, we understand that there is a definite need to put certain things in HTTP Session for the app to work correctly.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Question is, &lt;span style="font-size: large;"&gt;Is there an alternate to putting things in HTTP Session?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this series of three posts we will try to answer this question.&amp;nbsp; We will try to use MVC3 and Spring.NET to eliminate the need of putting stuff in HTTP Session.&lt;br /&gt;&lt;br /&gt;But wait a minute, let's first answer this question,&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why is putting things in HTTP Session is such a bad idea?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Lets start by looking at the code that will put UserName into the HTTP Session.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[Session["UserName"] = "Git Shah";]]&gt;&lt;/script&gt;Does it remind you of code that you have seen in one of your applicatoin?  It certainly reminds me of code that is used all over the place in one of the projects that I had worked.&lt;br /&gt;&lt;br /&gt;I totally hate to see code like this.&amp;nbsp; &lt;b&gt;Why whats wrong with such code?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Session is used like a Hash Table: &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In our example, key of the hash table would be &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; and value will be &lt;i&gt;&lt;b&gt;Git Shah&lt;/b&gt;&lt;/i&gt;.&amp;nbsp; Imagine while putting/retrieving values to/from the HTTP Session, if incorrect keys are used, results could be catastrophic.&amp;nbsp; Even a small typo like one shown in the example below would yield incorrect results&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[Session["UserName"] = "Git Shah";var userName = Session["userName"];]]&gt;&lt;/script&gt;Ofcourse there are ways to get around this problem.  Simplest of them is to use a Static Class that holds all the keys as constants.&lt;br /&gt;&lt;br /&gt;However, you can still not gaurentee that every programmer on your team will always always use constant keys from the static class.&amp;nbsp; Believe me, &lt;span style="font-size: large;"&gt;because of human error or some other unexplainable reason, someone would use hardcoded inline key to put value in the Session and rest of the team will curse him/her for eternity!&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Session values are not strongly typed:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;We have inserted a string value &lt;i&gt;&lt;b&gt;Git Shah&lt;/b&gt;&lt;/i&gt; in the HTTP Session against the key &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; but when we want to retrieve the value from the session we will have to typecast to its correct type.&amp;nbsp; In our example to retrieve the value of &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;key in HTTP Session code would look like&lt;/span&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[string userName = (string)Session["UserName"];]]&gt;&lt;/script&gt;I have a name for code like that, I call it &lt;span style="font-size: large;"&gt;A Time Bomb!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Its just a matter of time before which you start getting a class cast exception.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dude, whats in my Session? Where are these values used? &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Can we say for sure what all values are stored in our session?&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another important question to answer is, &lt;span style="font-size: large;"&gt;Can we say for sure, from what all places in the code are these values accessed?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;These are a very important questions.&amp;nbsp; Answers to these questions are absolutely vital for the health of your application.&lt;br /&gt;&lt;br /&gt;In one of the projects that I had worked, we were extremely confused for a very long period of time.&amp;nbsp; The question that was bothering us was, &lt;span style="font-size: large;"&gt;who was setting a specific value in the session and in what condition?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Consider an example&lt;br /&gt;&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// Login controller that will be used to login the user.     public class LoginController : Controller    {		        /// A very simple login method that sets the         /// UserName property in the http session        /// to the value that user has passed in.          /// This is the first place where the Session is populated.        public ActionResult Login(FormCollection formCollection)        {            Session["UserName"] = formCollection["UserName"];            return View();        }		    }]]&gt; &lt;/script&gt;&lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key is populated in the &lt;i&gt;&lt;b&gt;LoginController.Login method&lt;/b&gt;&lt;/i&gt;.  Lets look at another place where &lt;i&gt;&lt;b&gt;UserName &lt;/b&gt;&lt;/i&gt;is used.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[	/// Account controller that will be used to update user profile.	public class AccountController : Controller 	{		/// A very simple update user method that updates the 		/// UserName property in the http session		/// to the value that is passed as argument.  		/// This is the second place where the Session is populated.		public ActionResult UpdateUser(string userName)		{			Session["UserName"] = userName;			return View();            		}				/// Method that uses the UserName 		/// from the session to populate in the ViewBag.		/// View can then access the ViewBag 		/// to show the value of the UserName.		public ActionResult GetUserDetails() 		{			ViewBag.UserName = Session["UserName"];			return View();		}	}]]&gt;&lt;/script&gt;&lt;i&gt;&lt;b&gt;AccoutController.UpdateUser&lt;/b&gt;&lt;/i&gt; updates the value of the &lt;i&gt;&lt;b&gt;UserName key &lt;/b&gt;&lt;/i&gt;in the HTTP Session to the new value passed as argument and &lt;i&gt;&lt;b&gt;AccountController.GetUserDetails &lt;/b&gt;&lt;/i&gt;method fetches the value of the &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key from the HTTP Session and sets the &lt;i&gt;&lt;b&gt;ViewBag.UserName &lt;/b&gt;&lt;/i&gt;property.&lt;br /&gt;&lt;br /&gt;As you can see in our simplistic example &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key of the HTTP Session is used at three places.&amp;nbsp; In real life, it would be used in many more places than this.&amp;nbsp; The code that accesses the &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key from the HTTP Session would be littered all over the place!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;How will we find the exact places where &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key is populated/fetched into/from the HTTP Session?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is no easy way to find the exact places where &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; key of the HTTP Session is used.&amp;nbsp; We can extract a constant for the &lt;i&gt;&lt;b&gt;UserName&lt;/b&gt;&lt;/i&gt; and then search for its usages, but still this is not a full proof way, as I mentioned earlier, there are many fools out there who will not bother to use the constant and use an Hardcoded string key instead.&lt;br /&gt;&lt;br /&gt;These are few of the problems that are a big concern to me.&amp;nbsp; Question to be answered is,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How can we avoid such code?&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;How can we achieve an alternate option that will discourage people from writing such code?&lt;/li&gt;&lt;/ul&gt;Before we dig deeper into the solution, lets first focus on some of the design goals that this new solution should have. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Things that we put into and fetch from the session should be strongly typed objects.&lt;/span&gt;&amp;nbsp; There should not be any cast of any sort.&amp;nbsp; This will avoid &lt;b&gt;Time Bomb &lt;/b&gt;like code.&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Session should not be used as a Hash Table.&lt;/span&gt;&amp;nbsp; Whatever we put into the session should become a property of the session which can be accessed from anywhere in the code.&amp;nbsp; Moreover, because it becomes a property of the HTTP Session, we would get all sorts of intelli-sense on it.&amp;nbsp; There is no chance of any typo in this case.&amp;nbsp; For e.g. the existing code&lt;/li&gt;&lt;/ul&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[Session["UserName"] = "Git Shah";string userName = (string) Session["UserName"];]]&gt;&lt;/script&gt;Should no longer be required instead we should have code that looks like&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[Session.UserName = "Git Shah";string userName = Session.UserName;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;At any point in time, it should be easy enough to find the exact places where a certain property of HTTP Session is used.  In some ways this point is related to the previous point.  If we are able to convert Keys of session into strongly typed Properties then we can just search for the usages of those properties and we know exactly where those properties were used!&lt;/li&gt;&lt;/ul&gt;Enough goals to start with.&amp;nbsp; Question is, &lt;span style="font-size: large;"&gt;Can these goals be implemented in real life?&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Well, the good news is, these goals are definitely implementable.&lt;/span&gt;&amp;nbsp; In fact its not too difficult to implement these goals when we use Spring.NET with MVC3.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is the bad news?&lt;/b&gt;&amp;nbsp; You will have to wait for my next posts to see how exactly we could implement these goals :)&lt;br /&gt;&lt;br /&gt;Stay tuned folks in the next couple of posts we are going to have some fun with HTTP Session Management!&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-2270975688744761452?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/2270975688744761452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/09/strongly-typed-session-with-mvc3-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2270975688744761452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2270975688744761452'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/09/strongly-typed-session-with-mvc3-and.html' title='Strongly typed Session with MVC3 and Spring.NET - Part - 1'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-1748678907138447792</id><published>2011-09-20T23:08:00.000+05:30</published><updated>2011-09-20T23:14:33.532+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='stored procedures'/><category scheme='http://www.blogger.com/atom/ns#' term='enlist transaction'/><category scheme='http://www.blogger.com/atom/ns#' term='stored procedure with out parameters'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='out parameters'/><category scheme='http://www.blogger.com/atom/ns#' term='legacy database'/><category scheme='http://www.blogger.com/atom/ns#' term='output parameters'/><title type='text'>Calling a Stored Procedure with OUT parameters using NHibernate</title><content type='html'>&lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;/&lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt; is one product that I appreciate a lot.&amp;nbsp; I absolutely love the flexibility that NHibernate offers.&lt;br /&gt;&lt;br /&gt;Lots of &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt; products out there work well when we are developing application from scratch, however they fail miserable when we have to work with existing legacy database.&amp;nbsp; Hibernate/NHibernate on other end, works very well when application are build from scratch as well as when we have to work with legacy database.&amp;nbsp; Hibernate/NHibernate provides lots of hooks because of which, using it with any legacy database is completely painfree.&lt;br /&gt;&lt;br /&gt;In this post, we are going to see how we could use NHibernate to get around one such legacy issue.&amp;nbsp; One of the common technique employed in legacy databases to exchange information between the DB and Application layer is, having stored procedures with OUT parameters.&amp;nbsp; OUT parameters are special type of parameters in which the stored procedure returns values which can then be accessed by the Application layers.&lt;br /&gt;&lt;br /&gt;We will not go into details whether OUT parameters are good or bad but, we will see how exactly we could use NHibernate to invoke stored procedures with OUT parameters. &lt;br /&gt;&lt;br /&gt;Calling stored procedures without any OUT parameters using NHibernate is fairly straight forward, but calling stored procedures having OUT parameters using NHibernate is a bit tricky.&amp;nbsp; Without wasting any more time lets straight away dive into the solution. &lt;br /&gt;&lt;b&gt;How do they do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To call stored procedures with OUT parameters we have to fallback to the System.Data.SqlClient.SqlCommand (assuming that the database is MSSQL) to get the job done.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Let's say that,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We have a stored procedure called &lt;b&gt;&lt;i&gt;encrypt&lt;/i&gt;&lt;/b&gt; that is supposed to encrypt any string&lt;/li&gt;&lt;li&gt;It takes INPUT parameter called &lt;i&gt;&lt;b&gt;stringToEncrypt&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;It returns the encrypted string as an OUTPUT parameter called &lt;i&gt;&lt;b&gt;encryptedValue&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;We want to invoke this stored procedure using NHibernate.&amp;nbsp; The steps to do this would be as follows&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Get an instance of &lt;b&gt;&lt;i&gt;Session using the NHibernateSessionFactory&lt;/i&gt;&lt;/b&gt; (or get it some how injected into the DAO class using Dependency Injection)&lt;/li&gt;&lt;li&gt;Start the &lt;i&gt;&lt;b&gt;transaction on the NHibernate session using BeginTransaction method&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Create a &lt;i&gt;&lt;b&gt;new instance of System.Data.SqlClient.SqlCommand &lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Set the &lt;i&gt;&lt;b&gt;Connection &lt;/b&gt;&lt;b&gt;property of the &lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;SqlCommand instance using the NHibernate Session's Connection property&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Set the &lt;i&gt;&lt;b&gt;SqlCommand instances CommandType property as CommandType.StoredProcedure&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Set the &lt;i&gt;&lt;b&gt;SqlCommand instances CommandText property &lt;/b&gt;&lt;/i&gt;as the stored procedure name, in our case &lt;i&gt;&lt;b&gt;encrypt&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the &lt;i&gt;&lt;b&gt;INPUT parameter to the SqlCommand instance.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; In our case, adding the &lt;i&gt;&lt;b&gt;parameter with name stringToEncrypt and setting the value of the parameter to the string we want to encrypt&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the &lt;i&gt;&lt;b&gt;OUTPUT parameter to the SqlCommand instance with Direction property set to ParameterDirection.Output.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; In our case, &lt;i&gt;&lt;b&gt;add the parameter encryptedValue.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; Since, this is an output parameter we will have to specify its &lt;i&gt;&lt;b&gt;SqlDbType as SqlDbType.NVarChar and size as 255.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; But the most important thing here is, &lt;span style="font-size: large;"&gt;&lt;i&gt;&lt;b&gt;to set the Direction property of SqlParameter to ParameterDirection.Output.&lt;/b&gt;&lt;b&gt;&amp;nbsp; This tells the SqlCommand that this parameter is an output parameter.&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&amp;nbsp; After executing the stored procedure we will be able to get the value out of this parameter.&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;&lt;i&gt;&lt;b&gt;Enlist the SqlCommand instance with the NHibernate transaction.&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&amp;nbsp; This is another crucial step.&amp;nbsp; &lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;If this is not done SqlCommand will throw an error saying "ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction.&amp;nbsp; The Transaction property of the command has not been initialized"&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Execute the command using &lt;i&gt;&lt;b&gt;ExecuteNonQuery method &lt;/b&gt;&lt;/i&gt;on the command instance.&lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Get the &lt;i&gt;&lt;b&gt;output parameter value from the &lt;/b&gt;&lt;b&gt;SqlCommand instance&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Commit the &lt;i&gt;&lt;b&gt;NHibernate transaction &lt;/b&gt;&lt;/i&gt;and &lt;i&gt;&lt;b&gt;Close the NHibernate Session.&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;As you can see there are quite some steps involved while invoking a stored procedure with OUT parameters.&amp;nbsp; But looking at the code would definately make things easier.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[        public void ShouldEncryptTheValue()        {		   //Getting the instance of session factory using,		   //the NHibernateSessionHelper custom class.  		   //This step could be different in your case.		   //May be the session factory gets injected in some way.           ISessionFactory sessionFactory = NHibernateSessionHelper.GetSessionFactory();						//Step - 1 - Opening a NHibernate session using the session factory.            var session = sessionFactory.OpenSession();						//Step - 2 - Starting the NHibernate transaction.            session.BeginTransaction();						//Step - 3 - Creating an instance of SqlCommand            IDbCommand command = new SqlCommand();						//Step - 4 - Setting the connection property of the command instance 			//with NHibernate session's Connection property.            command.Connection = session.Connection;						//Step - 5 - Setting the CommandType property 			//as CommandType.StoredProcedure            command.CommandType = CommandType.StoredProcedure;						//Step - 6 - Setting the CommandText to the name 			//of the stored procedure to invoke.            command.CommandText = "encrypt";            //Step - 7 - Set input parameter, 			//in our case its "@stringToEncrypt" with the value to encrypt, 			//in our case "Hello World"            command.Parameters.Add(new SqlParameter("@stringToEncrypt", "Hello World"));            //Step - 8 - Set output parameter, in our case "encryptedValue".  			//Notice that we are specifying the parameter type as second argument 			//and its size as the third argument to the constructor.  			//The Direction property is initialized in the initialization block 			//with ParameterDirection.Output.            SqlParameter outputParameter = 				new SqlParameter("@encryptedValue", SqlDbType.VarChar, 255)							   {								   Direction = ParameterDirection.Output							   };            command.Parameters.Add(outputParameter);			//Step - 9 - Enlisting the command with the NHibernate transaction.            session.Transaction.Enlist(command);			            //Step - 10 - Executing the stored procedure.            command.ExecuteNonQuery();			//Step - 11 - Getting the value set by the stored procedure 			//in the output parameter.            var encryptedValue = 				((SqlParameter)command.Parameters["@encryptedValue"]).Value.ToString();            Console.WriteLine(encryptedValue);						//Step - 12 - Cleanup.  Committing the NHibernate Transaction 			//and closing the NHibernate session.            session.Transaction.Commit();            session.Close();        }]]&gt;&lt;/script&gt;And that is how its done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-1748678907138447792?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/1748678907138447792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/09/calling-stored-procedure-with-out.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/1748678907138447792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/1748678907138447792'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/09/calling-stored-procedure-with-out.html' title='Calling a Stored Procedure with OUT parameters using NHibernate'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-6141178886827116651</id><published>2011-09-05T19:39:00.000+05:30</published><updated>2011-09-05T19:39:28.155+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='fixing'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual path'/><title type='text'>Fixing the The virtual path '/test/currentcontext.dummy' maps to another application, which is not allowed</title><content type='html'>We have recently integrated &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; in an &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3&lt;/a&gt; application.&amp;nbsp; In one of my &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt;, I have already documented the detailed process of integrating Spring.NET with MVC3 application.&amp;nbsp; Spring.NET is really helpful when it comes to writing Modular, Testable code.&amp;nbsp; I totally recommend Spring.NET as Dependency Injection framework of choice!&lt;br /&gt;&lt;br /&gt;We did a fresh deployment of our application on a new server.&amp;nbsp; On this computer, when we tried to access any of the pages of our application we got an error which looked like&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-VQuX2rpp8fU/TmTG9soPGRI/AAAAAAAABQI/mTQdBNSzI6M/s1600/The+virtual+path+%2527-test-currentcontext.dummy%2527+maps+to+another+application%252C+which+is+not+allowed._1312100508770.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="110" src="http://3.bp.blogspot.com/-VQuX2rpp8fU/TmTG9soPGRI/AAAAAAAABQI/mTQdBNSzI6M/s320/The+virtual+path+%2527-test-currentcontext.dummy%2527+maps+to+another+application%252C+which+is+not+allowed._1312100508770.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Virtual Path Maps to Another Application, is not allowed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;That was not very encouraging.&amp;nbsp; How can an application that was working correctly on all other servers stared giving exceptions for this particular server?&lt;br /&gt;&lt;br /&gt;We tried to find out what were the differences between the other server and this new server.&amp;nbsp; We narrowed it down to one very interesting difference,&amp;nbsp; we used to deploy our project as a website in &lt;a href="http://www.iis.net/"&gt;IIS&lt;/a&gt; on all other server.&amp;nbsp; While on the server that was giving us exceptions, we deployed our application as a virtual directory under the default website.&amp;nbsp; This very curious difference was giving us exceptions while initializing the spring context.&lt;br /&gt;&lt;br /&gt;I Googled a little and found out that this is a known issue which has been reported &lt;a href="https://jira.springsource.org/browse/SPRNET-921"&gt;here&lt;/a&gt; and &lt;a href="https://jira.springsource.org/browse/SPRNET-561"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The workaround to this issue was simple enough, we just have to give a name the spring context in &lt;i&gt;web.config&lt;/i&gt;.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Would any random name work?&amp;nbsp; Do we have to follow some convention?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Our Spring.NET section in web.config file looked like&lt;/i&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;spring&gt;    &lt;parsers&gt;      &lt;parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" /&gt;      &lt;parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" /&gt;    &lt;/parsers&gt;    &lt;context&gt;      &lt;resource uri="~/Config/web.xml" /&gt;    &lt;/context&gt;  &lt;/spring&gt;]]&gt;&lt;/script&gt;By now it should be clear that, &lt;b&gt;we have to add a name attribute to &lt;/b&gt;&lt;context&gt;&lt;b&gt; node&lt;/b&gt;.  But the question is, &lt;b&gt;what value should it hold?&lt;/b&gt;&lt;/context&gt;&lt;br /&gt;&lt;br /&gt;&lt;context&gt;The answer is pretty simple, the Spring.NET context should be named after the virtual directory under which the application is deployed.&amp;nbsp; For example, if the virtual directory under which the application is deployed is called &lt;i&gt;springmvc&lt;/i&gt;.&amp;nbsp; The updated &lt;i&gt;web.config &lt;/i&gt;should look like&lt;/context&gt;&lt;br /&gt;&lt;context&gt;&lt;/context&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;spring&gt;    &lt;parsers&gt;      &lt;parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" /&gt;      &lt;parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" /&gt;    &lt;/parsers&gt;    &lt;context name="springmvc"&gt;      &lt;resource uri="~/Config/web.xml" /&gt;    &lt;/context&gt;  &lt;/spring&gt;]]&gt;&lt;/script&gt;This did the trick!  After making this change we were able to browse all pages in our application and Spring.NET integration with MVC3 application was working well!&lt;br /&gt;&lt;br /&gt;Small issues like these have very simple solutions but, one might end up spending quite some time before finding a satisfactory solution.&amp;nbsp; I decided to document my finding for the benefit of the community! &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-6141178886827116651?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/6141178886827116651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/09/fixing-the-virtual-path.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6141178886827116651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6141178886827116651'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/09/fixing-the-virtual-path.html' title='Fixing the The virtual path &apos;/test/currentcontext.dummy&apos; maps to another application, which is not allowed'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-VQuX2rpp8fU/TmTG9soPGRI/AAAAAAAABQI/mTQdBNSzI6M/s72-c/The+virtual+path+%2527-test-currentcontext.dummy%2527+maps+to+another+application%252C+which+is+not+allowed._1312100508770.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3508583156557166429</id><published>2011-08-28T22:14:00.005+05:30</published><updated>2011-08-28T22:29:43.248+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='NHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating NHibernate with MVC3'/><category scheme='http://www.blogger.com/atom/ns#' term='Fluent API'/><title type='text'>Integrating NHibernate with Spring.NET and MVC3</title><content type='html'>We have seen in one of the &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt; that its not very difficult to integrate &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; with &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3 &lt;/a&gt;application.&amp;nbsp; Almost every real project has a need to talk to a database for doing stuff.&amp;nbsp; When it comes to interacting with the Database, &lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt; does an Awesome job.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;I have used NHibernate with legacy database as well as databases that were designed from scratch.&amp;nbsp; IMHO, other competing products have a long way to catchup before they can be compared with the flexibility that NHibernate offers!&lt;br /&gt;&lt;br /&gt;Recently, in one of MVC3 project we integrated NHibernate using the &lt;a href="http://fluentnhibernate.org/"&gt;Fluent API&lt;/a&gt; with Spring.NET.&amp;nbsp; This process is not very difficult but it involves a few steps.&amp;nbsp; I decided to document the steps for the benefit of the community.&lt;br /&gt;&lt;br /&gt;We will continue from where we left in the &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt;, if you did not read the &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt; already then, I strongly recommend reading it to understand &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;how you can integrate Spring.NET with MVC3 application&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Very well than, Lets start!&lt;br /&gt;&lt;br /&gt;To integrate NHibernate using the Fluent API in a Spring.NET MVC3 application one has to do the following&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make the &lt;i&gt;Web.config &lt;/i&gt;changes to include the &lt;i&gt;Parsers config section &lt;/i&gt;in the &lt;i&gt;spring configuration.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Register the &lt;a href="http://www.springframework.net/docs/1.3.0-RC1/api/net-2.0/html/Spring.Data.NHibernate21%7ESpring.Data.NHibernate.Support.OpenSessionInViewModule.html"&gt;OpenSessionInView&lt;/a&gt; &lt;i&gt;HTTP Module in web.config&lt;/i&gt;.&amp;nbsp; We will be using single session per request, NHibernate session handling strategy.&lt;i&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the reference to the required DLL's&lt;/li&gt;&lt;li&gt;Register the &lt;i&gt;DB provider&lt;/i&gt; in the &lt;i&gt;spring configuration file&lt;/i&gt;.&lt;i&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Register the &lt;i&gt;NHibernate Session Factory&lt;/i&gt; in the &lt;i&gt;spring configuration file&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Write a custom implementation of the &lt;i&gt;NHibernate Session Factory&lt;/i&gt; that loads and registers the Assembly that has Fluent NHibernate mappings in it.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Register the &lt;i&gt;Transaction Manager&lt;/i&gt; in the &lt;i&gt;spring configuration file&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Enable the &lt;i&gt;Spring AOP Transactions&lt;/i&gt; using attributes in the &lt;i&gt;spring configuration file&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Test out the NHibernate integration&lt;/li&gt;&lt;/ul&gt;Lets execute the steps one by one.&amp;nbsp; Please remember I will be continuing from where I left in the &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt;.&amp;nbsp; Hence, I will be assuming that you already have Spring.NET correctly integrated in your MVC3 application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 1 - Make the Web.config changes to include the Parsers config section in the spring configuration&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To integrate only Spring.NET with MVC3 application we had to add a &lt;i&gt;configurationSection called context&lt;/i&gt;.&amp;nbsp; To integrate NHibernate with Spring.NET in a MVC3 application we have to add another &lt;i&gt;configurationSection called parser&lt;/i&gt;.&amp;nbsp; This section will help Spring.NET understand the Database and Transaction configuration.&amp;nbsp; Lets look at how its done.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;configsections&gt;    &lt;sectiongroup name="spring"&gt;      &lt;section name="context" type="dispatchOfficeWeb.MvcAppCode.Context.Impl.MvcWebContextHandler, dispatchOfficeWeb"/&gt;      &lt;!-- Adding another section for the parsers            so that Spring.NET can understand the database            and transaction configuration in spring config files --&gt;      &lt;section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/&gt;    &lt;/sectionGroup&gt;  &lt;/configSections&gt;  &lt;!-- Integrate Spring.NET with NHibernate --&gt;  &lt;spring&gt;    &lt;parsers&gt;      &lt;!-- Registering the parsers for            DatabaseNamespace and TransactionNamespace  --&gt;      &lt;parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/&gt;      &lt;parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/&gt;    &lt;/parsers&gt;    &lt;context name="dispatchOfficeWeb"&gt;      &lt;resource uri="~/Config/web.xml"/&gt;    &lt;/context&gt;  &lt;/spring&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;Step - 2 - Register the OpenSessionInViewModule HTTP Module in web.config.  We will be using single session per request, NHibernate session handling strategy&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why do we need the OpenSessionInViewModule HTTP Module?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This will ensure that before &lt;span style="font-size: large;"&gt;the request is processed by any Controller, NHibernate session is opened and attached to the current thread.&lt;/span&gt;&amp;nbsp; And just before sending the response to the client, &lt;span style="font-size: large;"&gt;the NHibernate Session will be flushed and closed.&amp;nbsp; This enables us to do lazy loading even when the View is being rendering.&lt;/span&gt;&amp;nbsp; Lets look at the web.config change required to enable this:&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;system.web&gt;    &lt;!-- Registering OpenSessionInView HttpModule in the system.web sesction.  	 This will ensure that a session is opened when the request first comes to          the server and closed just before the response is sent to the client.  --&gt;    &lt;httpmodules&gt;      &lt;add name="OpenSessionInView"         type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate30"/&gt;    &lt;/httpModules&gt;  &lt;/system.web&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;Step - 3 - Add the reference to the required DLL's&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For integrating NHibernate with Spring.NET and MVC3 application we need to add the references of following spring DLL's&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spring.AOP.dll -&amp;gt; Used to enable AOP using Spring.NET.&amp;nbsp; This will be heavily used when we enable transactions in our application.&lt;/li&gt;&lt;li&gt;Spring.Data.dll -&amp;gt; Used to enable the Spring.NET Database module&lt;/li&gt;&lt;li&gt;Spring.Data.NHibernate30.dll -&amp;gt; Used to integrate Spring.NET with NHibernate&lt;/li&gt;&lt;li&gt;NHibernate.dll -&amp;gt; The core NHibernate DLL&lt;/li&gt;&lt;li&gt;Iesi.Collections.dll -&amp;gt; Provides the ISet interface and its implementation&lt;/li&gt;&lt;li&gt;FluentNHibernate.dll -&amp;gt; Used to enable FluentNhibernate configuration for NHibernate&lt;/li&gt;&lt;li&gt;log4net.dll -&amp;gt; Used by NHibernate for logging.&amp;nbsp; &lt;span style="font-size: large;"&gt;Lot of effort has been put into making the NHibernate log as detail as possible and as readable as possible.&amp;nbsp; This is a great tool when it comes to debugging something that you cannot understand easily&lt;/span&gt; &lt;/li&gt;&lt;li&gt;NHibernate.ByteCode.Castle.dll -&amp;gt; Used by NHibernate to enable Dynamic Proxies&lt;/li&gt;&lt;li&gt;Castle.Core.dll -&amp;gt; Used by NHibernate to enable Dynamic Proxies using Castle&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Step - 4 - Register the DB provider in the spring configuration file&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;This step is pretty simple.&amp;nbsp; We need to inform NHibernate about the Database.&amp;nbsp; This is done by registering a &lt;i&gt;DbProvider in the spring configuration file&lt;/i&gt;.&amp;nbsp; We will be registering the &lt;i&gt;DbProvider in the web.xml &lt;/i&gt;(web.xml was the file we created in the &lt;a href="http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html"&gt;previous post&lt;/a&gt;.&amp;nbsp; This hold all the Spring.NET configuration).&amp;nbsp; Add following configuration to the web.xml&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;objects xmlns="http://www.springframework.net"         xmlns:db="http://www.springframework.net/database"&gt;  &lt;!-- Default Database Configuration --&gt;  &lt;db:provider id="DbProvider"   provider="System.Data.SqlClient"   connectionString=   "Data Source=localhost;Database=my_db;User ID=sa;Password=password;"/&gt;				     &lt;!-- Existing configuration entries come after this line.         Not showing them for the sake of simplicity. --&gt;&lt;/objects&gt;			]]&gt;&lt;/script&gt;&lt;br /&gt;Notice that we have to define the db name space in the &lt;i&gt;objects root tag&lt;/i&gt;.  Please update the above configuration with the DB Credentials that you are using.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 5 - Register the NHibernate session Factory in the spring configuration file&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Session Factory is a heavy weight NHibernate object.&amp;nbsp; &lt;span style="font-size: large;"&gt;Only one instance of SessionFactory is create per database.&lt;/span&gt;&amp;nbsp; Lets look at the Spring.NET configuration file for registering the NHibernate Session Factory.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;!-- NHibernate Configuration Session Factory --&gt;  &lt;object id="SessionFactory"type="aspnetwebFormsWithMvc3App.NHibernate.FluentNhibernateLocalSessionFactoryObject, aspnetwebFormsWithMvc3App"&gt;    &lt;property name="DbProvider" ref="DbProvider"/&gt;    &lt;property name="FluentNhibernateMappingAssemblies"&gt;      &lt;list&gt;        &lt;value&gt;aspnetwebFormsWithMvc3App&lt;/value&gt;      &lt;/list&gt;    &lt;/property&gt;    &lt;property name="MappingAssemblies"&gt;      &lt;list&gt;        &lt;value&gt;aspnetwebFormsWithMvc3App&lt;/value&gt;      &lt;/list&gt;    &lt;/property&gt;    &lt;property name="HibernateProperties"&gt;      &lt;dictionary&gt;        &lt;entry key="hibernate.connection.provider"                value="NHibernate.Connection.DriverConnectionProvider"/&gt;        &lt;entry key="dialect"                value="NHibernate.Dialect.MsSql2005Dialect"/&gt;        &lt;entry key="connection.driver_class"                value="NHibernate.Driver.SqlClientDriver"/&gt;        &lt;entry key="show_sql" value="false" /&gt;      &lt;/dictionary&gt;    &lt;/property&gt;    &lt;!-- provides integration with Spring's          declarative transaction management features --&gt;    &lt;property name="ExposeTransactionAwareSessionFactory" value="true" /&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The above configuration registers a NHibernate session factory which is of type &lt;b&gt;aspnetwebFormsWithMvc3App.NHibernate.FluentNhibernateLocalSessionFactoryObject &lt;/b&gt;and is found in the assembly &lt;b&gt;aspnetwebFormsWithMvc3App.&lt;/b&gt;&amp;nbsp; This is a custom class that we will create later in the post.&amp;nbsp; It has various properties like&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Which DbProvider to use&lt;/li&gt;&lt;li&gt;What are the FluentNhibernateMappingAssemblies.&amp;nbsp; This is a list of assembly names which our NHibernate Session factory class will search for to locate Fluent Nhibernate mappings&lt;/li&gt;&lt;li&gt;What are the MappingAssemblies.&amp;nbsp; This is a list of assembly names which has normal NHibernate mappings&lt;/li&gt;&lt;li&gt;What are the HibernateProperties.&amp;nbsp; These are the key value pairs of NHibernate properties that we would want to use.&amp;nbsp; We are setting the connection provider, dialect, driver_class and sql_sql values&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Step - 6 - Write a custom implementation of the NHibernate session factory that loads and registers the Assembly that has Fluent NHibernate mappings in it&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;We have to provide a custom implementation of NHibernate Session Factory class so that we could load our Fluent NHibernate assemblies.&amp;nbsp; These assemblies will have the Fluent NHibernate mapping classes.&amp;nbsp; The code of our Custom NHibernate Session Factory looks like this&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class FluentNhibernateLocalSessionFactoryObject : LocalSessionFactoryObject    {        /// &lt;summary&gt;        /// Sets the assemblies to load that contain fluent NHibernate mappings.        /// &lt;/summary&gt;        /// &lt;value&gt;The mapping assemblies.&lt;/value&gt;        public string[] FluentNhibernateMappingAssemblies { get; set; }        /// &lt;summary&gt;        /// This method will be called after the configuration is processed         /// but before the session factory is created.          /// Adding the assembly mappings for the         /// Fluent NHibernate mapping assemblies to the config object.        /// This is done so that later when the session factory is created        /// Using the updated configuration it will have         /// Fluent NHibernate mappings registered in it.        /// &lt;/summary&gt;        /// &lt;param name="config"&gt;        /// The configuration object that holds the NHibernate configuration.        /// &lt;/param&gt;        protected override void PostProcessConfiguration(Configuration config)        {            base.PostProcessConfiguration(config);            if (FluentNhibernateMappingAssemblies == null) return;            foreach (string assemblyName in FluentNhibernateMappingAssemblies)            {                // Loading the assembly by name and                 // then adding it as the Mapping assembly.                config.AddMappingsFromAssembly(Assembly.Load(assemblyName));            }        }    }]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;Step - 7 - Register the Transaction manager in the spring configuration file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;NHibernate always interacts with the database using Transactions.&amp;nbsp; We would definitely want to control how and when the transactions are started and ended.&amp;nbsp; For that to happen we need to register the transaction manager in the spring configuration file.&amp;nbsp; Add the following to the web.xml spring configuration file.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;!-- Transaction Management Strategy - local database transactions --&gt;  &lt;object id="transactionManager"          type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate30"&gt;    &lt;property name="DbProvider" ref="DbProvider"/&gt;    &lt;property name="SessionFactory" ref="SessionFactory"/&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;Step - 8 - Enable the Spring AOP transactions using attributes in the spring configuration file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We would want to govern how and when the transactions are started using Attributes.&amp;nbsp; For this to happen we need to inform Spring.NET that we are going to use Attributes to define the transactional behavior we need.&amp;nbsp; Spring.NET reads these attributes and starts/commits/rollbacks transactions using AOP.&amp;nbsp; To inform spring.net about our intentions add the following line in web.xml spring configuration file.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;objects xmlns="http://www.springframework.net"         xmlns:db="http://www.springframework.net/database"         xmlns:tx="http://www.springframework.net/tx"&gt;	&lt;!-- Not showing the other configuration in the web.xml ... --&gt;  &lt;tx:attribute-driven/&gt;&lt;/objects&gt;	]]&gt;&lt;/script&gt;&lt;br /&gt;Notice that we added the line &lt;b&gt;tx:attribute-driven &lt;/b&gt;but we also added the namespace &lt;b&gt;tx in the &lt;i&gt;objects&lt;/i&gt; root node declaration&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;If you have followed all the steps so far then you have successfully Integrated NHibernate with Spring.NET in an MVC3 application. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step - 9 - Test out the NHibernate integration&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To test out our brand new NHibernate integration with Spring.NET in an MVC3 application, lets change the implementation of the &lt;i&gt;AccountService.UserCount&lt;/i&gt; method.&amp;nbsp; &lt;span style="font-size: large;"&gt;Currently the &lt;i&gt;AccountService.UserCount &lt;/i&gt;method returns a hard coded value of 5454&lt;/span&gt;.&amp;nbsp; &lt;span style="font-size: large;"&gt;We will now replace it with the correct implementation, we will get the record count from the User table.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We will have to create an NHibernate entity that maps to the User table.&amp;nbsp; Lets create the User class that will map to the User table.&amp;nbsp; We will also create a class called UserMap class that will hold the NHibernate Fluent Mappings for the User class.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// &lt;summary&gt;    /// The user class that will map to the Users table.      /// We are only mapping the ID which is the primary key in the database.    /// We are not mapping any other properties since right now     /// we don't need them.    /// &lt;/summary&gt;    public class User    {        public virtual long ID { get; set; }    }    /// &lt;summary&gt;    /// The class that will hold the mappings for the Users table.      /// &lt;/summary&gt;    public class UserMap : ClassMap&lt;user&gt;    {        /// &lt;summary&gt;        /// The Default constructor that will hold the fluent NHibernate mappings.          /// We have to specify the table name used to map the User class        /// And we have to specify the Id column,         /// in our case its the ID property which maps to the user_id column         /// in the database.        /// &lt;/summary&gt;        public UserMap()        {             Table("users");             Id(x =&gt; x.ID, "user_id");        }    }]]&gt;&lt;/script&gt;&lt;br /&gt;The details are embedded in comments.  We have the User entity class and the UserMap mapping class to hold Fluent NHibernate mappings.&lt;br /&gt;&lt;br /&gt;Now, its time to actually use the User class to get the count of number of users in the database.&amp;nbsp; To do that, we will have to inject the &lt;span style="font-size: large;"&gt;SessionFactory instance in the AccountService&lt;/span&gt;.&amp;nbsp; Updated Spring.NET configuration file web.xml would look like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;object       type="aspnetwebFormsWithMvc3App.Service.AccountService, aspnetwebFormsWithMvc3App" id="AccountService"&gt;    &lt;property name="SessionFactory" ref="SessionFactory"/&gt;  &lt;/object&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;After injecting the SessionFactory its time now to change the implementation of the UserCount method to return the count of users from the users table.  Updated AccountService looks like&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// &lt;summary&gt;    /// The AccountService implementation.    /// &lt;/summary&gt;    public class AccountService : IAccountService    {        /// &lt;summary&gt;        /// The Session factory reference that will be injected by spring.net        /// &lt;/summary&gt;        public ISessionFactory SessionFactory { get; set; }        /// &lt;summary&gt;        /// From the SessionFactory we are now getting the CurrentSession         /// and adding the criteria over the User class.          /// We are projecting the row count this will return us         /// the total number of rows in the user table.        /// &lt;/summary&gt;        /// &lt;returns&gt;The long value representing the user count.&lt;/returns&gt;        [Transaction(TransactionPropagation.Required)]        public long UserCount()        {            return SessionFactory                .GetCurrentSession()                .CreateCriteria&lt;user&gt;()                .SetProjection(Projections.RowCountInt64())                .UniqueResult&lt;long&gt;();        }    }]]&gt;&lt;/script&gt;&lt;br /&gt;Since we have registered the &lt;span style="font-size: large;"&gt;OpenSessionInViewModule HTTP Module the GetCurrentSession method of SessionFactory instance will return the same session instance that was created by the HTTP Module.&lt;/span&gt;  This is absolutely vital for the Lazy loading to work correctly.&lt;br /&gt;&lt;br /&gt;Also notice that we have added the &lt;span style="font-size: large;"&gt;[Transaction] attribute to the method UserCount with TransactionPropagation as Required.&lt;/span&gt;&amp;nbsp; This will make sure that whenever the method UserCout is invoked either a new transaction is started or the method will join any existing transaction started earlier in the same thread.&lt;br /&gt;&lt;br /&gt;All set!&amp;nbsp; Its time to run the server and browse the &lt;b&gt;/Home/SpringIndex URL&lt;/b&gt; to see if our integration with NHibernate works! &lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-nEqSyYjG8Gg/Tlpv4qctBYI/AAAAAAAABQA/NljicJwOtFc/s1600/MVC3IntegratedWithNHibernate.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://1.bp.blogspot.com/-nEqSyYjG8Gg/Tlpv4qctBYI/AAAAAAAABQA/NljicJwOtFc/s320/MVC3IntegratedWithNHibernate.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Showing the actual user count using NHibernate&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As show in the image we are successfully getting the UserCount from the database.&amp;nbsp; We have successfully integrated NHibernate with Spring.NET in an MVC3 application!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3508583156557166429?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3508583156557166429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/08/integrating-nhibernate-with-springnet.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3508583156557166429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3508583156557166429'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/08/integrating-nhibernate-with-springnet.html' title='Integrating NHibernate with Spring.NET and MVC3'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-nEqSyYjG8Gg/Tlpv4qctBYI/AAAAAAAABQA/NljicJwOtFc/s72-c/MVC3IntegratedWithNHibernate.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-190373416621940841</id><published>2011-08-21T16:39:00.000+05:30</published><updated>2011-08-21T16:39:36.772+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='india'/><category scheme='http://www.blogger.com/atom/ns#' term='anna hazare'/><category scheme='http://www.blogger.com/atom/ns#' term='india against corruption'/><category scheme='http://www.blogger.com/atom/ns#' term='team anna'/><title type='text'>India Against Corruption</title><content type='html'>No matter who you are or what you do, everyone in India has heard about &lt;a href="http://www.annahazare.org/"&gt;Anna Hazare&lt;/a&gt;.&amp;nbsp; Team Anna Hazare, has been protesting at ramlila maidan (in New Delhi) against the Government and is trying to push the &lt;a href="http://en.wikipedia.org/wiki/Jan_Lokpal_Bill"&gt;Jan Lokpal Bill&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Over the years, Corruption in India has grown by leaps and bounds.&amp;nbsp; Everywhere there is some or the other form of corruption.&amp;nbsp; From getting a motor driving license to getting admission in a school/college, we i.e. the common man has to face corruption at all levels.&lt;br /&gt;&lt;br /&gt;At bigger levels there is bigger corruption.&amp;nbsp; Indian politicians have found a way to exploit the system in the way they want it.&amp;nbsp; May it be, organizing Common Wealth Games or building roads, corruption is everywhere.&lt;br /&gt;&lt;br /&gt;Corruption has made our nation handicapped.&amp;nbsp; Team Anna hopes that by implementing the Jan Lokpal Bill we can curb the corruption at high level by 60-65%.&amp;nbsp; I certainly hope that it gets implemented.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;But what about us?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;At times, in many situations, we feel helpless against the system.&amp;nbsp; To get around it, &lt;span style="font-size: large;"&gt;we ourselves fuel the corruption.&amp;nbsp; Its high time that we change ourselves.&lt;/span&gt;&amp;nbsp; How many times we have given 100 Rs to the traffic cop and not taken a receipt?&amp;nbsp; I am sure most of us have done this, I certainly have done it.&lt;br /&gt;&lt;br /&gt;Corruption is a two way process, &lt;span style="font-size: large;"&gt;person who is taking money is corrupt and person who is giving money is also corrupt.&lt;/span&gt;&amp;nbsp; We common man have to make sure that from now on, we will never every fuel corruption ourselves.&amp;nbsp; If we can do that, corruption can be reduced even further.&amp;nbsp; This is the first step!&lt;br /&gt;&lt;br /&gt;Team Anna is taking great pains to push the Jan Lokapl Bill, the least we could do is change ourselves and stop fueling corruption. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;In my entire life span, I have never seen India as united as it's today!&amp;nbsp; People of India want to get rid of corruption.&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;A few days back, if we asked &lt;span style="font-size: large;"&gt;who he/she was, they would say they are Hindu, Muslim, Christian etc. but today we are all Indians!&amp;nbsp; Indians who want a change!&amp;nbsp; We have forgotten our petty differences and have reunited.&amp;nbsp; It feels like a nation with 1 Billion+ people, aiming for one thing i.e. get rid of corruption!&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;My only message to government is, &lt;span style="font-size: large;"&gt;you better pay attention to our demands, else wait and perish!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;There are very few times when we get to be part of history, in India today is that day!&amp;nbsp; Lets support Team Anna in this historic movement to remove corruption from our country!&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Charity begins at home, lets take a oath today that we will not fuel corruption in any way!&amp;nbsp; No more bribes! &lt;br /&gt;&lt;br /&gt;Lets do whatever we could to support this movement in whatever way we could!&amp;nbsp; Jai Hind!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-190373416621940841?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/190373416621940841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/08/india-against-corruption.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/190373416621940841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/190373416621940841'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/08/india-against-corruption.html' title='India Against Corruption'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-199404175949591920</id><published>2011-08-13T14:35:00.001+05:30</published><updated>2011-08-13T14:37:31.506+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='controller'/><category scheme='http://www.blogger.com/atom/ns#' term='spring.net'/><category scheme='http://www.blogger.com/atom/ns#' term='integrating spring.net with mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>Integrating Spring.net with MVC3</title><content type='html'>If you are doing any kind of serious project, you sure want to use some sort of &lt;a href="http://martinfowler.com/articles/injection.html"&gt;dependency injection&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why do I need dependency injection?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Lot's of people have written lot's about why dependency injection is required.&amp;nbsp; I am not going to repeat all that, just a few points that I think, cannot be ignored&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Configuration flexibility&lt;/span&gt; &lt;span style="font-size: large;"&gt;- &lt;/span&gt;alternative implementations of a given service can be used without recompiling code&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Testability - &lt;/span&gt;Since we can provide alternative implementation of any given service at any time, any class can be unit tested very easily and effectively.&amp;nbsp; Its easy to inject a fack implementation of a service in the class we want to unit test&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Reduction of Boiler plate code - &lt;/span&gt;Since we no longer need to create instances of classes and inject them with proper dependencies&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Promotes loose coupling between classes and subsystems -&lt;/span&gt; Since classes are not dependent on a specific implementation, they are dependent on the contract that the other classes expose.&lt;/li&gt;&lt;/ul&gt;Enough said about dependency injection.&amp;nbsp; At this point if you are still not convinced that you need dependency injection, then I strongly recommend reading the full series of posts on Dependency Injection from Fabien Potencier &lt;a href="http://fabien.potencier.org/article/11/what-is-dependency-injection"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Alright, so we need dependency injection, what next?&lt;br /&gt;&lt;br /&gt;How do we implement dependency injection?&amp;nbsp; Should we hand code the logic and create our own way of doing dependency injection?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Well, take my advice, never ever, never every do that!&lt;/span&gt;&amp;nbsp; Always look for options, you will surely find one depdendency injection framework/container that suites your requirements.&amp;nbsp; Even if it does not fit your requirement completely, I am sure &lt;span style="font-size: large;"&gt;the framework/container provides enough hooks, based on which you can customize it to you taste!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;In the year 2011 and beyond, you cannot be serious if you are wasting your time and someone Else's money writing a dependency injection framework (I know a few people who have done that, can you believe it!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is Spring.NET?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; is an awesome dependency injection framework (actually its lot more than that).&amp;nbsp; Its open-source and its design is based on the proven Java based &lt;a href="http://www.springsource.org/"&gt;Spring Framework&lt;/a&gt;.&amp;nbsp; The breath of functionality in Spring .NET spans application tiers which allows you to treat it as a&lt;i&gt; "one stop shop"&lt;/i&gt; but that is not required.&amp;nbsp; The best thing about Spring .NET is, &lt;span style="font-size: large;"&gt;its not an all-or-nothing solution.&lt;/span&gt;&amp;nbsp; You can use the functionality in its modules independently.&amp;nbsp; Spring.NET integrates with a lot of other projects like &lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt;, &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;, &lt;a href="http://activemq.apache.org/"&gt;Active MQ&lt;/a&gt;, &lt;a href="http://quartznet.sourceforge.net/"&gt;Quartz .NET&lt;/a&gt;, &lt;a href="http://velocity.apache.org/"&gt;Velocity&lt;/a&gt; etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enough about Spring.NET, if you want to know more details about Spring.NET, I strongly recommend visiting this &lt;a href="http://www.springframework.net/"&gt;site&lt;/a&gt;, it has all the info you need.&amp;nbsp; It has links to the latest documentation, blogs, articles, faq's etc.&lt;br /&gt;&lt;br /&gt;By this time we agree that, we should use a dependency injection framework and for the sake of this post, I am going to show how easily we can integrate the Spring.NET dependency injection framework in our &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3&lt;/a&gt; application.&amp;nbsp; Lets not waste any more time and jump into the code straightaway to get this part started, shall we!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do they do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To Integrate Spring.NET into the MVC3 application you will need to do the following steps&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add the Spring.NET dependencies to the project.&lt;/li&gt;&lt;li&gt;Make the web.cofig changes to register the spring context&lt;/li&gt;&lt;li&gt;Declare the dependencies in an xml file&lt;/li&gt;&lt;li&gt;Write the code to interact with the dependencies in the HomeController&lt;/li&gt;&lt;li&gt;Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication&lt;/li&gt;&lt;/ul&gt;Lets have a look at each step one after the other.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add the spring.net dependencies to the project&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For integrating Spring.NET in your MVC3 application you will need to add references of following Spring.NET assemblies.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spring.Core.dll&lt;/li&gt;&lt;li&gt;Spring.Web.dll&lt;/li&gt;&lt;li&gt;Spring.Web.Mvc.dll&lt;/li&gt;&lt;/ul&gt;These dll's can be found in the downloaded Spring.NET zip package from this &lt;a href="http://www.springframework.net/download.html"&gt;link&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make the web.config changes to register the spring context&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In this step we add a &lt;i&gt;&amp;lt;configSection&amp;gt;&lt;/i&gt; for the Spring.NET configuration.&amp;nbsp; In the spring config section we would like to register the spring context.&amp;nbsp; Update web.config should look like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[	&lt;configsections&gt;		&lt;sectiongroup name="spring"&gt;		  &lt;section name="context"              type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc"/&gt;		&lt;/sectionGroup&gt;	&lt;/configSections&gt;	&lt;spring&gt;		&lt;context&gt;		  &lt;resource uri="~/Config/web.xml"/&gt;		&lt;/context&gt;	&lt;/spring&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;What we are doing here is, telling Spring.NET to look for a file called &lt;i&gt;web.xml inside the Config directory.  &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;What will the web.xml file contain? &amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;It will contain the dependency injection configurations for the classes in our application.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Declare the dependencies in an xml file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Spring will search for a file named &lt;i&gt;web.xml inside the Config directory, &lt;/i&gt;directly under the root of you application.&amp;nbsp; Lets make sure, Spring finds the file.&amp;nbsp; Create a directory called &lt;span style="font-size: large;"&gt;Config at the root level of your MVC3 application and create a file called web.xml inside it&lt;/span&gt;.&amp;nbsp; The project structure should look somewhat like this&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KCB21isvl9s/TkY7LUd-flI/AAAAAAAABPs/tJ_T92ODPK4/s1600/web.xml_inside_config.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://1.bp.blogspot.com/-KCB21isvl9s/TkY7LUd-flI/AAAAAAAABPs/tJ_T92ODPK4/s320/web.xml_inside_config.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Project Structure with web.xml included in the project&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Now, its time to register our dependencies in the web.xml.&amp;nbsp; We are going to add a very simple dependency of &lt;span style="font-size: large;"&gt;IAccountService that will give us total number of users in the system.&amp;nbsp; &lt;/span&gt;The web.xml would look like this&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;?xml version="1.0" encoding="utf-8" ?&gt;&lt;objects xmlns="http://www.springframework.net"&gt;  &lt;object type="aspnetwebFormsWithMvc3App.Controllers.HomeController, aspnetwebFormsWithMvc3App" singleton="false" id="Home"&gt;    &lt;property name="AccountService" ref="AccountService"/&gt;  &lt;/object&gt;  &lt;object type="aspnetwebFormsWithMvc3App.Service.AccountService, aspnetwebFormsWithMvc3App" id="AccountService"&gt;  &lt;/object&gt;  &lt;/objects&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The web.xml is just a plain XML file that uses Spring.NET xml schema to inject the AccountService into the HomeController.  We have given an id to the HomeController its &lt;i&gt;Home&lt;/i&gt; in our case.  We are also declaring that HomeController has a property Called AccountService.  This property will be auto injected by the Spring.NET container with the reference of type AccountService.&lt;br /&gt;&lt;br /&gt;Notice that the HomeController is not a singleton class.&amp;nbsp; MVC3 framework creates a new instance of the Controller every time a request comes for that controller.&amp;nbsp; Hence, Spring needs to know that, &lt;span style="font-size: large;"&gt;the HomeController is not supposed to be a singleton class.&amp;nbsp; This is done by adding the attribute &lt;i&gt;singleton="false" &lt;/i&gt;in the declaration of the HomeController.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The next declaration in the web.xml is that of AccountService.&amp;nbsp; For the sake of this example this class has no dependencies.&amp;nbsp; For our example this class is going to be very simple it will return some hard coded values.&lt;br /&gt;&lt;br /&gt;Notice that the singleton attribute has not be specified for the declaration of AccountService.&amp;nbsp; By default the singleton value is true, this means that the AccountService is a singleton class.&amp;nbsp; Spring.NET will&amp;nbsp; instantiate only one instance of the AccountService for the entire application!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Write the code to interact with the dependencies in the HomeController&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;As seen in Step - 2, HomeController is going to have a property of type AccountService.&amp;nbsp; We are going to query the AccountService to get the user count which will be eventually be shown on the UI.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class HomeController : Controller    {        /// &lt;summary&gt;        /// Reference of the Account service.          /// This will be injected by the Dependency Injection framework,         /// in our case Spring.NET.        /// Notice that nowhere we are creating an instance of AccountService.          /// Before the request is processed by the Action method        /// This Object will be injected by Spring.NET for us.        /// &lt;/summary&gt;        public IAccountService AccountService { get; set; }		        /// &lt;summary&gt;        /// This method interacted with the Dependency AccountService         /// and populates the UserCount in the ViewBag.          /// This will eventually be shown on the UI.        /// &lt;/summary&gt;        /// &lt;returns&gt;The ActionResult instance to render the         /// SpringIndex.cshtml view.        /// &lt;/returns&gt;        public ActionResult SpringIndex()        {            ViewBag.UserCount = AccountService.UserCount();            return View();        }    }    /// &lt;summary&gt;    /// The Interface of the AccountService.    /// &lt;/summary&gt;	    public interface IAccountService    {        /// &lt;summary&gt;        /// This method should return the total user count in the system.        /// &lt;/summary&gt;        /// &lt;returns&gt;Long value representing the user cont.&lt;/returns&gt;        long UserCount();    }    /// &lt;summary&gt;    /// The AccountService implementation.    /// &lt;/summary&gt;    public class AccountService : IAccountService    {        /// &lt;summary&gt;        /// For simplicity this method will return the         /// hard coded user count of 5454.        /// &lt;/summary&gt;        /// &lt;returns&gt;The long value representing the user count.&lt;/returns&gt;        public long UserCount()        {            return 5454;        }    }]]&gt;&lt;/script&gt;&lt;br /&gt;As you can see there is no magic in our classs.  HomeController simply calls the AccountService to get the UserCount and sets the value in the ViewBag.  The AccountService implementation is extremely simple, it returns a hardcoded value of 5454.  &lt;br /&gt;&lt;br /&gt;Lets look at the view SpringIndex.cshtml that will show the UserCount from the ViewBag.	&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;    &lt;title&gt;The MVC Page demostrating integration with Spring.NET&lt;/title&gt;&lt;/head&gt;&lt;body&gt;    &lt;h1&gt;  This is a page that demonstrates integration with Spring.NET.  Total number of users for this website are: @ViewBag.UserCount&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;As you must have guessed, the view could not have been any simpler.  It simply shows the message with the UserCount in it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We are almost done with all the plumbing required to integrate Spring.NET with MVC3 but, one last thing is left.&amp;nbsp; We need to inherit our &lt;span style="font-size: large;"&gt;Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication instead of System.Web.HttpApplication.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;This is required so that Spring registers the controller factory to instantiate the Controllers when the request comes.&lt;/span&gt;&amp;nbsp; This is done so that Spring gets an opportunity to dependency inject the controllers.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    /// &lt;summary&gt;    /// Inheriting the Global class from SpringMvcApplicaiton     /// instead of System.Web.HttpApplication.      /// This is required so that Spring registers the controller factory     /// to instantiate the Controllers when the request comes.    /// This is done so that Spring gets an opportunity to dependency inject     /// the controllers.    /// &lt;/summary&gt;    public class Global : SpringMvcApplication    {    }]]&gt;&lt;/script&gt;&lt;br /&gt;And we are done!  Lets run the application and browse the URL &lt;i&gt;/Home/SpringIndex &lt;/i&gt;to see what happens.  If you have followed the post till this point, browsing the url will result in a page like this&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-1JFDcS8N4eI/TkY9xZTfu4I/AAAAAAAABPw/jwziquLLeXE/s1600/SpringIndex.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://3.bp.blogspot.com/-1JFDcS8N4eI/TkY9xZTfu4I/AAAAAAAABPw/jwziquLLeXE/s320/SpringIndex.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;SpringIndex renders with UserCount value&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The User count 5454 is coming from the AccountService which we successfully injected into the HomeController.&lt;br /&gt;&lt;br /&gt;When the request for SpringIndex action of the HomeController comes to the server&amp;nbsp; following things occur&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spring intercepts the call and instantiates HomeController&amp;nbsp;&lt;/li&gt;&lt;li&gt;Injects all the dependencies of HomeController i.e. AccountService in our case&lt;/li&gt;&lt;li&gt;Calls the action method SpringIndex to complete the request&lt;/li&gt;&lt;li&gt;SpringIndex method calls the AccountService to get the UserCount and sets it in the ViewBag&lt;/li&gt;&lt;li&gt;SpringIndex.cshtml is rendered which shows UserCout!&lt;/li&gt;&lt;/ul&gt;We have successfully integrated Spring.NET with a MVC3 application!&amp;nbsp; That's all folks! &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-199404175949591920?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/199404175949591920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/199404175949591920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/199404175949591920'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/08/integrating-springnet-with-mvc3.html' title='Integrating Spring.net with MVC3'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-KCB21isvl9s/TkY7LUd-flI/AAAAAAAABPs/tJ_T92ODPK4/s72-c/web.xml_inside_config.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-2789438026403657800</id><published>2011-08-06T12:50:00.001+05:30</published><updated>2011-08-06T12:56:37.832+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='razor view'/><category scheme='http://www.blogger.com/atom/ns#' term='razor view engine'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc vs web forms'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc3 and web forms in one project'/><title type='text'>Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project - With Razor Views</title><content type='html'>In The &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;previous post&lt;/a&gt;, I explained how we could use &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;MVC3 and Asp.Net Web Forms Side-By-Side in One Project&lt;/a&gt;.&amp;nbsp; In that post, we were rendering &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3&lt;/a&gt; pages using the ASPX View Engine.&amp;nbsp; ASPX View Engine is the legacy view engine, &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;Razor View Engine&lt;/a&gt; has significant advantages over the ASPX View Engine.&amp;nbsp; In this post we will see how we could use the Razor View Engine instead of the ASPX View Engine.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;The Asp.Net MVC 3 has always supported the concept of &lt;i&gt;view engines&lt;/i&gt; – which are the pluggable modules that implement different template syntax options.&amp;nbsp; Razor view engine is optimized around HTML generation using a code-focused templating approach. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why Razor View engine?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Razor View engine is build with the following design goals (read the detail design goals &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Compact, Expressive, and Fluid: &lt;/b&gt;Razor minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding workflow. Unlike most template syntax's, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Easy to Learn: &lt;/b&gt;Razor is easy to learn and enables you to quickly be productive. You use all your existing language and HTML skills.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Is not a new language: &lt;/b&gt;Razor enables developers to use their existing C#/VB (or other) language skills and deliver a template markup syntax that enables an awesome HTML construction workflow with language of our choice.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Works with any Text Editor: &lt;/b&gt;Razor doesn’t require a specific tool and enables you to be productive in any plain old text editor (notepad works great).&amp;nbsp; That said, I have to mention this, &lt;a href="http://blogs.jetbrains.com/dotnet/tag/resharper-6/"&gt;Resharper 6.0&lt;/a&gt; has one of the best support for Razor Syntax.&amp;nbsp; Its a paid tool but its definitely worth the price.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Has great Intellisense: &lt;/b&gt;While Razor has been designed to not require a specific tool or code editor, it will have awesome statement completion support within Visual Studio.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Unit Testable:&lt;/b&gt; This is one of the most important Design Goal.&amp;nbsp; Razor implementation supports the ability to unit test views (without requiring a controller or web-server and can be hosted in any unit test project – no special app-domain required).&lt;/li&gt;&lt;/ul&gt;If you want to see a detailed reasoning of why Razor is better then ASPX View Engine, I strongly recommend vising this &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;link&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now that we are convinced that, Razor View Engine is better than ASPX View Engine, lets integrate the Razor views in our Asp.Net Web Forms application with MVC3 integrated in it. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;How Do they do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Initially, I though there must be setting somewhere in the project properties which will enable us to use the Razor View Engine, however, after several wasteful minutes of searching and researching in the project properties I found that, &lt;span style="font-size: large;"&gt;there is no such setting, &lt;/span&gt;we can directly go ahead and create the Razor view in the project. &lt;br /&gt;&lt;br /&gt;Razor views have an extension of &lt;b&gt;&lt;i&gt;cshtml&lt;/i&gt;&lt;/b&gt;.&amp;nbsp; Lets create our first Razor view called &lt;i&gt;RazorIndex.cshtml &lt;/i&gt;right next to the &lt;i&gt;Index.aspx &lt;/i&gt;that we had created in the &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;previous post&lt;/a&gt;.&amp;nbsp; This view will have nothing special, it will display one message that we set in the &lt;i&gt;ViewBag.&lt;/i&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;!DOCTYPE html PUBLIC    "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;    &lt;title&gt;The MVC Page Using the Razor Syntax&lt;/title&gt;&lt;/head&gt;&lt;body&gt;    &lt;h1&gt;     This is a page that is rendered via the Razor View Engine.     Hello @ViewBag.UserName Welcome to MVC3!    &lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;Notice that we are displaying the &lt;i&gt;UserName from the ViewBag&lt;/i&gt;.&amp;nbsp; Notice that, &lt;span style="font-size: large;"&gt;in the new Razor syntax, we have to use the @ sign to access any objects and properties.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Let's add one more method in our &lt;i&gt;HomeController &lt;/i&gt;which will render the &lt;i&gt;RazorIndex view &lt;/i&gt;and set the &lt;i&gt;UserName in the ViewBag&lt;/i&gt;.&amp;nbsp; The controller code will look no different from how it looked for rendering ASPX pages.&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[    public class HomeController : Controller    {        /// &lt;summary&gt;        /// The method is used to render the aspx view called Index.aspx.        /// This method also sets the UserName property in the ViewBag.        /// &lt;/summary&gt;        /// &lt;returns&gt;ActionResult instance to render the aspx view&lt;/returns&gt;        public ActionResult Index()        {            ViewBag.UserName = "Git Shah";            return View();        }        /// &lt;summary&gt;        /// The method that is used to render the Razor view         /// called RazorIndex.cshtml.        /// This method also sets the UserName property in the ViewBag.        /// &lt;/summary&gt;        /// &lt;returns&gt;ActionResult instance to render the razor view&lt;/returns&gt;        public ActionResult RazorIndex()        {            ViewBag.UserName = "Git Shah";            return View();        }    }]]&gt;&lt;/script&gt;&lt;br /&gt;This is a very good example of showing, how well the &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;Seperation of Concerns&lt;/a&gt; Design Pattern has been implemented in MVC3.&amp;nbsp; Even though we want to use a different View Engine, controller code remains unchanged.&amp;nbsp; In fact, &lt;span style="font-size: large;"&gt;Controller has no idea about which View Engine will be used to render the view.&amp;nbsp; This is an excellent example of why things should be loosely coupled to achieve modular and clean code!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before we can see if our Razor view is rendered correctly or not let's not forget to add one more route to our routes collection in Global.asax.cs file&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public class Global : System.Web.HttpApplication{   /// &lt;summary&gt;   /// This method will be called once when the application is started.   /// We will register our routes in this method.   /// &lt;/summary&gt;   protected void Application_Start()   {    AreaRegistration.RegisterAllAreas();    RegisterRoutes(RouteTable.Routes);   }   /// &lt;summary&gt;   /// Registers the routes that we want to use in our application.   /// We are registering one route which will show the index screen    /// when /home/index url is used.  Shows the RazorIndex view when   /// /home/razorindex url is used.   /// &lt;/summary&gt;   /// &lt;param name="routes"&gt;   /// The collection where the routes are to be registered.   /// &lt;/param&gt;   public static void RegisterRoutes(RouteCollection routes)   {     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");     routes.MapRoute(       "Home", // Route name       "home/index", // URL       new { controller = "Home", action = "Index"});     routes.MapRoute(       "RazorHome", // Route name       "home/razorindex", // URL       new { controller = "Home", action = "RazorIndex"});   }}]]&gt;&lt;/script&gt;&lt;br /&gt;We have just added one route called &lt;i&gt;RazorHome&lt;/i&gt;.  All set!  Lets build the project and access the URL &lt;b&gt;&lt;i&gt;/home/razorindex &lt;/i&gt;&lt;/b&gt;and see whats the outcome.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-gkpB0ybLywk/TjzmLqSZFDI/AAAAAAAABPc/AJuBLmUmyRw/s1600/razorFirstError.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://4.bp.blogspot.com/-gkpB0ybLywk/TjzmLqSZFDI/AAAAAAAABPc/AJuBLmUmyRw/s320/razorFirstError.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;First attempt to render Razor View results in an compilation error&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;OK does not look too good.&amp;nbsp; The error states that &lt;span style="font-size: large;"&gt;The type or namespace name 'Helpers' does not exist in the namespace 'System.Web'&lt;/span&gt;&amp;nbsp; To fix this we will have to do a change in the &lt;i&gt;web.config.&lt;/i&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;We will need to add a few assemblies in the&amp;nbsp; &amp;lt;system.web&amp;gt;&amp;lt;compilation&amp;gt; section.&amp;nbsp; &lt;span style="font-size: small;"&gt;The updated web.config would look like&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;system.web&gt;    &lt;compilation debug="true" targetFramework="4.0"&gt;      &lt;assemblies&gt;        &lt;add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;        &lt;add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;        &lt;add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;        &lt;add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;        &lt;add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;      &lt;/assemblies&gt;    &lt;/compilation&gt;  &lt;/system.web&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;After this lets build and access the URL &lt;i&gt;/home/razorindex &lt;/i&gt;and les see what happens&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-SxbuBuJgIuw/TjzmN1g8UxI/AAAAAAAABPg/T3FnhuGYH5w/s1600/razorErrorBecauseOfWrongClassName.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-SxbuBuJgIuw/TjzmN1g8UxI/AAAAAAAABPg/T3FnhuGYH5w/s320/razorErrorBecauseOfWrongClassName.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Second attempt at rendering the Razor view also results in compilation error, this time it cribs for ViewBag&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Still not quite there, but getting closer.&amp;nbsp; This time the error says that &lt;span style="font-size: large;"&gt;The name 'ViewBag' does not exist in the current context&lt;/span&gt;.&amp;nbsp; The problem is that the compiled &lt;i&gt;&lt;b&gt;class RazorIndex_cshtml&lt;/b&gt;&lt;/i&gt; is extending &lt;b&gt;&lt;i&gt;System.Web.WebPages.WebPage&lt;/i&gt;&lt;/b&gt; &lt;i&gt;&lt;b&gt;class&lt;/b&gt;&lt;/i&gt;.&amp;nbsp; As we had seen in the &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;previous post&lt;/a&gt;, MVC views needs to extend from &lt;i&gt;&lt;b&gt;System.Web.Mvc.WebViewPage&lt;/b&gt;&lt;/i&gt; and not &lt;i&gt;&lt;b&gt;System.Web.WebPages.WebPage.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do we fix this issue?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We need to some how tell the framework that the Razor pages should extend &lt;i&gt;&lt;b&gt;System.Web.Mvc.WebViewPage class.&lt;/b&gt;&lt;/i&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;This is done by adding another &lt;i&gt;web.config&lt;b&gt; &lt;/b&gt;&lt;/i&gt;in the Views directory.&lt;/span&gt;&amp;nbsp; The project structure would now look like this&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-pBHIahjEUJw/TjzmTKhsLiI/AAAAAAAABPk/to5P4oNNTyM/s1600/projectWithTwoWebConfig.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-pBHIahjEUJw/TjzmTKhsLiI/AAAAAAAABPk/to5P4oNNTyM/s320/projectWithTwoWebConfig.png" width="221" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Project Structure with two web.config's&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The content of this new &lt;i&gt;web.config &lt;/i&gt;should look like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;?xml version="1.0"?&gt;&lt;configuration&gt;  &lt;configsections&gt;    &lt;sectiongroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"&gt;      &lt;section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /&gt;      &lt;section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /&gt;    &lt;/sectionGroup&gt;  &lt;/configSections&gt;  &lt;system.web.webPages.razor&gt;    &lt;host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;    &lt;pages pageBaseType="System.Web.Mvc.WebViewPage"&gt;      &lt;namespaces&gt;        &lt;add namespace="System.Web.Mvc" /&gt;        &lt;add namespace="System.Web.Mvc.Ajax" /&gt;        &lt;add namespace="System.Web.Mvc.Html" /&gt;        &lt;add namespace="System.Web.Routing" /&gt;      &lt;/namespaces&gt;    &lt;/pages&gt;  &lt;/system.web.webPages.razor&gt;  &lt;system.web&gt;    &lt;httphandlers&gt;      &lt;add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/&gt;    &lt;/httpHandlers&gt;    &lt;!--        Enabling request validation in view pages would cause validation to occur        after the input has already been processed by the controller. By default        MVC performs request validation before a controller processes the input.        To change this behavior apply the ValidateInputAttribute to a        controller or action.    --&gt;    &lt;pages        validateRequest="false"        pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"&gt;      &lt;controls&gt;        &lt;add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /&gt;      &lt;/controls&gt;    &lt;/pages&gt;  &lt;/system.web&gt;  &lt;system.webServer&gt;    &lt;validation validateIntegratedModeConfiguration="false" /&gt;    &lt;handlers&gt;      &lt;remove name="BlockViewHandler"/&gt;      &lt;add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /&gt;    &lt;/handlers&gt;  &lt;/system.webServer&gt;&lt;/configuration&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The element &lt;span style="font-size: large;"&gt;&amp;lt;pages pageBaseType="System.Web.Mvc.WebViewPage"&amp;gt;&lt;/span&gt; &lt;span style="font-size: large;"&gt;tells that, the Razor views will have base class of &lt;i&gt;System.Web.Mvc.WebViewPage.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lets Rebuild the app and browse the URL &lt;i&gt;/home/razorindex &lt;/i&gt;and see what happens.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-vDQgZs0eM6E/TjzmjPU2UXI/AAAAAAAABPo/OK0tdr2Ks1Q/s1600/razorViewRendered.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-vDQgZs0eM6E/TjzmjPU2UXI/AAAAAAAABPo/OK0tdr2Ks1Q/s320/razorViewRendered.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Success! Razor view renders correctly&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Bingo!&amp;nbsp; We have an Asp.Net Web Forms application with MVC3 Razor views integrated in it!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;PS: Now you have no reason to not move to ASP.NET MVC3 from Web Forms, we have proved that MVC3 can co-exist with a Web Forms in the same project!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-2789438026403657800?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/2789438026403657800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/08/aspnet-mvc3-and-aspnet-web-forms-side.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2789438026403657800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2789438026403657800'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/08/aspnet-mvc3-and-aspnet-web-forms-side.html' title='Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project - With Razor Views'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-gkpB0ybLywk/TjzmLqSZFDI/AAAAAAAABPc/AJuBLmUmyRw/s72-c/razorFirstError.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-601878224667397791</id><published>2011-07-31T12:16:00.007+05:30</published><updated>2011-08-06T12:53:28.840+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='aspx rendering engine'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc vs web forms'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc3 and web forms in one project'/><title type='text'>Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project.</title><content type='html'>You must have known from my &lt;a href="http://www.gitshah.com/2011/07/aspnet-mvc-vs-aspnet-web-forms.html"&gt;previous post&lt;/a&gt; that, we have moved to &lt;a href="http://www.asp.net/mvc/mvc3"&gt;MVC3&lt;/a&gt; instead of the &lt;a href="http://www.asp.net/"&gt;Web Forms &lt;/a&gt;approach.&lt;br /&gt;&lt;br /&gt;While I was suggesting the clients to adopt the new MVC3 framework, the obvious question from their side was, &lt;span style="font-size: large;"&gt;Can the Web Forms and MVC3 co-exist?&amp;nbsp; Can the new MVC code reside in the Web Forms project?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I Googled a little, found that it was very much possible, however we needed to spike it out to be completely sure.&amp;nbsp; After some trial and errors, &lt;span style="font-size: large;"&gt;we were able to make the Web Forms and MVC3 code co-exist in one project.&lt;/span&gt;&amp;nbsp; The entire process was not very straight forward hence, I decided to write a post on how to do it.&lt;br /&gt;&lt;br /&gt;Let's first create a bare bone ASP.NET Web Forms application.&amp;nbsp; This can be done by using the &lt;i&gt;Create New Project Wizard&lt;/i&gt; of the &lt;i&gt;Visual Studio 2010&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-300hBXZSKkY/TjTuuE3q5SI/AAAAAAAABOo/j_EclwOBjjc/s1600/asp.netwebformsapp.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://1.bp.blogspot.com/-300hBXZSKkY/TjTuuE3q5SI/AAAAAAAABOo/j_EclwOBjjc/s320/asp.netwebformsapp.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Create new Asp.Net Web Forms Project&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The Wizard generates the &lt;i&gt;web.config file, master page and two pages About.aspx and Default.aspx.&lt;/i&gt;&amp;nbsp; Running the app at this stage should open up a page like this&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-KY4PWUKEwMI/TjTvCbN48XI/AAAAAAAABOs/1VqojwEt8Os/s1600/asp.netWebFormsBareBone.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://4.bp.blogspot.com/-KY4PWUKEwMI/TjTvCbN48XI/AAAAAAAABOs/1VqojwEt8Os/s320/asp.netWebFormsBareBone.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Asp.Net Web Forms Default Page&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Now we have an asp.net web forms application up and running.&amp;nbsp; Lets try and add the MVC3 code in the existing project and lets get it running.&amp;nbsp; This would effectively prove that Web Forms and MVC3 can co-exist.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Integrating MVC3 into the Web Forms application - How Do They Do It!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;MVC3 is build on &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration"&gt;Convention Over Configuration&lt;/a&gt;.&amp;nbsp; Controllers in MVC3 are put in a special directory called &lt;i&gt;Controllers&lt;/i&gt;, the views go into the &lt;i&gt;Views &lt;/i&gt;directory.&amp;nbsp; Lets create these two directories at the root level.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-xjuOX_ApnpU/TjTx0bFXe9I/AAAAAAAABOw/cxTjoq-tv8s/s1600/controllersAndViews.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://4.bp.blogspot.com/-xjuOX_ApnpU/TjTx0bFXe9I/AAAAAAAABOw/cxTjoq-tv8s/s320/controllersAndViews.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Adding Directories Controllers and View&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Let's add a very simple controller class called &lt;i&gt;HomeController &lt;/i&gt;to the project.&amp;nbsp; &lt;span style="font-size: large;"&gt;All MVC3 Controllers need to extend the System.Web.Mvc.Controller class.&lt;/span&gt;&amp;nbsp; To do this, you will need to add the reference of the &lt;span style="font-size: large;"&gt;System.Web.Mvc.dll&lt;/span&gt; into the project.&lt;br /&gt;&lt;br /&gt;Lets look at the code that goes into the HomeController&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public class HomeController : Controller{ /// &lt;summary&gt; /// The method is used to render the aspx view called Index.aspx. /// This method also sets the UserName property in the ViewBag. /// &lt;/summary&gt; /// &lt;returns&gt;ActionResult instance to render the aspx view&lt;/returns&gt; public ActionResult Index() {  ViewBag.UserName = "Git Shah";  return View(); }}]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;span style="font-size: small;"&gt;&lt;i&gt;HomeController has a very simple Index Action method&lt;/i&gt;.&lt;/span&gt;&amp;nbsp; This &lt;i&gt;Index action &lt;/i&gt;is simply going to render the &lt;i&gt;Index view&lt;/i&gt;.&amp;nbsp; The &lt;i&gt;Action method also adds a property to the ViewBag called UserName.&lt;/i&gt;&amp;nbsp; We will use the &lt;i&gt;UserName Property in the view.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The Index view needs to be created.&amp;nbsp; Let's create a file called &lt;i&gt;Index.aspx in the Views/Home/ &lt;/i&gt;directory.&amp;nbsp; The Index.aspx file looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %&gt;&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head runat="server"&gt;    &lt;title&gt;The MVC Page using ASPX Syntax&lt;/title&gt;&lt;/head&gt;&lt;body&gt;    &lt;h1&gt;     This is a page that is rendered via the Razor View Engine.       Hello &lt;%= ViewBag.UserName%&gt; Welcome to MVC3!    &lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;Notice that, &lt;span style="font-size: large;"&gt;the aspx page inherits the class &lt;i&gt;System.Web.Mvc.ViewPage&lt;/i&gt; and not &lt;i&gt;System.Web.Page&lt;/i&gt;.  All MVC3 views must extend the ViewPage class.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Also Notice, &lt;span style="font-size: large;"&gt;how we are showing the UserName from the ViewBag using the &amp;lt;%= %&amp;gt; Syntax.&amp;nbsp; Unlike traditional ASPX pages there is no code behind for this ASPX file.&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Curious thing about &lt;span style="font-size: large;"&gt;Index.aspx file is that, it does not inherit from the HomeController class&lt;/span&gt;.&amp;nbsp; Then how can the view access the &lt;i&gt;ViewBag property UserName &lt;/i&gt;which was set in the Controller?&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Well, the MVC3 framework implements &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;Separation of Concerns&lt;/a&gt; between the View and the Controller.&amp;nbsp; But &lt;span style="font-size: large;"&gt;it surely needs to pass information between the Controller and View, ViewBag is just one way of doing this.&amp;nbsp; Whatever we set in the ViewBag from the Controller is available in the Views!&lt;/span&gt;&amp;nbsp; This is just one of the way in which you can pass information between Controller and View.&lt;br /&gt;&lt;br /&gt;The project structure at this stage looks like&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-YVJWzPZDGNU/TjTx9wrUfpI/AAAAAAAABO0/w4k-KDBSvCk/s1600/projectstructure.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-YVJWzPZDGNU/TjTx9wrUfpI/AAAAAAAABO0/w4k-KDBSvCk/s320/projectstructure.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Project Structure after adding the HomeController and Index.aspx page&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;At this stage, if we could open up the URL &lt;i&gt;http://&amp;lt;host name&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;your application name&amp;gt;/home/index&lt;/i&gt; then we can be sure that we have successfully integrated MVC3 in a Web Forms Project.&amp;nbsp; Lets try and browse the URL and see what we get.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XmZEn2kT0fM/TjT2kdstETI/AAAAAAAABO4/zqKnK-2MmYw/s1600/The+resource+cannot+be+found._1312093808852.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="152" src="http://2.bp.blogspot.com/-XmZEn2kT0fM/TjT2kdstETI/AAAAAAAABO4/zqKnK-2MmYw/s320/The+resource+cannot+be+found._1312093808852.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;404 Error When we try to browse /home/index URL&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;We get a &lt;span style="font-size: large;"&gt;The resource cannot be found (404) error.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is because, we have not yet informed the framework that, when someone hits the URL &lt;i&gt;/home/index &lt;/i&gt;then how should it be served.&amp;nbsp; This can be done by registering a new route in the &lt;i&gt;Global.ascx.cs file&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;This file has an &lt;i&gt;Application_Start method.&lt;/i&gt;&amp;nbsp; This method is called when the application is started.&amp;nbsp; In this method we have to inform the framework that, &lt;span style="font-size: large;"&gt;when someone sends a request for the URL &lt;i&gt;/home/index &lt;/i&gt;then, route that URL to the HomeController.&lt;/span&gt;&amp;nbsp; This is done using the following code&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[routes.MapRoute( "Home", // Route name "home/index", // URL new { controller = "Home", action = "Index" });]]&gt;&lt;/script&gt;&lt;br /&gt;The complete code of Global.ascx.cs file looks like&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public class Global : System.Web.HttpApplication{        /// &lt;summary&gt;        /// This method will be called once when the application is started.        /// We will register our routes in this method.        /// &lt;/summary&gt;        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RegisterRoutes(RouteTable.Routes);        }        /// &lt;summary&gt;        /// Registers the routes that we want to use in our application.        /// We are registering one route which will show the index screen         /// when /home/index url is used.        /// &lt;/summary&gt;        /// &lt;param name="routes"&gt;        /// The collection where the routes are to be registered.        /// &lt;/param&gt;        public static void RegisterRoutes(RouteCollection routes)        {            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");            routes.MapRoute(                "Home", // Route name                "home/index", // URL                new { controller = "Home", action = "Index"});        }}]]&gt;&lt;/script&gt;&lt;br /&gt;Lets run the application and browse the URL &lt;i&gt;/home/index &lt;/i&gt;lets see what happens now?&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-pz4PU9LLbZk/TjT4MC2rHkI/AAAAAAAABO8/ak2RUrHMtnQ/s1600/Parser+Error_1312094236526.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="152" src="http://4.bp.blogspot.com/-pz4PU9LLbZk/TjT4MC2rHkI/AAAAAAAABO8/ak2RUrHMtnQ/s320/Parser+Error_1312094236526.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Parser Error - Could not load type 'System.Web.ViewPage'&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Nope, not there yet.&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[Parser Error Message: Could not load type 'System.Web.Mvc.ViewPage'.]]&gt;&lt;/script&gt;&lt;br /&gt;Turns out that for the page to get compiled and render correctly we need to &lt;span style="font-size: large;"&gt;add the System.Web.Mvc in the &lt;/span&gt;&lt;assemblies&gt;&lt;span style="font-size: large;"&gt; system.web/compilation/assemblies section in the web.config&lt;/span&gt;.  The updated web.config looks like&amp;nbsp;&lt;/assemblies&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;system.web&gt;    &lt;compilation debug="true" targetFramework="4.0"&gt;      &lt;assemblies&gt;        &lt;add           assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&gt;      &lt;/assemblies&gt;    &lt;/compilation&gt; ...  &lt;/system.web&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The only change here was to add the assembly System.Web.Mvc to the list of assemblies under the compilation section.  This will make sure that this assembly is available to the aspx view when its compiled.&lt;br /&gt;&lt;br /&gt;After making this change lets run the app and browse the URL &lt;i&gt;/home/index &lt;/i&gt;and lets see what happens.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-M7NSXwxm9yw/TjT5i13T13I/AAAAAAAABPA/5wVzIEPRP_w/s1600/The+MVC+Page+using+ASPX+Syntax_1312094584868.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="152" src="http://3.bp.blogspot.com/-M7NSXwxm9yw/TjT5i13T13I/AAAAAAAABPA/5wVzIEPRP_w/s320/The+MVC+Page+using+ASPX+Syntax_1312094584868.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Index.aspx is rendered Successfully using MVC3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Success!&amp;nbsp; We are able to render the page using MVC3 in a Web Forms application!&lt;br /&gt;&lt;br /&gt;Notice that, currently we are using the &lt;span style="font-size: large;"&gt;aspx rendering engine for rending MVC3 views&lt;/span&gt;, in the &lt;a href="http://www.gitshah.com/2011/08/aspnet-mvc3-and-aspnet-web-forms-side.html"&gt;next post&lt;/a&gt; I will explain how we could take advantage of the new &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;Razor Rendering Engine &lt;/a&gt;in a Web Forms application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-601878224667397791?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/601878224667397791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/601878224667397791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/601878224667397791'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/07/aspnet-mvc3-and-aspnet-web-forms-side.html' title='Asp.Net MVC3 and Asp.Net Web Forms Side-By-Side in One Project.'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-300hBXZSKkY/TjTuuE3q5SI/AAAAAAAABOo/j_EclwOBjjc/s72-c/asp.netwebformsapp.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-421149175002877567</id><published>2011-07-24T16:15:00.004+05:30</published><updated>2011-07-24T16:38:55.250+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='photoswipe'/><category scheme='http://www.blogger.com/atom/ns#' term='touchgallery'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery lightbox'/><category scheme='http://www.blogger.com/atom/ns#' term='full screen gallery with navigation links'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile image gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='image gallery for mobile'/><title type='text'>Showing an Image Gallery for HTML5 Mobile Web Site</title><content type='html'>Last Friday, I got task that was to be done as quickly as possible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What Was the Task? &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There was a HTML5 based mobile web site that few people from my company were working on.&amp;nbsp; On a certain page, we were showing thumbnail images&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-UhtoyZbmD3I/TivJScHFN3I/AAAAAAAABN4/jvOi5rDXzG8/s1600/IMG_0053.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-UhtoyZbmD3I/TivJScHFN3I/AAAAAAAABN4/jvOi5rDXzG8/s320/IMG_0053.PNG" width="213" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Page with Thumbnail images on it&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;If user wants to see a bigger image, they can click on one of the  thumbnail images, a new page opens up which shows only the image that  user had clicked.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zBwSWa7yVfE/TivJqj-DyqI/AAAAAAAABN8/NvvWX-x2JRg/s1600/IMG_0054.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-zBwSWa7yVfE/TivJqj-DyqI/AAAAAAAABN8/NvvWX-x2JRg/s320/IMG_0054.PNG" width="213" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;New page is opened,&lt;br /&gt;it shows only the image that was clicked&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&amp;nbsp;If user wants to see the next image, they have click back button on the browser and then click the other  image in the thumbnail list.&amp;nbsp; Certainly this was not very user friend behavior.&amp;nbsp; There was no easy way to see all the images one after the other.&amp;nbsp; User had to navigate between the pages to see all the images.&lt;br /&gt;&lt;br /&gt;Hence, I was given the task to implement some sort of a image gallery which will enable users to navigate between the images easily.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Approach&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Initially, I thought that the task was simple.&amp;nbsp; The possible approaches that immediately came to my mind where&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Full Home Grown Solution - This meant, writing some JavaScript on my own to show Next and Previous links (on the page where we are showing the image) and then cycle through the thumbnail images.&lt;/li&gt;&lt;li&gt;Reuse an existing image gallery JavaScript library - This meant, Googling a little, finding what image gallery JavaScript libraries are available and using the one that fits the our requirements.&lt;/li&gt;&lt;/ul&gt;I am firm believer that, &lt;span style="font-size: large;"&gt;one should not reinvent the wheel!&lt;/span&gt;&amp;nbsp; Hence, for obvious reasons, I ruled out the first approach.&amp;nbsp; I narrowed down my task, to find the Image Gallery JavaScript that would suite our requirements.&lt;br /&gt;&lt;br /&gt;Lets look at the HTML used to show the thumbnails and then the bigger images. &lt;br /&gt;&lt;script class="brush: html" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;div id="gallery"&gt;  &lt;a href="images/full/001.jpg"&gt;    &lt;img src="images/thumb/001.jpg" alt="Image 001" /&gt;  &lt;/a&gt;  &lt;a href="images/full/002.jpg"&gt;    &lt;img src="images/thumb/002.jpg" alt="Image 002" /&gt;  &lt;/a&gt;  &lt;a href="images/full/003.jpg"&gt;    &lt;img src="images/thumb/003.jpg" alt="Image 003" /&gt;  &lt;/a&gt;&lt;/div&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;As you can see, the HTML used to show the thumbnails and full images is pretty standard.&amp;nbsp; Thumbnail images are wrapped with an Anchor (&amp;lt;a&amp;gt;) tag with href attribute pointing to the full image.&amp;nbsp; Because of this, when user's click on the thumbnail, a new page with full image URL opens up.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;I was in no mood to change the HTML or use completely different approach to show the Image Gallery.&amp;nbsp; I wanted to do as little as possible to get the desired results, I am a lazy  developer you see!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We were using jquery on our HTML5 Mobile Website.&amp;nbsp; I was thinking, there  should be a ready made jquery plugin, which would show the images one  after the other and I would have to do little or no work.&amp;nbsp; Googling a little, I found many JQuery based Image Gallery JavaScript that looked promising.&amp;nbsp; I will list down a few of my not so successful attempts at showing the Image Gallery and then finally the one worked for me.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://leandrovieira.com/projects/jquery/lightbox/"&gt;The JQuery LightBox Plugin&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I am a fan of this plugin.&amp;nbsp; I had used this plugin in the past for few of my other projects.&amp;nbsp; I like everything about this plugin, the ease of use, the end result etc, its completely awesome!&amp;nbsp; Hence, I decided to give this plugin a go.&lt;br /&gt;&lt;br /&gt;I opened up the &lt;a href="http://leandrovieira.com/projects/jquery/lightbox/"&gt;JQuery LightBox examples URL&lt;/a&gt; on an iPhone to see how it behaves on the phone.&amp;nbsp; This is what I get&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-9DNRXjS2Di8/TivWpcHqI-I/AAAAAAAABOA/5yibMeflVTI/s1600/IMG_0056.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-9DNRXjS2Di8/TivWpcHqI-I/AAAAAAAABOA/5yibMeflVTI/s320/IMG_0056.PNG" width="213" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;LightBox examples URL opened in iPhone 3Gs&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;There is no doubt that it works on the iPhone.&amp;nbsp; But somethings were not right.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The preview image is still very small&amp;nbsp;&lt;/li&gt;&lt;li&gt;Next, Previous and Close links are difficult to find and click &lt;/li&gt;&lt;li&gt;One needs to Zoom In on the page to actually see the bigger preview image or click next, previous links.&lt;/li&gt;&lt;li&gt;Does not support swipe to change the image.&lt;/li&gt;&lt;li&gt;Clicking the Browser Back button takes the users to the Previous page in the browser history, it should have closed the full image preview dialog and stayed on the same page.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;I realized that I was trying to fit one solution to all problems.&lt;span style="font-size: small;"&gt;&amp;nbsp; Its evident that although the JQuery LightBox does an awesome job at showing the Image Gallery for web based application, I needed a JavaScript library that was build/optimized for Mobile devices.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Please note that, the issues that I just mentioned are &lt;span style="font-size: large;"&gt;not JQuery LightBox specific issues&lt;/span&gt;.&amp;nbsp; &lt;span style="font-size: large;"&gt;There is no doubt that the authors of JQuery LightBox have done a fantastic job at developing an Image Gallery JavaScript library, that does an awesome job at showing Image Gallery on web pages build for Computer and not for mobile devices.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I decided to search for Image Gallery JavaScript libraries that were build for the Mobile devices.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://neteye.github.com/touch-gallery.html"&gt;Touch Gallery&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Finally, I found a JQuery based Image Gallery JavaScript library that was build for mobile devices.&amp;nbsp; The Usage was simple enough, all I had to do was&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add the &lt;i&gt;&amp;lt;meta&amp;gt;&lt;/i&gt; tag for the&lt;i&gt; viewport&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Include the TouchGallery javascript library&lt;i&gt; &lt;/i&gt;&lt;/li&gt;&lt;li&gt;Select the appropriate Anchor (&amp;lt;a&amp;gt;) elements and call &lt;i&gt;touchGallery JavaScript function &lt;/i&gt;on them.&lt;/li&gt;&lt;/ul&gt;Updated HTML looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;meta name="viewport" content="width=device-width,initial-scale=1.0" /&gt;  &lt;script type="text/javascript" src="jquery.js" /&gt;  &lt;script type="text/javascript" src="jquery.touch-gallery-1.0.0.min.js" /&gt;  &lt;div id="gallery"&gt;    &lt;a href="images/full/001.jpg"&gt;     &lt;img src="images/thumb/001.jpg" alt="Image 001" /&gt;    &lt;/a&gt;    &lt;a href="images/full/002.jpg"&gt;     &lt;img src="images/thumb/002.jpg" alt="Image 002" /&gt;    &lt;/a&gt;    &lt;a href="images/full/003.jpg"&gt;     &lt;img src="images/thumb/003.jpg" alt="Image 003" /&gt;    &lt;/a&gt;  &lt;/div&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;JavaScript to integrate the Touch Gallery looks like&lt;br /&gt;&lt;script class="brush: jscript" type="syntaxhighlighter"&gt;&lt;![CDATA[    $(function() {      $('#gallery a').touchGallery();          });]]&gt;&lt;/script&gt;&lt;br /&gt;So far so good, lets look at the rendered result&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-1Zt3wYB-JIU/TivdeyZwSKI/AAAAAAAABOE/4NiN2LlM44k/s1600/IMG_0057.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-1Zt3wYB-JIU/TivdeyZwSKI/AAAAAAAABOE/4NiN2LlM44k/s320/IMG_0057.PNG" width="213" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Preview image opens up in full screen&lt;br /&gt;using Touch Gallery&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Better? Yes, the result is definitely better then the JQuery LightBox plugin.&amp;nbsp; Lets look at things that I like and dislike about this plugin.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Good&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The preview image is bigger and occupies full screen width&lt;/li&gt;&lt;li&gt;User can change images using a swipe&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;The Bad&lt;/b&gt; &lt;br /&gt;&lt;ul&gt;&lt;li&gt;There are no buttons to go Back and Forward.&amp;nbsp; User might not know in the first go that, they could swipe to change the image.&lt;/li&gt;&lt;li&gt;Big black sections at the top and bottom of the preview image&lt;/li&gt;&lt;li&gt;There is no close link, which users can click to go back to the page which shows all the thumbnails&lt;/li&gt;&lt;li&gt;Clicking the Browser Back button, takes the users to the Previous page in  the browser history, it should have closed the full image preview  dialog and stayed on the same page.&lt;/li&gt;&lt;/ul&gt;Seems like we were able to solve a few problems but still there are a few negatives.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Now what?&amp;nbsp; Write a custom solution?&amp;nbsp; NO! Never do that!&amp;nbsp; Obviously people must have faced this problem before and there has to be a JQuery based JavaScript library that fits my requirements, after all, its not Rocket Science!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I decided to find a better solution!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.photoswipe.com/"&gt;&lt;b&gt;PhotoSwipe&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;PhotoSwipe is a FREE HTML/CSS/JavaScript based image gallery specifically targeting mobile devices.&amp;nbsp; &lt;/span&gt;It provides visitors with a familiar and intuitive  interface allowing them to interact with images on your mobile website.&amp;nbsp; So far it seems to fit the bill.&amp;nbsp; Lets integrate it and see the results.&lt;br /&gt;&lt;br /&gt;Integrating it was not all that difficult, all I had to do was&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add the &lt;i&gt;&amp;lt;meta&amp;gt;&lt;/i&gt; tag for the&lt;i&gt; viewport&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the PhotoSwipe and dependent JavaScript files.&lt;i&gt; &lt;/i&gt;&lt;/li&gt;&lt;li&gt;Add the PhotoSwipe css&lt;i&gt; &lt;/i&gt;&lt;/li&gt;&lt;li&gt;Select the appropriate Anchor (&amp;lt;a&amp;gt;) elements and call &lt;i&gt;photoSwipe &lt;/i&gt;on them.&lt;/li&gt;&lt;/ul&gt;Update HTML looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[    &lt;meta name="viewport" content="width=device-width,initial-scale=1.0" /&gt;    &lt;link rel="stylesheet" type="text/css" href="/styles/mobile/photoswipe.css" /&gt;    &lt;script type="text/javascript" src="jquery.js" /&gt;    &lt;script type="text/javascript" src="simple-inheritance.min.js" /&gt;    &lt;script type="text/javascript" src="code-photoswipe-1.0.19.min.js" /&gt;    &lt;div id="gallery"&gt;      &lt;a href="images/full/001.jpg"&gt;       &lt;img src="images/thumb/001.jpg" alt="Image 001" /&gt;      &lt;/a&gt;      &lt;a href="images/full/002.jpg"&gt;       &lt;img src="images/thumb/002.jpg" alt="Image 002" /&gt;      &lt;/a&gt;      &lt;a href="images/full/003.jpg"&gt;       &lt;img src="images/thumb/003.jpg" alt="Image 003" /&gt;      &lt;/a&gt;    &lt;/div&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The Script to integrate the PhotoSwipe JavaScript library looks like&lt;br /&gt;&lt;script class="brush: jscript" type="syntaxhighlighter"&gt;&lt;![CDATA[  document.addEventListener('DOMContentLoaded', function(){     Code.photoSwipe('a', '#gallery');  }, false);]]&gt;&lt;/script&gt;&lt;br /&gt;Looks simple right, lets look at the results&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XpLuLLNatOw/Tiv1bhI2AxI/AAAAAAAABOI/JP70Fw91vS4/s1600/IMG_0058.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-XpLuLLNatOw/Tiv1bhI2AxI/AAAAAAAABOI/JP70Fw91vS4/s320/IMG_0058.PNG" width="213" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;PhotoSwipe in action &lt;br /&gt;Portrait mode with navigation links&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TEjhIwxqUWQ/Tiv1rQJLhuI/AAAAAAAABOM/rhjHp4dkMuo/s1600/IMG_0059.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="213" src="http://4.bp.blogspot.com/-TEjhIwxqUWQ/Tiv1rQJLhuI/AAAAAAAABOM/rhjHp4dkMuo/s320/IMG_0059.PNG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;PhotoSwipe in action&lt;br /&gt;Ladscape mode with navigation links&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As you can see, the results are wonderful.&lt;br /&gt;&lt;br /&gt;&lt;b&gt; The Good&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The preview image is bigger and occupies full screen width&lt;/li&gt;&lt;li&gt;User can change images using a swipe&lt;/li&gt;&lt;li&gt;There are navigation links using which users can go back, forward, close the dialog and even play the images as slide show&lt;/li&gt;&lt;li&gt; Clicking the back button of the browser show the original page with thumbnails on it!&lt;/li&gt;&lt;/ul&gt;PhotoSwipe fits the bill completely! &lt;br /&gt;&lt;br /&gt;IMHO there is no one solution that fits in all situations, but certainly there is a solution out there in the wild, that will fit your requirements!&amp;nbsp; If you don't find it in the fist go, try harder!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-421149175002877567?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/421149175002877567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/07/showing-image-gallery-for-html5-mobile.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/421149175002877567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/421149175002877567'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/07/showing-image-gallery-for-html5-mobile.html' title='Showing an Image Gallery for HTML5 Mobile Web Site'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-UhtoyZbmD3I/TivJScHFN3I/AAAAAAAABN4/jvOi5rDXzG8/s72-c/IMG_0053.PNG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-8522483337716705571</id><published>2011-07-17T19:09:00.003+05:30</published><updated>2011-07-17T19:18:40.584+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc3'/><category scheme='http://www.blogger.com/atom/ns#' term='web forms'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='IsPostBack'/><category scheme='http://www.blogger.com/atom/ns#' term='Seperation of Concerns'/><category scheme='http://www.blogger.com/atom/ns#' term='problems with telerik controls'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Single Responsibility Principle'/><category scheme='http://www.blogger.com/atom/ns#' term='telerik controls'/><category scheme='http://www.blogger.com/atom/ns#' term='No View State'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc vs web forms'/><title type='text'>Asp.Net MVC vs Asp.Net Web Forms</title><content type='html'>We were working on this project which was build using &lt;a href="http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29"&gt;C#&lt;/a&gt;, &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=17851"&gt;.Net 4.0&lt;/a&gt; and &lt;a href="http://www.asp.net/web-forms"&gt;Asp.NET Web Forms&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I come from a &lt;a href="http://www.java.com/en/download/"&gt;Java&lt;/a&gt; background where &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC pattern&lt;/a&gt; has been around since ever.&amp;nbsp; There are tons of Java based web frameworks out there that implement the MVC pattern.&amp;nbsp; It looked quite surprising to me that, till very recently there was no equivalent of MVC pattern in the .Net world.&amp;nbsp; But, recently the things have changed, Microsoft has come up with its own implementation of the MVC pattern called &lt;a href="http://www.asp.net/mvc/mvc3"&gt;Asp.NET MVC3&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;I certainly like the MVC approach over the Web Forms approach for multiple reasons&lt;/span&gt;, I had to present these reasons to the client and convince them to move to Asp.Net MVC3 instead of the current Asp.Net Web Forms approach.&amp;nbsp; Finally, after quite some talking and presenting and discussions we managed to convenience the client to adaopt the Asp.Net MVC 3 approach over the Web Forms approach.&lt;br /&gt;&lt;br /&gt;This blog post highlights the points why I think, MVC makes a better choice as the presentation framework over Web Forms.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Separation of Concerns (SoC) And Single Responsibility Principle&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you ask me, &lt;span style="font-size: large;"&gt;what are the two most important principles which helps in keeping the code clean, modular, readable and maintainable?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My Answer would be, &lt;span style="font-size: large;"&gt;Separation of Concerns (SoC) and Single Responsibility Principle.&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Its extremely important that every class in the system has a well defined job for itself.&amp;nbsp; No class should try and do too many things, in fact &lt;span style="font-size: large;"&gt;it should do only &lt;b&gt;*one* &lt;/b&gt;thing and do it well (Single Responsibility Principle).&amp;nbsp; If one class tries to do too many things, then the code of the class would be messy, difficult to understand and maintain.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;The code behind classes of the Web Forms approach are victim of this problem.&amp;nbsp; &lt;/span&gt;Lot of times, I have seen the code behind classes are bloated and are longer than 2000 lines.&amp;nbsp; Such classes are difficult to maintain and understand.&amp;nbsp; The code looks convoluted.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Why does this happen?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Because, code behind classes have lots of responsibility.&amp;nbsp; They deal with&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Showing the view&lt;/li&gt;&lt;li&gt;Dynamically rendering JavaScript&lt;/li&gt;&lt;li&gt;Updating the model&lt;/li&gt;&lt;li&gt;Validating the values entered by the user&lt;/li&gt;&lt;li&gt;Implementing some business logic&lt;/li&gt;&lt;li&gt;Making a call to the service&lt;/li&gt;&lt;li&gt;Differentiate the Post and Get requests etc.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;End result is a &lt;span style="font-size: large;"&gt;truly complex and &lt;a href="http://www.urbandictionary.com/define.php?term=Gumped%20Up&amp;amp;defid=5935600"&gt;gumped up&lt;/a&gt; code behind&lt;/span&gt;.&lt;br /&gt;MVC on the other hand, implements these principle very well.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Controller classes are only responsible to update the model, decided which view to render and that's about it.&lt;/li&gt;&lt;li&gt;Views only responsibility is to use the model to render itself.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Model just holds the business realted information.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;End result of all this is &lt;span style="font-size: large;"&gt;clean, modular, readable and maintainable code&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;MVC gives full control over the rendered HTML&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the Web Forms approach, we were using third part controls called &lt;a href="http://www.telerik.com/products/aspnet-ajax.aspx"&gt;Telerik controls&lt;/a&gt;.&amp;nbsp; &lt;span style="font-size: large;"&gt;At times its really difficult to control the HTML that gets rendered from these controls.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;Many times the HTML that is rendered is more complex than what would be required.&amp;nbsp; &lt;/span&gt;Because of this, designers find it difficult to style it the way they want it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;With MVC, you get full control of the exact HTML that gets rendered.&amp;nbsp; This is an absolute boon for the designers and developers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Unit Testing&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I don't want to talk about how difficult it is to unit-test web forms code behind classes.&amp;nbsp; &lt;span style="font-size: large;"&gt;The web form code behind classes are tightly coupled with things like Session, ViewState Request, Response etc.&amp;nbsp; This makes them extremely bad candidates for unit testing.&lt;/span&gt;&amp;nbsp; To unit test web forms code behind classes one needs a very strong will and extremely good mocking and Unit testing skills.&lt;br /&gt;&lt;br /&gt;On the other hand, &lt;span style="font-size: large;"&gt;MVC has been build with Unit Testing in mind.&amp;nbsp; One can easily do Test Driven Development with MVC controllers.&amp;nbsp; Controllers are not coupled with Session or Request or Response object which makes them easily unit testable.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Search Engine Optimizations and RESTful URL's&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Web Forms application URL's end with &lt;b&gt;.aspx&lt;/b&gt; extension.&amp;nbsp; They represent a physical file in the file system.&amp;nbsp; The MVC URL's do not have any extensions.&amp;nbsp; They do not logically map to a file on the file system.&amp;nbsp; Instead they map to a controller and an action method inside the controller.&amp;nbsp; The URL of MVC application look like&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://localhost:8080/appname/customer/create&lt;/li&gt;&lt;li&gt;http://localhost:8080/appname/customer/1&lt;/li&gt;&lt;li&gt;http://localhost:8080/appname/customer/list&lt;/li&gt;&lt;li&gt;http://localhost:8080/appname/customer/edit&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Integration with Third Party JavaScript libraries&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Its difficult to integrate the web forms application seamlessly with a JavaScript library.&amp;nbsp; For e.g. &lt;span style="font-size: large;"&gt;If you wanted to do Ajax with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; in a web forms application, imagine how much code you will have to write.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;How will you render the dynamic HTML in this case.&amp;nbsp; How will you preserve the view state?&amp;nbsp; Its all very messy.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With MVC, we do not have a problem like this ever.&amp;nbsp; By default, &lt;span style="font-size: large;"&gt;MVC application comes integrated with jQuery.&lt;/span&gt;&amp;nbsp; However, you could go ahead and integrate any other JavaScript library of your choice.&amp;nbsp; Since view is not tightly coupled with controller integrating any JavaScript library is extremely easy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;No IsPostBack&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think there is no Asp.Net application in the world that does not have code which looks like&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public partial class Register : Page{ protected void Page_Load(object sender, EventArgs e) {  if (IsPostBack)  {   //Do something its a post back envet.  }  else  {   //Do something else its a get request  } }}]]&gt;&lt;/script&gt;&lt;br /&gt;One class/method to handle both the get and post requests.  &lt;span style="font-size: large;"&gt;At every step we have to decide whether its a get request or a post request and change the business processing&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This is infrastructure code.  &lt;span style="font-size: large;"&gt;We should not be bothering about checking whether the request is a get request or a post request.&lt;/span&gt;  Framework should do this for me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;With MVC, we do not have to keep checking whether its a get request or a post request.&amp;nbsp; We can simply put an attribute to a method marking it only accessible via the GET request or only accessible via the POST requests.&lt;/span&gt;&amp;nbsp; With MVC the above code would look like&lt;br /&gt;&lt;script class="brush: csharp" type="syntaxhighlighter"&gt;&lt;![CDATA[public class RegistrationController : Controller{ [HttpGet] public ActionResult Something() {   return View(); }  [HttpPost] public ActionResult Something(RegistrationMode model)  {   //Actually register the user and redirect to a different Action   return new RedirectToAction("Success"); }}]]&gt;&lt;/script&gt;&lt;br /&gt;Notice that we simply have to mark which methods are invokable over which protocol using either the &lt;b&gt;HttpGet or HttpPost attributes.  &lt;/b&gt;End result, &lt;span style="font-size: large;"&gt;simplified and easy to understand code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;No View State&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Web Forms provides a wrapper over the stateless HTTP protocol to make it state-full.&amp;nbsp; &lt;span style="font-size: large;"&gt;It achieves this by adding a hidden field called &lt;i&gt;__VIEWSTATE__&lt;/i&gt; to the rendered page.&lt;/span&gt;&amp;nbsp; &lt;span style="font-size: large;"&gt;If not handled correctly and especially when you are using some third party control library like Telerik controls ViewState can easily get out of hands.&lt;/span&gt;&amp;nbsp; I have see pages that have ViewState that goes in MB's.&amp;nbsp; &lt;span style="font-size: large;"&gt;This ViewState will be sent/received to/from the server for every Post requests.&amp;nbsp; Its sent/received to/from the server even when you do a Ajax request.&amp;nbsp; The performance of such pages goes for a toss!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;MVC has no concept of ViewState.&amp;nbsp; &lt;/span&gt;MVC does not add a wrapper over the stateless HTTP Protocol.&amp;nbsp; In fact it harnesses the HTTP protocol.&amp;nbsp; Hence, &lt;span style="font-size: large;"&gt;MVC pages are much faster and they can easily out perform the Web Forms counter parts on any day.&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;These are some of the points why I think, &lt;span style="font-size: large;"&gt;MVC is definitely a better choice over Web Forms for building Customer Facing, fast Web 2.0 applications.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;This list is by not means an extensive comparision of Web Forms vs the MVC appraoches.&amp;nbsp; Just some little peaces which I though were really important.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt; We have made our choice to move to MVC, have you?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-8522483337716705571?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/8522483337716705571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/07/aspnet-mvc-vs-aspnet-web-forms.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/8522483337716705571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/8522483337716705571'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/07/aspnet-mvc-vs-aspnet-web-forms.html' title='Asp.Net MVC vs Asp.Net Web Forms'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3006079540713871165</id><published>2011-07-09T21:19:00.001+05:30</published><updated>2011-07-17T18:26:18.764+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='trek'/><category scheme='http://www.blogger.com/atom/ns#' term='rejuvenate'/><category scheme='http://www.blogger.com/atom/ns#' term='rocks'/><category scheme='http://www.blogger.com/atom/ns#' term='fort'/><category scheme='http://www.blogger.com/atom/ns#' term='peace'/><category scheme='http://www.blogger.com/atom/ns#' term='natural beauty'/><category scheme='http://www.blogger.com/atom/ns#' term='landscape'/><category scheme='http://www.blogger.com/atom/ns#' term='lohagad'/><title type='text'>Lohagad - Nature at its best - Rejuvenate yourself</title><content type='html'>It all started with me and my friend Mahendra, talking about how the weather in Pune is perfect for a trek.&amp;nbsp; We have been talking about doing a trek since one year now, but because of some or the other reason, never managed to actually do it.&amp;nbsp; But this time, I really really wanted to do it!&amp;nbsp; After some initially talks, we decided to do a trek to &lt;a href="http://en.wikipedia.org/wiki/Lohagad"&gt;Lohagad&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;I asked around to see if others were interested.&amp;nbsp; Total 12 people agreed for the trek.&amp;nbsp; We decided to start at 0630 hrs on Saturday and come back by afternoon.&lt;br /&gt;&lt;br /&gt;Staring from 2000 hrs on Friday evening, I started getting SMS'es from people saying they cannot make it.&amp;nbsp; By morning, I was thinking it will be just me and my wife who will be going for the trek :).&amp;nbsp; But in the end, we were 5 adults and 4 kids (all of them 8 years old) made it!&lt;br /&gt;&lt;br /&gt;As planned we started off at about 0630 hrs.&amp;nbsp; I had been to Lohagad in the past, at that time, there were no shops at the top, i.e. no food and no water at the top.&amp;nbsp; Hence, we wanted to have heavy breakfast before starting.&amp;nbsp; We tried a few good restaurants but none of them were open that early.&amp;nbsp; Finally, we settled for a &lt;a href="http://en.wikipedia.org/wiki/Dhaba"&gt;dhaba&lt;/a&gt; type place to have breakfast.&amp;nbsp; Although the ambiance of the place was not all that great, the food was good!&amp;nbsp; We had &lt;a href="http://en.wikipedia.org/wiki/Misal"&gt;Misal&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Poha_%28rice%29"&gt;Poha&lt;/a&gt; and Tea.&amp;nbsp; After filling our tanks, it was time to hit the road again.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;We reach the base village Malawali at about 0830 hrs, it was a good surprice to see a very well organized pay and park facility at Malawli.&amp;nbsp; We parked our vehciles there and started the climb.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Way Up:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Right at the beginning of our ascent we saw two waterfalls.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-mP8ZuyurJzA/ThhteRSfJGI/AAAAAAAABJk/g5y7IpVrQm0/s1600/IMG_1440.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-mP8ZuyurJzA/ThhteRSfJGI/AAAAAAAABJk/g5y7IpVrQm0/s320/IMG_1440.JPG" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;As we climbed up, breathtaking views would unfold in front of our eyes.&amp;nbsp; The natural beauty on the way was simply amazing. &lt;br /&gt;&lt;br /&gt;A few images to illustrate what I mean&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-A65etV1xj0c/ThhtfoXSwEI/AAAAAAAABJo/kZfBeMidUbs/s1600/IMG_1459.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://3.bp.blogspot.com/-A65etV1xj0c/ThhtfoXSwEI/AAAAAAAABJo/kZfBeMidUbs/s320/IMG_1459.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-UpYY3B8dBrc/Thhtgt1-oAI/AAAAAAAABJs/IM3Xv5-EfCk/s1600/IMG_1463.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://1.bp.blogspot.com/-UpYY3B8dBrc/Thhtgt1-oAI/AAAAAAAABJs/IM3Xv5-EfCk/s320/IMG_1463.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-hw7GogbQ5xk/ThhthsO9jsI/AAAAAAAABJw/0xb_EvL2c8o/s1600/IMG_1467.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-hw7GogbQ5xk/ThhthsO9jsI/AAAAAAAABJw/0xb_EvL2c8o/s320/IMG_1467.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KSelml--bXU/ThhtwsHTvyI/AAAAAAAABKg/KmQ_1nqhlxQ/s1600/IMG_1530.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://1.bp.blogspot.com/-KSelml--bXU/ThhtwsHTvyI/AAAAAAAABKg/KmQ_1nqhlxQ/s320/IMG_1530.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-aeToHGLXKlQ/Thht2ctioVI/AAAAAAAABK0/TjcphemMSgU/s1600/IMG_1623.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-aeToHGLXKlQ/Thht2ctioVI/AAAAAAAABK0/TjcphemMSgU/s320/IMG_1623.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;At one point right over our head we saw a big rock which looked like a gigantic ship.&amp;nbsp; It would immediately remind you of the famous scene from "&lt;a href="http://en.wikipedia.org/wiki/Titanic_%281997_film%29"&gt;Titanic&lt;/a&gt;" where Leonardo and Kate are standing at the tip of the titanic to feeling the breeze.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-3d1hfh8wpVI/Thht5N8BmZI/AAAAAAAABLA/LLhQLYRQcZ8/s1600/020720112201.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-3d1hfh8wpVI/Thht5N8BmZI/AAAAAAAABLA/LLhQLYRQcZ8/s320/020720112201.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;The snaps does not do justice to the view that we saw!&lt;br /&gt;&lt;br /&gt;For the first time in my life I saw blue beetles&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-1QnFeCeC5lk/ThhtnRF01JI/AAAAAAAABKA/jW7Q8D6ch8k/s1600/IMG_1486.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-1QnFeCeC5lk/ThhtnRF01JI/AAAAAAAABKA/jW7Q8D6ch8k/s320/IMG_1486.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;After walking some more, we saw another natural miracle.&amp;nbsp; We saw a big rock hanging by the side of the cliff.&amp;nbsp; The rock and cliff would be attached only at the ends.&amp;nbsp; The space between the center of the rock and the cliff formed a shape which looked similar to &lt;a href="http://en.wikipedia.org/wiki/Shiva"&gt;Shiva's&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Third_eye"&gt;third eye&lt;/a&gt;!&amp;nbsp; Its difficult to explain, a picture would clarify things.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-lstgNVGSRCw/ThhttHKyYWI/AAAAAAAABKU/Eic8LX4TESo/s1600/IMG_1517.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-lstgNVGSRCw/ThhttHKyYWI/AAAAAAAABKU/Eic8LX4TESo/s320/IMG_1517.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Finally, after about 1.5 hours of walking and enjoying the natural marvels, we reached the base of the Fort.&amp;nbsp; There we were greeted by our ancestors&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-f3CGjSb2JV0/Thhty3g089I/AAAAAAAABKo/2-8ZHp9cqSg/s1600/IMG_1556.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-f3CGjSb2JV0/Thhty3g089I/AAAAAAAABKo/2-8ZHp9cqSg/s320/IMG_1556.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;There are lots of monkeys in and around the Lohagad fort.&amp;nbsp; They were waiting to get one opportunity to snatch anything that looked like food.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;There are proper steps created to go from the base of the fort to the fort itself.&amp;nbsp; &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-H9uiWTd3n_U/ThhyLN5XIaI/AAAAAAAABLY/EiHMDwkM-5Q/s1600/IMG_1547.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-H9uiWTd3n_U/ThhyLN5XIaI/AAAAAAAABLY/EiHMDwkM-5Q/s320/IMG_1547.JPG" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-65hqg3nD25A/ThhyPYb0ahI/AAAAAAAABLo/L3j05tbsjtM/s1600/IMG_1571.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://3.bp.blogspot.com/-65hqg3nD25A/ThhyPYb0ahI/AAAAAAAABLo/L3j05tbsjtM/s320/IMG_1571.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;During the monsoons, small stream of water keeps flowing down the steps.&amp;nbsp; On our way into the fort, we saw a small lake formed by the back waters of the &lt;a href="http://www.google.co.in/search?q=pawna+dam+images&amp;amp;hl=en&amp;amp;biw=1366&amp;amp;bih=628&amp;amp;prmd=ivns&amp;amp;tbm=isch&amp;amp;tbo=u&amp;amp;source=univ&amp;amp;sa=X&amp;amp;ei=DnMYTqG3AszHrQfo0tnPAQ&amp;amp;ved=0CBoQsAQ"&gt;Pawna dam&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KSelml--bXU/ThhtwsHTvyI/AAAAAAAABKg/KmQ_1nqhlxQ/s1600/IMG_1530.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://1.bp.blogspot.com/-KSelml--bXU/ThhtwsHTvyI/AAAAAAAABKg/KmQ_1nqhlxQ/s320/IMG_1530.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-l5w7aR_AuQU/ThhzpD_zxuI/AAAAAAAABL0/HHfOu_zw6AA/s1600/IMG_1529.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://3.bp.blogspot.com/-l5w7aR_AuQU/ThhzpD_zxuI/AAAAAAAABL0/HHfOu_zw6AA/s320/IMG_1529.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-AzDPgIs1boY/Thhtu4GY9KI/AAAAAAAABKY/Zr1eCle59BQ/s1600/IMG_1524.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;On the way up, we saw ruins of few small cannons.&amp;nbsp; We tried to lift them just to see how heavy they were, but they wont move even a inch!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-AzDPgIs1boY/Thhtu4GY9KI/AAAAAAAABKY/Zr1eCle59BQ/s1600/IMG_1524.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-AzDPgIs1boY/Thhtu4GY9KI/AAAAAAAABKY/Zr1eCle59BQ/s320/IMG_1524.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;A few more steps and we saw a gigantic Maratha gate!&amp;nbsp; It had massive chains and sharp spikes all over it.&amp;nbsp; Needless to say that one person cannot open or close the gate.&amp;nbsp; The spikes made sure that, it would be difficult even for a fully grown elephant, to break open it.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-HxQgXcCy--k/Thh0wajGZpI/AAAAAAAABL8/cp5oex3ECsc/s1600/IMG_1551.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-HxQgXcCy--k/Thh0wajGZpI/AAAAAAAABL8/cp5oex3ECsc/s320/IMG_1551.JPG" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;Last few steps, took us into the fort.&amp;nbsp; No one wanted to walk any further without having a bite.&amp;nbsp; We decided to stop there and have something to eat.&amp;nbsp; We had carried lots to eat, Sandwiches, Chips, Sabzi Roti etc.&amp;nbsp; When we were half way through our lunch, one monkey located us and came extremely close to us, looking for an opportunity to snatch something.&amp;nbsp; We reacted quickly, &lt;span style="font-size: large;"&gt;we put everything back in the bags and started walking.&amp;nbsp; 5 adults and 4 kids against 1 monkey, believe me, monkey was not at all afraid of any of us.&lt;/span&gt;&amp;nbsp; In fact he was actually trying to scare us.&amp;nbsp; We had to finally give him a peace of sandwich.&lt;br /&gt;&lt;br /&gt;We decided to move ahead since we could not continue our lunch at the same place.&amp;nbsp; After walking for 5 min we saw a &lt;a href="http://en.wikipedia.org/wiki/Dargah"&gt;Dargah&lt;/a&gt; and a small pond, we decided to finish our lunch there. &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-eS00mbWPWvc/Thht0H4TqEI/AAAAAAAABKs/R4yhC2LTp2s/s1600/IMG_1584.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-eS00mbWPWvc/Thht0H4TqEI/AAAAAAAABKs/R4yhC2LTp2s/s320/IMG_1584.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;After lunch, it was time to sit and relax and do nothing absolutely nothing!&amp;nbsp; Cool breeze was blowing continuously.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;I was at "peace" with myself!&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was not thinking about anything, nothing absolutely nothing at all!&amp;nbsp; &lt;span style="font-size: large;"&gt;Not thinking about the city roads, traffic jams, home, projects to be delivered, meeting the deadlines, nothing!&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;My 10 gallon head was completely empty.&amp;nbsp; Simply, sitting and enjoying the natural beauty.&amp;nbsp; I have to admit, I had not felt like this for quite some time now.&lt;/span&gt;&amp;nbsp; I am not a person who would keep thinking and worry about stuff, but still the feeling that I got at that point was beyond anything that I had experienced before.&lt;br /&gt;&lt;br /&gt;In the movie &lt;a href="http://www.imdb.com/title/tt0454921/"&gt;The Pursuit of Happyness&lt;/a&gt;, right before he gets the job as a Broker, &lt;a href="http://en.wikipedia.org/wiki/Chris_Gardner"&gt;Chris Gardner&lt;/a&gt; says,&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: large;"&gt;&lt;i&gt;The next day, after work, we just went to the beach. Far away from anything, everything, just Christopher and me. Far away from buses, and noise, and my constant disappointment in my ten gallon head, in myself&lt;/i&gt;&lt;/span&gt;&lt;/blockquote&gt;At that moment, I was able to understand what he was talking about.&amp;nbsp; What is that feeling and I can tell you one thing, it surely feels great!&amp;nbsp; That moment for me was the best moment in the entire trek.&amp;nbsp; It was totally worth it!&lt;br /&gt;&lt;br /&gt;After relaxing for about an hour or so, we decided to explore the, West side of Lohagad fort to see The Vinchukata(Scorpion Tail).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-lVMK6gC4Px4/Thht1SfG5EI/AAAAAAAABKw/D-O4yECvV38/s1600/IMG_1622.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://1.bp.blogspot.com/-lVMK6gC4Px4/Thht1SfG5EI/AAAAAAAABKw/D-O4yECvV38/s320/IMG_1622.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-aeToHGLXKlQ/Thht2ctioVI/AAAAAAAABK0/TjcphemMSgU/s1600/IMG_1623.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-aeToHGLXKlQ/Thht2ctioVI/AAAAAAAABK0/TjcphemMSgU/s320/IMG_1623.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;On the way to Vinchukata one has to climb down an almost straight wall made of rocks.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-KWbQUeg5Lz0/Thht6anfFGI/AAAAAAAABLE/gfOE_kbfhiY/s1600/IMG_1638.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-KWbQUeg5Lz0/Thht6anfFGI/AAAAAAAABLE/gfOE_kbfhiY/s320/IMG_1638.JPG" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;It was pretty steep, but in the end I did make it.&amp;nbsp; From the tip of the fort you could see the entire landscape.&amp;nbsp; There was no obstruction.&amp;nbsp; On one side you could see magnificent &lt;a href="http://en.wikipedia.org/wiki/Western_Ghats"&gt;Sahyadri range&lt;/a&gt; and on the other side you could see the &lt;a href="http://en.wikipedia.org/wiki/Mumbai_Pune_Expressway"&gt;Pune-Mumbai express way&lt;/a&gt;.&amp;nbsp; Clouds were passing right through us.&amp;nbsp; Its was simply beautiful!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-k66ngC8wZLU/Thh3xVBb74I/AAAAAAAABME/q5jae1-KJxk/s1600/IMG_1634.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://1.bp.blogspot.com/-k66ngC8wZLU/Thh3xVBb74I/AAAAAAAABME/q5jae1-KJxk/s320/IMG_1634.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-T1cvUcdmqNI/Thht3bp0StI/AAAAAAAABK4/ftYVemPqoKQ/s1600/IMG_1632.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-T1cvUcdmqNI/Thht3bp0StI/AAAAAAAABK4/ftYVemPqoKQ/s320/IMG_1632.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Later, at about 1400 hrs, we decided to start our descent.&amp;nbsp; While coming down one of our friend, twisted her ankle.&amp;nbsp; Luckily, it was not that bad.&amp;nbsp; After some rest she was able to walk normally.&amp;nbsp; We reached the base village at about 1545 hrs.&lt;br /&gt;&lt;br /&gt;It was trek a wonderful trek with breathtaking views on the way and at the top.&amp;nbsp; But the most important USP for me were, those moments at the top when I was at peace with myself!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I would strongly recommend everyone to do treks on a regular basis.&amp;nbsp; Oh! almost forgot, all 4 kids did manage to do the entire trek by themselves.&amp;nbsp; No one had to carry them, in fact the kids carried their bags all by themselves!&lt;br /&gt;&lt;br /&gt;If 8 year old kids can do the trek without any problems, so can you!&amp;nbsp; Go for it, I can assure you, you will return completely rejuvenated!&lt;br /&gt;&lt;br /&gt;PS: To view all pictures visit this &lt;a href="https://picasaweb.google.com/sapna.d.shah/Lohagadh"&gt;link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3006079540713871165?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3006079540713871165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/07/lohagad-nature-at-its-best-rejuvenate.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3006079540713871165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3006079540713871165'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/07/lohagad-nature-at-its-best-rejuvenate.html' title='Lohagad - Nature at its best - Rejuvenate yourself'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-mP8ZuyurJzA/ThhteRSfJGI/AAAAAAAABJk/g5y7IpVrQm0/s72-c/IMG_1440.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-7574205382197969869</id><published>2011-06-25T13:12:00.001+05:30</published><updated>2011-06-25T13:19:10.355+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='turn by turn directions'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Driving Directions'/><category scheme='http://www.blogger.com/atom/ns#' term='android emulator'/><category scheme='http://www.blogger.com/atom/ns#' term='intent'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>How to show turn by turn directions on Android</title><content type='html'>As you can probably make out, these days I am working on an Android project.&amp;nbsp; And I will tell you one thing, &lt;i&gt;I am loving it!&lt;br /&gt;&lt;/i&gt;I have worked on iOS, BREW and Simbian OS in the past but the productivity, while developing on Android is far better than the other platforms!&lt;br /&gt;&lt;br /&gt;Excellent job Android guys!&lt;br /&gt;&lt;br /&gt;Coming back to the post topic, recently I in one of the Android projects, we had a requirement that we wanted to show &lt;span style="font-size: large;"&gt;turn by turn directions&lt;/span&gt; between two geo points.&lt;br /&gt;&lt;br /&gt;We are all familier with the excellent support for &lt;span style="font-size: large;"&gt;Turn by turn directions&lt;/span&gt; on the native &lt;a href="http://www.google.com/mobile/maps/"&gt;Google Maps application&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Although, Android API permits us embed a maps view in the application, but it does not provide a way to show turn by turn directions between two geo points.&lt;br /&gt;&lt;br /&gt;In early days of Android (SDK 1.0), Google had provided the DrivingDirections class.&amp;nbsp; Using this class it was possible to get the driving directions between two geo points.&amp;nbsp; However, since SDK 1.1, Google removed the DrivingDirections class from the API.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why would they remove something as useful as this?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Because it violated some of the legal agreements made by Google.&amp;nbsp; Extract from the &lt;a href="http://code.google.com/apis/maps/terms.html"&gt;Google Maps terms &lt;/a&gt;states that&lt;br /&gt;&lt;blockquote&gt;8.3    &lt;u&gt;Content License&lt;/u&gt;. Subject to these Terms (including but not limited   to Section 9 (License Requirements) and Section 10 (License Restrictions)),   Google gives you a personal, worldwide,   royalty-free, non-transferable, non-assignable, and non-exclusive license to access,   use, publicly perform and publicly display the Content in your Maps   API Implementation, as the Content is provided in the Service, and   in the manner permitted by the Terms.  Specifically, you understand   the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;(a) Content (including but not limited to map data,              traffic, directions, and places) is provided for planning              purposes only.  You may find that weather conditions,              construction projects, closures, or other events may cause              road conditions or directions to differ from the results              depicted in the Content.  You should exercise judgment in              your use of the Content.&lt;br /&gt;(b)    Certain Content is provided              under &lt;a href="http://www.google.com/intl/en-us/help/legalnotices_maps.html" id="nalu" target="_top" title="license from third parties"&gt;license from third parties&lt;/a&gt;, including              Tele Atlas B.V. ("&lt;b&gt;Tele Atlas&lt;/b&gt;"), and is subject              to copyright and other intellectual property rights              owned by or licensed to Tele Atlas and/or such third              parties. You may be held liable for any unauthorized              copying or disclosure of this content.  Your use              of Tele Atlas map data and certain other Content (including              certain business listings Content) is subject to additional              restrictions located in the &lt;a href="http://www.google.com/intl/en-us/help/legalnotices_maps.html" id="smzl" target="_top" title="Legal Notices"&gt;Legal Notices&lt;/a&gt; page.&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&amp;nbsp;In simple terms, Google has tied up with many Third party companies to get the mapping and other information.&amp;nbsp; The terms of the agreement do not allow them to expose those functionality in an open source project.&amp;nbsp; This is the reason why they removed the DrivingDirections API since SDK 1.1&lt;br /&gt;&lt;br /&gt;All right fine!&amp;nbsp; Google could not expose that as API's, but we sill have this requirement to fulfill.&amp;nbsp; We want to show &lt;span style="font-size: large;"&gt;turn by turn&lt;/span&gt; directions between two geo points on Android platform.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do we do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As we all know that the native &lt;i&gt;Google Maps&lt;/i&gt; application (which comes pre-installed on all Android devices) does a great job of showing Turn by Turn driving directions.&amp;nbsp; The updated application also provides a link to &lt;a href="http://www.google.com/mobile/navigation/"&gt;Google Navigate (beta)&lt;/a&gt; which shows 3D maps and updates the route as the user location changes.&lt;br /&gt;&lt;br /&gt;We should definitely try and make use of this feature for our requirement.&amp;nbsp; After all, why reinvent the wheel!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hence now, our tasks are:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;To invoke the native google maps application&lt;/li&gt;&lt;li&gt;Show turn by turn directions between two geo points on the native google maps application&lt;/li&gt;&lt;/ul&gt;One very big plus of the Android platform is that, it has multitasking support.&amp;nbsp; Because of this, when user clicks the back button on the phone, they will come back to our application, user does not feel they are navigating away from our application.&amp;nbsp; This enhances the user experience quite a lot!&lt;br /&gt;&lt;br /&gt;So the questions is how do we invoke the native Google Maps application to show turn by turn direction between two geo points!&lt;br /&gt;&lt;br /&gt;Inter process/activity communication on Android platform is done via an &lt;a href="http://developer.android.com/reference/android/content/Intent.html"&gt;Intent&lt;/a&gt;.&amp;nbsp; Hence the answer to our question is: Via an Intent!&lt;br /&gt;&lt;br /&gt;Yes and that's the correct answer!&amp;nbsp; But what Intent, what will be the URL, what should be the parameters?&lt;br /&gt;&lt;br /&gt;Slow down, slow down, lets tackle one problem at a time!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;This is how they do it!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Looking at &lt;a href="http://developer.android.com/guide/appendix/g-app-intents.html"&gt;this URL&lt;/a&gt; it seems that we can invoke the native maps application using the following URLs&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[geo:latitude,longitudegeo:latitude,longitude?z=zoomgeo:0,0?q=my+street+addressgeo:0,0?q=business+near+city]]&gt;&lt;/script&gt;&lt;br /&gt;One line description for the above url's is&lt;br /&gt;&lt;blockquote&gt;Opens the Maps application to the given location or query. The Geo URI scheme (not fully supported) is &lt;a href="http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00"&gt;currently under development&lt;/a&gt;.&lt;br /&gt;The z field specifies the zoom level. A zoom level of 1 shows the whole Earth, centered at the given lat,lng. A zoom level of 2 shows a quarter of the Earth, and so on. The highest zoom level is 23. A larger zoom level will be clamped to 23. &lt;/blockquote&gt;Basically, the description says that, The above URLs will show the maps application which is centered around the given geo point&lt;br /&gt;&lt;br /&gt;Hence, &lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[showDirections.setOnClickListener(new View.OnClickListener() {            public void onClick(final View view) {                startActivity(new Intent(Intent.ACTION_VIEW,                        Uri.parse("geo:43.0054446,-87.9678884")));            } });]]&gt;&lt;/script&gt;&lt;br /&gt;This code will actuall open up the native map application which is centered around the given geo point.  We have solved one task from our task list.  We have managed to invoke the native google maps application!&lt;br /&gt;&lt;br /&gt;But wait!&amp;nbsp; We want to show two points not just one point on the map.&amp;nbsp; We also want to show turn by turn directions between those points!&lt;br /&gt;&lt;br /&gt;Using the URL i.e. the &lt;i&gt;&lt;b&gt;geo:x:y&lt;/b&gt;&lt;/i&gt; in the above format, we cannot specify two geo points.&amp;nbsp; Damn!&lt;br /&gt;&lt;br /&gt;I tried many permutations &amp;amp; combinations to specify the second geo point, but nothing worked.&lt;br /&gt;&lt;br /&gt;Finally, after a lot of trials and errors I found a workaround to this problem.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;This is how its actually done!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The URL &lt;i&gt;&lt;b&gt;geo:x,y&lt;/b&gt;&lt;/i&gt; &lt;span style="font-size: large;"&gt;does not support the second geo point&lt;/span&gt;, hence we can't use that URL.&amp;nbsp; What is the other URL we could use, which will show turn by turn directions between two geo points?&lt;br /&gt;&lt;br /&gt;After some more googling, I found that, &lt;span style="font-size: large;"&gt;we might be able to use the URL format used by&amp;nbsp; &lt;a href="http://maps.google.com/"&gt;maps.google.com&lt;/a&gt; website&lt;/span&gt;.&amp;nbsp; The maps.google.com follows a simple url pattern&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[http://maps.google.com/maps?  saddr=&lt;long,lat values of source address&gt;  &amp;daddr=[long, lat values of destination address]http://maps.google.com/maps?  saddr=43.0054446,-87.9678884  &amp;daddr=42.9257104,-88.0508355]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;span style="font-size: large;"&gt;maps.google.com uses two parameters "saddr" (source address) and "daddr" (destination address)&lt;/span&gt;.  If we pass those two parameters correctly it shows, turn by turn directions between those points.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-2WKI1VGeGp8/TgWF07Vj8ZI/AAAAAAAABIs/XRAX_wH4VEE/s1600/turn-by-turn-web.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="115" src="http://2.bp.blogspot.com/-2WKI1VGeGp8/TgWF07Vj8ZI/AAAAAAAABIs/XRAX_wH4VEE/s320/turn-by-turn-web.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Web Based Turn-By-Turn Directions on Google Maps&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;b&gt;Why are we even bothered about viewing turn by turn directions on the web?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Because guess what, &lt;span style="font-size: large;"&gt;we can use the same web based URL pattern on the Android platform!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What?&amp;nbsp; Yes, we can use the URL &lt;i&gt;http://maps.google.com/maps?saddr=43.0054446,-87.9678884&amp;amp;daddr=42.9257104,-88.0508355&lt;/i&gt; to open up the Google Maps application to see turn by turn directions between two geo points!&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[showDirections.setOnClickListener(new View.OnClickListener() { public void onClick(final View view) {       final Intent intent = new Intent(Intent.ACTION_VIEW,       /** Using the web based turn by turn directions url. */       Uri.parse(                "http://maps.google.com/maps?" +                "saddr=43.0054446,-87.9678884" +                "&amp;daddr=42.9257104,-88.0508355"));       startActivity(intent); }});]]&gt;&lt;/script&gt;&lt;br /&gt;The above code surely works!  It shows the user, turn by turn directions between the geo points [43.0054446,-87.9678884] and [42.9257104,-88.0508355].&lt;br /&gt;&lt;br /&gt;There is only one problem though, Android platform identifies that the above URL can be processed by two Activities!&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;The Browser Activity&lt;/b&gt; - Since the URL starts with &lt;i&gt;http://&lt;/i&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The Google Maps Activity&lt;/b&gt; - Since the address we are opening up is &lt;a href="http://maps.google.com/"&gt;maps.google.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Whenever Android platform has more than one options to process an intent, it leaves the choice to users, gives them an option of both the applications and lets them chose the application to fulfill the intent.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Nnotskh3UD4/TgWHUka86qI/AAAAAAAABIw/I_15DZ8o0bU/s1600/chooseApplication.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="254" src="http://3.bp.blogspot.com/-Nnotskh3UD4/TgWHUka86qI/AAAAAAAABIw/I_15DZ8o0bU/s320/chooseApplication.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;User gets an option to chose the application for the processing the Maps URL&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;User can chose either application, both show driving directions between those two geo points.&lt;br /&gt;&lt;br /&gt;Driving directions using the browser application&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-3JqkFCJCf3Q/TgWQLIpbpmI/AAAAAAAABI4/y-7IDkZAFHo/s1600/browserTurnByTurn.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-3JqkFCJCf3Q/TgWQLIpbpmI/AAAAAAAABI4/y-7IDkZAFHo/s320/browserTurnByTurn.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Driving directions using the Native Google Maps application&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-A0odIdM528M/TgWK2Wj0FEI/AAAAAAAABI0/v6FQXbun-qw/s1600/nativeGoogleMapsWithDirections.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-A0odIdM528M/TgWK2Wj0FEI/AAAAAAAABI0/v6FQXbun-qw/s320/nativeGoogleMapsWithDirections.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;How to make this solution better:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Although we have achieved what we intended for.&amp;nbsp; But there is one extra step that user has to perform, i.e. select the application of his choice to see the driving directions.&amp;nbsp; At this point, user might notice that he is going out of the current application and into a different application.&amp;nbsp; There is nothing wrong with this approach but, it does not integrate the Google Maps application seamlessly with our application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do we eliminate this extra step of choosing the application to view turn by turn directions?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The answer is simple and we can do this by providing a hint in the Intent we are firing.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[showDirections.setOnClickListener(new View.OnClickListener() { public void onClick(final View view) {          final Intent intent = new Intent(Intent.ACTION_VIEW,          /** Using the web based turn by turn directions url. */          Uri.parse(                   "http://maps.google.com/maps?" +                   "saddr=43.0054446,-87.9678884" +                   "&amp;daddr=42.9257104,-88.0508355"));                /** Setting the Class Name that should handle                  *  this intent.  We are setting the class name to                  *  the class name of the native maps activity.                 *  Android platform recognizes this and now knows that                 *  we want to open up the Native Maps application to                 *  handle the URL.  Hence it does not give the choice of                 *  application to the user and directly opens the                  *  Native Google Maps application.                 */                intent.setClassName(                 "com.google.android.apps.maps",                 "com.google.android.maps.MapsActivity");          startActivity(intent); }});]]&gt;&lt;/script&gt;&lt;br /&gt;The line &lt;span style="font-size: large;"&gt;intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"); does the trick.&lt;/span&gt;  We are passing additional information in the Intent.  We are informing that, &lt;span style="font-size: large;"&gt;the class name of the activity that should fulfill the intent is "com.google.android.apps.maps/com.google.android.maps.MapsActivity"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's it!  Now Android platform knows that, user wants to see the turn by turn directions on the native google maps application and not on the browser.  The extra step of chosing the application is eliminated.&lt;br /&gt;&lt;br /&gt;User directly goes to this view&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ubgIBQIBnxw/TgWQy_I6GCI/AAAAAAAABI8/2AmAJneBc-Q/s1600/nativeDrivingDirectionsList.png" imageanchor="1"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-ubgIBQIBnxw/TgWQy_I6GCI/AAAAAAAABI8/2AmAJneBc-Q/s320/nativeDrivingDirectionsList.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;There are many advantage of this approach&lt;br /&gt;&lt;ul&gt;&lt;li&gt;User can choose to start navigation using &lt;b&gt;Google Navigate (beta)&lt;/b&gt; (without us doing anything).&lt;/li&gt;&lt;li&gt;User can click back button and return to our application as well!&lt;/li&gt;&lt;/ul&gt;As we can see, Android platform is pretty awesome, when it comes to ease of development!&amp;nbsp; Something as complex as showing turn by turn driving directions between two geo points can be achieved by writing 3 lines of code!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-7574205382197969869?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/7574205382197969869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/06/how-to-show-turn-by-turn-directions-on.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/7574205382197969869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/7574205382197969869'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/06/how-to-show-turn-by-turn-directions-on.html' title='How to show turn by turn directions on Android'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-2WKI1VGeGp8/TgWF07Vj8ZI/AAAAAAAABIs/XRAX_wH4VEE/s72-c/turn-by-turn-web.png' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-1682777240300055132</id><published>2011-06-22T09:00:00.005+05:30</published><updated>2011-06-25T11:04:07.031+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='options menu'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Handler'/><category scheme='http://www.blogger.com/atom/ns#' term='change text color of options menu'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='menu'/><category scheme='http://www.blogger.com/atom/ns#' term='LayoutInflater.Factory'/><category scheme='http://www.blogger.com/atom/ns#' term='IconMenuItemView'/><title type='text'>How to change the text color of Android options menu</title><content type='html'>As promised in the &lt;a href="http://www.gitshah.com/2011/06/how-to-change-background-color-of.html"&gt;previous post&lt;/a&gt;, here comes the second installment of styling the options menu.&amp;nbsp; In the &lt;a href="http://www.gitshah.com/2011/06/how-to-change-background-color-of.html"&gt;previous post&lt;/a&gt; we saw how we could change the background color of the options menu.&amp;nbsp; This time we are going to look at how we could change the text color of Android options menu.&lt;br /&gt;&lt;br /&gt;We already know that styling the options menu is not really easy.&amp;nbsp; As shown in the previous post, its a eight step process.&amp;nbsp; To change the text color of the options menu we need to put in another hack.&amp;nbsp; We need to add a ninth step.&amp;nbsp; Lets look at all nine steps once again. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Setting the custom &lt;i&gt;&lt;b&gt;LayoutInflater.Factory &lt;/b&gt;&lt;/i&gt;instance. &lt;/li&gt;&lt;li&gt;Implementing the &lt;i&gt;&lt;b&gt;onCreateView method &lt;/b&gt;&lt;/i&gt;that will actually set the background selector for the options menu.&lt;/li&gt;&lt;li&gt;In the implementation of &lt;i&gt;&lt;b&gt;onCreateView&lt;/b&gt;&lt;/i&gt;, check if the view that is to be created is of type &lt;span style="font-size: medium;"&gt;&lt;b&gt;com.android.internal.view.menu.IconMenuItemView&lt;/b&gt;&lt;/span&gt;.&amp;nbsp; Yes, I know, its an &lt;b&gt;*internal* &lt;/b&gt;class!&lt;/li&gt;&lt;li&gt;If the view is of type &lt;span style="font-size: medium;"&gt;IconMenuItemView &lt;/span&gt;then create the view using the &lt;i&gt;&lt;b&gt;LayoutInflater&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;At this point we have an instance of &lt;span style="font-size: medium;"&gt;IconMenuItemView &lt;/span&gt;but  we cannot change the background color of the view directly.&amp;nbsp; Even if we  change the background color at this point, framework updates it again  and our changes are overwritten&lt;/li&gt;&lt;li&gt;We have to &lt;span style="font-size: medium;"&gt;change the background color after the view has rendered&lt;/span&gt;, using the &lt;span style="font-size: medium;"&gt;&lt;a href="http://developer.android.com/reference/android/os/Handler.html"&gt;Handler&lt;/a&gt; API&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Change the background color in run method of the &lt;i&gt;&lt;b&gt;Runnable instance &lt;/b&gt;&lt;/i&gt;that we pass to the &lt;a href="http://developer.android.com/reference/android/os/Handler.html#post%28java.lang.Runnable%29"&gt;Handler's post method&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Change the text color using reflection.&amp;nbsp; This is the new step.&amp;nbsp; We need to change the text color using reflection.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Catch all exceptions that could occur in the entire process.&amp;nbsp; Notice  that, we are using an internal class there are high changes that its  behavior could change without any notice.&amp;nbsp; In fact this approach does  not work on &lt;a href="http://developer.android.com/sdk/android-2.3-highlights.html"&gt;Android 2.3&lt;/a&gt;.&amp;nbsp; In this case we have to fallback to the default menu styling.&lt;/li&gt;&lt;/ol&gt;Lets look at code to make things clear&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class ChangeMenuBackgroundColorActivity extends Activity {     /**     * {@inheritDoc}     */    @Override    protected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.change_menu_background);    }     /**     * Creating the options menu.     * Should show two items in the options menu, Menu1 and Menu2.     * {@inheritDoc}     */    @Override    public boolean onCreateOptionsMenu(Menu menu) {        menu.add(1, 1, 0, "Menu1");        menu.add(1, 1, 0, "Menu2");        //Calling a method to set the backgournd color of the options menu        setMenuBackground();        return true;    }     /**     * Sets the menu items background.     */    private void setMenuBackground() {        /** Step 1. setting the custom LayoutInflater.Factory instance. */        getLayoutInflater().setFactory(new LayoutInflater.Factory() {             /**             * Step 2. Implementing the onCreateView method              * that will actually set the background selector.             * {@inheritDoc}             */            public View onCreateView(final String name,                                      final Context context,                                      final AttributeSet attributeSet) {                /**                 *  Step 3. Checking if the view that is to be created                  *  is IconMenuItemView.                 *  Notice that this is an internal class.                 */                if (name.equalsIgnoreCase                      ("com.android.internal.view.menu.IconMenuItemView")) {                    try {                        /**                         * Step 4. If the view is IconMenuItemView then                          * create the view using the LayoutInflater.                         */                        final LayoutInflater f = getLayoutInflater();                        final View view = f.createView(name, null, attributeSet);                        /**                         * Step 5. This is the key part.                           * The view instance that was created in step 4                          * is an instance of IconMenuItemView.                           * This is the view whose background color                          * we want to change.  Unfortunately we just cannot                          * change the background color at this place,                          * since even if we change it here,                          * framework overrides this value and                          * we see the default background selector.                         * Because of this reason the below line is commented.                           * It does not work.                         */                        //view.setBackgroundResource(R.drawable.menu_selector);                        /**                         * Step 6. We have to change the background color                          * after the view has rendered, using the Handler api.                         */                        new Handler().post(new Runnable() {                            public void run() {                               /** Step 7.  Changing the backgound color. */                               view.setBackgroundResource(                                               R.drawable.menu_selector);                                /** Step 8.  Setting the text color                                  *  via reflection.                                 */                                setTextColor(view);                            }                        });                        return view;                    } catch (final Exception e) {                        /**                         * Step 9.  Catching all exceptions that could occur                          * in the process.  This is necessary since                          * on Android 2.3, styling the internal                          * IconMenuItemView throws an exception.                           * Hence we have to fallback to the default menu styles.                         */                        Log.e("##Menu##",                               "Could not create a custom view for menu: "                                                      + e.getMessage(), e);                    }                }                return null;            }        });    }    /**     * Sets the text color for the view using reflection.       * We have to use reflection for changing the text color of the options menu     * because, there is no public setTextColor method in the View class.     * @param view the view whose text color is to be set.     */    private void setTextColor(final View view) {        try {            final Method setTextColor = view.getClass()                    .getMethod("setTextColor", int.class);            setTextColor.invoke(view, "0x80FFFFFF");        } catch (Exception e) {            Log.e("##Menu##",                    "Error while setting the text color: "                                         + e.getMessage(), e);        }    }}]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;b&gt;&lt;i&gt;menu_selector.xml&lt;/i&gt;&lt;/b&gt; and &lt;b&gt;&lt;i&gt;colors.xml&lt;/i&gt;&lt;/b&gt; have been kept unchanged from the previous post.&amp;nbsp; The comments are embedded in the code.&amp;nbsp; One new methods has been added setTextColor.&amp;nbsp; This method does the job for us!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-UOs9KxmRP7g/TfzsOTeWXQI/AAAAAAAABIY/zkHyXb-Cd4M/s1600/menu_focused.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-UOs9KxmRP7g/TfzsOTeWXQI/AAAAAAAABIY/zkHyXb-Cd4M/s320/menu_focused.png" width="215" /&gt;&lt;/a&gt;&lt;/div&gt;The above screenshot shows the menu item color changes when its pressed.&lt;br /&gt;&lt;br /&gt;That's it!&amp;nbsp; We have successfully changed the background color and text color of Android options menu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-1682777240300055132?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/1682777240300055132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/06/how-to-change-text-color-of-android.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/1682777240300055132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/1682777240300055132'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/06/how-to-change-text-color-of-android.html' title='How to change the text color of Android options menu'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-UOs9KxmRP7g/TfzsOTeWXQI/AAAAAAAABIY/zkHyXb-Cd4M/s72-c/menu_focused.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3270963727160205454</id><published>2011-06-18T17:21:00.001+05:30</published><updated>2011-06-18T17:23:50.013+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='change background color of options menu'/><category scheme='http://www.blogger.com/atom/ns#' term='options menu'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Handler'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='menu'/><category scheme='http://www.blogger.com/atom/ns#' term='LayoutInflater.Factory'/><category scheme='http://www.blogger.com/atom/ns#' term='IconMenuItemView'/><title type='text'>How to change the background color of Android options menu</title><content type='html'>I have been trying my hand at developing apps with Android.&amp;nbsp; I have had my fair share of leanings.&amp;nbsp; Today I am going to share my experience around styling the options menu in Android.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is the options menu?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Options menu is the menu that is shown to the user when the &lt;i&gt;Menu&lt;/i&gt; key is pressed on the Android phone.&lt;br /&gt;&lt;br /&gt;Lets look at an example, that will make things easier to understand.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class ChangeMenuBackgroundColorActivity extends Activity {    /**     * {@inheritDoc}     */    @Override    protected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //Setting the layout to change_menu_background.        setContentView(R.layout.change_menu_background);    }    /**     * Creating the options menu.     * Should show two items in the options menu, Menu1 and Menu2.     * {@inheritDoc}     */    @Override    public boolean onCreateOptionsMenu(Menu menu) {        menu.add(1, 1, 0, "Menu1");        menu.add(1, 1, 0, "Menu2");        return true;    }}]]&gt;&lt;/script&gt;&lt;br /&gt;The layout file.&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;linearlayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="fill_parent"              android:layout_height="fill_parent"               android:background="@drawable/header_background"&gt;    &lt;textview android:id="@+id/some_text"               android:layout_height="wrap_content"              android:layout_width="fill_parent"              android:text="Some content here"               android:textColor="@color/white"              android:layout_marginTop="100dp"               android:layout_marginLeft="5dp"               android:textSize="22dp" /&gt;&lt;/LinearLayout&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The above code shows the following GUI&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HzNiZw6lKYc/TfyK8FH0YjI/AAAAAAAABIQ/zUVxqQr6-_I/s1600/options_menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="210" src="http://2.bp.blogspot.com/-HzNiZw6lKYc/TfyK8FH0YjI/AAAAAAAABIQ/zUVxqQr6-_I/s320/options_menu.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;As you can see from the above screenshot the background color of the Activity is greenish while the default Color of the selected element of the options menu is Orange.&lt;br /&gt;&lt;br /&gt;It definitely looks inconsistent and ugly.&amp;nbsp; This is the reason we need to style the options menu to match the rest of the application theme.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Android platform is highly configurable&lt;/span&gt;.&amp;nbsp; One can change all aspects of look and feel on the android platform.&amp;nbsp; Hence, when this task was given to me, I thought it would be a 2 min fix.&amp;nbsp; But unfortunately it took much longer than I expected.&lt;br /&gt;&lt;br /&gt;All I wanted to do is change the background selector of the options menu.&amp;nbsp; Android does not provide a straight forward way to do this.&amp;nbsp; In fact, it meant writing quiet some code.&amp;nbsp; I decided to write a post on this, so that other can benefit from my learning's.&lt;br /&gt;&lt;br /&gt;So back to the original question.&amp;nbsp; How do we change the background color of Android options menu?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How do they do it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now there is nothing fancy about the above code.&amp;nbsp; But to change the background color we have to write some fancy code :)&lt;br /&gt;&lt;br /&gt;Changing the options menu background color is a 8 step process&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Setting the custom &lt;i&gt;&lt;b&gt;LayoutInflater.Factory &lt;/b&gt;&lt;/i&gt;instance. &lt;/li&gt;&lt;li&gt;Implementing the &lt;i&gt;&lt;b&gt;onCreateView method &lt;/b&gt;&lt;/i&gt;that will actually set the background selector for the options menu.&lt;/li&gt;&lt;li&gt;In the implementation of &lt;i&gt;&lt;b&gt;onCreateView&lt;/b&gt;&lt;/i&gt;, check if the view that is to be created is of type &lt;span style="font-size: large;"&gt;&lt;b&gt;com.android.internal.view.menu.IconMenuItemView&lt;/b&gt;&lt;/span&gt;.&amp;nbsp; Yes, I know, its an &lt;b&gt;*internal* &lt;/b&gt;class!&lt;/li&gt;&lt;li&gt;If the view is of type &lt;span style="font-size: large;"&gt;IconMenuItemView &lt;/span&gt;then create the view using the &lt;i&gt;&lt;b&gt;LayoutInflater&lt;/b&gt;&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;At this point we have an instance of &lt;span style="font-size: large;"&gt;IconMenuItemView &lt;/span&gt;but we cannot change the background color of the view directly.&amp;nbsp; Even if we change the background color at this point, framework updates it again and our changes are overwritten&lt;/li&gt;&lt;li&gt;We have to &lt;span style="font-size: large;"&gt;change the background color after the view has rendered&lt;/span&gt;, using the &lt;span style="font-size: large;"&gt;&lt;a href="http://developer.android.com/reference/android/os/Handler.html"&gt;Handler&lt;/a&gt; API&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Change the background color in run method of the &lt;i&gt;&lt;b&gt;Runnable instance &lt;/b&gt;&lt;/i&gt;that we pass to the &lt;a href="http://developer.android.com/reference/android/os/Handler.html#post%28java.lang.Runnable%29"&gt;Handler's post method&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Catch all exceptions that could occur in the entire process.&amp;nbsp; Notice that, we are using an internal class there are high changes that its behavior could change without any notice.&amp;nbsp; In fact this approach does not work on &lt;a href="http://developer.android.com/sdk/android-2.3-highlights.html"&gt;Android 2.3&lt;/a&gt;.&amp;nbsp; In this case we have to fallback to the default menu styling.&lt;/li&gt;&lt;/ol&gt;Yep, I know, it looks like a lot of work and pretty complex too.&amp;nbsp; Lets look at the code to make things more clear.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class ChangeMenuBackgroundColorActivity extends Activity {    /**     * {@inheritDoc}     */    @Override    protected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.change_menu_background);    }    /**     * Creating the options menu.     * Should show two items in the options menu, Menu1 and Menu2.     * {@inheritDoc}     */    @Override    public boolean onCreateOptionsMenu(Menu menu) {        menu.add(1, 1, 0, "Menu1");        menu.add(1, 1, 0, "Menu2");        //Calling a method to set the backgournd color of the options menu        setMenuBackground();        return true;    }    /**     * Sets the menu items background.     */    private void setMenuBackground() {        /** Step 1. setting the custom LayoutInflater.Factory instance. */        getLayoutInflater().setFactory(new LayoutInflater.Factory() {            /**             * Step 2. Implementing the onCreateView method              * that will actually set the background selector.             * {@inheritDoc}             */            public View onCreateView(final String name,                                      final Context context,                                      final AttributeSet attributeSet) {                /**                 *  Step 3. Checking if the view that is to be created                  *  is IconMenuItemView.                 *  Notice that this is an internal class.                 */                if (name.equalsIgnoreCase                      ("com.android.internal.view.menu.IconMenuItemView")) {                    try {                        /**                         * Step 4. If the view is IconMenuItemView then                          * create the view using the LayoutInflater.                         */                        final LayoutInflater f = getLayoutInflater();                        final View view = f.createView(name, null, attributeSet);                        /**                         * Step 5. This is the key part.                           * The view instance that was created in step 4                          * is an instance of IconMenuItemView.                           * This is the view whose background color                          * we want to change.  Unfortunately we just cannot                          * change the background color at this place,                          * since even if we change it here,                          * framework overrides this value and                          * we see the default background selector.                         * Because of this reason the below line is commented.                           * It does not work.                         */                        //view.setBackgroundResource(R.drawable.menu_selector);                        /**                         * Step 6. We have to change the background color                          * after the view has rendered, using the Handler api.                         */                        new Handler().post(new Runnable() {                            public void run() {                               /** Step 7.  Changing the backgound color. */                               view.setBackgroundResource(                                               R.drawable.menu_selector);                            }                        });                        return view;                    } catch (final Exception e) {                        /**                         * Step 8.  Catching all exceptions that could occur                          * in the process.  This is necessary since                          * on Android 2.3, styling the internal                          * IconMenuItemView throws an exception.                           * Hence we have to fallback to the default menu styles.                         */                        Log.e("##Menu##",                               "Could not create a custom view for menu: "                                                       + e.getMessage(), e);                    }                }                return null;            }        });    }}]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;span style="font-size: large;"&gt;menu_selector is an XML &lt;/span&gt;file that choses the background color based on the state of the menu item.&amp;nbsp; My menu_selector.xml looks like this&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;    &lt;item android:state_pressed="true" android:drawable="@color/menu_pressed"/&gt;    &lt;item android:state_focused="true" android:drawable="@color/menu_focused"/&gt;    &lt;item android:drawable="@color/menu_normal"/&gt;&lt;/selector&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The colors.xml file looks like&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[    &lt;color name="menu_normal"&gt;#ff000000&lt;/color&gt;    &lt;color name="menu_focused"&gt;#ff097400&lt;/color&gt;    &lt;color name="menu_pressed"&gt;#ff005E24&lt;/color&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;The comments are embedded in the code. One new methods has been added called setMenuBackground.  This method does the job for us!&lt;br /&gt;&lt;br /&gt;The screenshots of the styled options menu&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-gu9VNiL8QyU/TfyQLNDhOFI/AAAAAAAABIU/eo6fad-y51k/s1600/menu_pressed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-gu9VNiL8QyU/TfyQLNDhOFI/AAAAAAAABIU/eo6fad-y51k/s320/menu_pressed.png" width="217" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;As we can see the Options Menu background color has been changed from Orange to greenish.&lt;br /&gt;&lt;br /&gt;That's all folks!&lt;br /&gt;&lt;br /&gt;We have successfully changed the background color of Android options men.&amp;nbsp; But wait a minute, how to change the default text color of the Android options menu?&amp;nbsp; If this question is bothering you stay tuned, in the next post I am going to explain exactly that!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3270963727160205454?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3270963727160205454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/06/how-to-change-background-color-of.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3270963727160205454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/3270963727160205454'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/06/how-to-change-background-color-of.html' title='How to change the background color of Android options menu'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-HzNiZw6lKYc/TfyK8FH0YjI/AAAAAAAABIQ/zUVxqQr6-_I/s72-c/options_menu.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-4300771120059765120</id><published>2011-06-11T14:46:00.001+05:30</published><updated>2011-06-18T16:51:00.453+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='fixing'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='259'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='max path length'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='The referenced project does not exist'/><category scheme='http://www.blogger.com/atom/ns#' term='visual studio 2010'/><title type='text'>Visual Studio 2010 Fixing "The referenced project XX does not exist" Error</title><content type='html'>Recently one of my friend was facing a weird issue while building our application.  The application was developed in C#.  We were using &lt;a href="http://msdn.microsoft.com/en-us/library/0k6kkbsd.aspx"&gt;MSBuild&lt;/a&gt; as the build tool.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What was the issue?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The issue was simple, she was not able to compile the application.&lt;br /&gt;&lt;br /&gt;The issue was special in many ways because, all of us (i.e. her team members) were able to compile the project just fine.  Even the continuous integration service - &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; (formally &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;), was able to compile the application.  We were &lt;span style="font-size: large;"&gt;not able to compile the application only on her machine&lt;/span&gt;.  The build failed with the error&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1200,9): warning : The referenced project '..\..\..\abcdefgh.dosomeprojects\abcdefgh.dosomeprojects.Common\abcdefgh.dosomeprojects.Common.csproj' does not exist. [E:\projects\ABC\SVN\dosomeprojectsweb\trunk\AB.dosomeprojects.Services\AB.dosomeprojects.Services.FillImporter\AB.dosomeprojects.Services.FillImporter.Service\AB.dosomeprojects.Services.FillImporter.Service.csproj]]]&gt;&lt;/script&gt;&lt;br /&gt;The project &lt;i&gt;"AB.dosomeprojects.Services.FillImporter.Service.csproj" &lt;/i&gt;referred the project &lt;i&gt;"abcdefgh.dosomeprojects.Common.csproj" &lt;/i&gt;which was in the path &lt;i&gt;"..\..\..\abcdefgh.dosomeprojects\abcdefgh.dosomeprojects.Common"&lt;/i&gt;.  The path was relative to the Service project directory.&lt;br /&gt;&lt;br /&gt;The directory structure was correct, &lt;i&gt;Common project&lt;/i&gt; was correctly reffered from the &lt;i&gt;Service project,&lt;/i&gt; but still we were not able to build the app on her machine.&lt;br /&gt;&lt;br /&gt;Initially, we thought that there must me some local changes on her machine because of which, she was not able to run the build on her machine.&amp;nbsp; Build was not passing neither with Visual Studio 2010 nor with MSBuild and that too only on her machine.&lt;br /&gt;&lt;br /&gt;We looked for any local changes on her machine, but unfortunately her machine was clean.&amp;nbsp; There were no local changes.&amp;nbsp; We were simply clueless!&amp;nbsp; Why does the project build fine on other developers machine while it does not build on her machine?&lt;br /&gt;&lt;br /&gt;After some intense Googling, we found an interesting &lt;span style="font-size: large;"&gt;hidden treasure&lt;/span&gt; shipped silently by &lt;span style="font-size: large;"&gt;Microsoft Visual Studio 2010&lt;/span&gt;.&amp;nbsp; I call such issues as hidden treasure because, I can hardly believe my ears when I hear/read about such an issue.&lt;br /&gt;&lt;br /&gt;I am sure it will come as an surprise to you as well.&amp;nbsp; The issue is:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Real Problem:&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Visual Studio 2010 fails to build the project when the following conditions are met:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Solution with multiple projects exists, where there exists dependency relationships among them&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;The sum of the following two path length is exactly added up to 259 characters (= MAX_PATH – 1)&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;The path of a referencing project’s directory.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;The relative path to a referenced project from the current directory (= a referencing project’s directory).&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;Hmm, cryptic information lets decrypt it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Condition&lt;/b&gt;&lt;b&gt; 1:&lt;/b&gt; We have solution with multiple projects where there exists dependency relationships among them&lt;br /&gt;&lt;br /&gt;Yes, we do have the solution with multiple projects in it and one project depends on the other.&amp;nbsp; In our case the &lt;i&gt;AB.dosomeprojects.Services.FillImporter.Service.csproj &lt;/i&gt;depends on the &lt;i&gt;abcdefgh.dosomeprojects.Common.csproj &lt;/i&gt;project.&amp;nbsp; Hence, &lt;b&gt;condition 1 is met&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Condition 2:&lt;/b&gt; The sum of the following two path length is exactly added up to 259 characters (= MAX_PATH – 1)&lt;br /&gt;&lt;br /&gt;This one is tricky.&amp;nbsp; Which path sum are we talking about?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Condition 2.1:&lt;/b&gt; The path of a referencing project’s directory.&lt;br /&gt;&lt;br /&gt;The path of the referencing project's directory, in our case the path of the &lt;i&gt;AB.dosomeprojects.Services.FillImporter.Service.csproj &lt;/i&gt;on the file system, which was, &lt;i&gt;"E:\projects\ABC\SVN\dosomeprojectsweb\trunk\AB.dosomeprojects.Services\AB.dosomeprojects.Services.FillImporter\AB.dosomeprojects.Services.FillImporter.Service"&lt;/i&gt; &lt;span style="font-size: large;"&gt;has total length of 158 chars&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Condition 2.2: &lt;/b&gt;The relative path to a referenced project from the current directory (= a referencing project’s directory).&lt;br /&gt;&lt;br /&gt;The relative path of the referenced project from the current directory, in our case its the relative path of abcdefgh.dosomeprojects.Common.csproj, which is, "..\..\..\abcdefgh.dosomeprojects\abcdefgh.dosomeprojects.Common\abcdefgh.dosomeprojects.Common.csproj" &lt;span style="font-size: large;"&gt;has total length of 101 chars.&lt;br /&gt;&lt;br /&gt;The sum total of these two path lengths: 158 + 101 = 259!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Wow! condition 2 is also met.&lt;br /&gt;&lt;br /&gt;As I said, we have &lt;span style="font-size: large;"&gt;uncovered an hidden treasure of Visual Studio 2010.&lt;/span&gt;&amp;nbsp; Its unable to build the project when the &lt;span style="font-size: large;"&gt;path length of referencing project + path length of relative path to a referenced project = 259!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the &lt;span style="font-size: large;"&gt;sum total is one less or one greater than 259 it all works fine!&lt;/span&gt;  On other developers machine the total path length was less than or greater than 259 but was never equal to 259 and because of this reason we were all able to build the project but she was not able to build the project on her machine!  Weird isn't?&lt;br /&gt;&lt;br /&gt;This issue occurs due to a &lt;span style="font-size: large;"&gt;bug in the Path.GetFullPath in .NET Framework library.&lt;/span&gt;&amp;nbsp; This is a known issue in Visual Studio 2010.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Fix:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The workaround is pretty straight forward, &lt;span style="font-size: large;"&gt;rename one of the folders a bit longer or a bit shorter and make sure that, the sum of the two path length is NOT equal to 259 chars&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For more information on the issue visit the offical Microsoft Knowledge base article here &lt;a href="http://support.microsoft.com/kb/2516078"&gt;http://support.microsoft.com/kb/2516078&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Now you know, we are having so much fun with .Net (sarcasm intended)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-4300771120059765120?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/4300771120059765120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/06/visual-studio-2010-fixing-referenced.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4300771120059765120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4300771120059765120'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/06/visual-studio-2010-fixing-referenced.html' title='Visual Studio 2010 Fixing &quot;The referenced project XX does not exist&quot; Error'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-9174634256544810884</id><published>2011-05-28T11:50:00.003+05:30</published><updated>2011-05-28T11:55:26.441+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='web project'/><category scheme='http://www.blogger.com/atom/ns#' term='CI'/><category scheme='http://www.blogger.com/atom/ns#' term='jenkins'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='msbuild'/><category scheme='http://www.blogger.com/atom/ns#' term='continuous integration'/><category scheme='http://www.blogger.com/atom/ns#' term='visual studio 2010'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft.WebApplication.targets'/><title type='text'>How to build the web project on the CI server without Visual Studio 2010</title><content type='html'>On one of the &lt;a href="http://www.asp.net/"&gt;ASP.Net&lt;/a&gt; project, we were using &lt;a href="http://www.microsoft.com/visualstudio/en-us"&gt;Visual Studio 2010&lt;/a&gt; IDE and &lt;a href="http://msdn.microsoft.com/en-us/library/0k6kkbsd.aspx"&gt;MSBuild&lt;/a&gt;, to compile and build the application.&amp;nbsp; Pretty standard setup for a web project right?.&amp;nbsp; On developer machine all worked very smoothly, since each developer had Visual Studio 2010 installed locally on their machines.&lt;br /&gt;&lt;br /&gt;We setup a &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt; (CI) server &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; (formally &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;) for this project.&amp;nbsp; Naturally, we didn't wanted to install Visual Studio 2010 on the CI server.&amp;nbsp; But we still wanted to build our app on the CI server.&amp;nbsp; Hence, we installed &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35aeda01-421d-4ba5-b44b-543dc8c33a20"&gt;Microsoft Windows SDK 7.1&lt;/a&gt; and all its components on the CI server.&amp;nbsp; After installing the SDK, we were able to build all projects except the web project on the CI server.&lt;br /&gt;&lt;br /&gt;The error that we were getting was&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[error MSB4019: The imported project "C:\Program Files\ MSBuild\Microsoft\VisualStudio\v10.0\WebApplications \Microsoft.WebApplication.targets" was not found. Confirm that the path in the &lt;import&gt; declaration is correct, and that the file exists on disk.]]&gt;&lt;/script&gt;&lt;br /&gt;Obviously, since the Visual Studio 2010 was not installed on the CI server, the path mentioned in the error didn't exist and that's why the web project was not able to build.&lt;br /&gt;&lt;br /&gt;I opened the csproj file in &lt;a href="http://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt;, to find the reference of &lt;i&gt;&lt;span style="font-size: large;"&gt;"Microsoft.WebApplication.targets".&amp;nbsp; &lt;/span&gt;&lt;/i&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;I found a reference of &lt;i&gt;"Microsoft.WebApplication.targets"&lt;/i&gt; in the csproj which looked liked&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;script class="brush: xml" type="syntaxhighlighter"&gt;&lt;![CDATA[  &lt;import Project= "$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications    \Microsoft.WebApplication.targets" /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;Indeed the web csproj file had an import statement, which added the reference to &lt;i&gt;"Microsoft.WebApplication.targets"&lt;/i&gt;.  But I was not sure why this reference was needed in the first place.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My first attempt at fixing the CI server:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I removed the reference of &lt;i&gt;"Microsoft.WebApplication.targets" &lt;/i&gt;from the web csproj file and tried building the application using MSBuild.&amp;nbsp; To my surprise, &lt;span style="font-size: large;"&gt;the app build fine, it ran all the tests without any issue.&lt;/span&gt;&amp;nbsp; My confidence grew a little, I thought I had the solution.&amp;nbsp; I thought the reference was added to the csproj by Visual Studio 2010, but was never used.&lt;br /&gt;&lt;br /&gt;I committed the fix, build went green on the CI Server as well!&lt;br /&gt;&lt;br /&gt;After a few hours, some developers complained that, when they now open up the web project, &lt;span style="font-size: large;"&gt;Visual Studio 2010 prompted for converting the project into a Visual Studio 2010.&lt;/span&gt;&amp;nbsp; Certainly, this behaviour was triggered after I removed the import statement from the web csproj file.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-dYNLrUmi0TQ/TeCM_nxZudI/AAAAAAAABIM/bRhRk429A0Q/s1600/VisualStudio2010ConversionWizard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://1.bp.blogspot.com/-dYNLrUmi0TQ/TeCM_nxZudI/AAAAAAAABIM/bRhRk429A0Q/s320/VisualStudio2010ConversionWizard.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Its pretty clear now, why the import was required.&amp;nbsp; &lt;span style="font-size: large;"&gt;Visual Studio 2010 identifies that, the project is a Visual Studio 2010 Web project using the import of "&lt;/span&gt;&lt;i&gt;&lt;span style="font-size: large;"&gt;Microsoft.WebApplication.targets&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size: large;"&gt;".&lt;/span&gt;&amp;nbsp; Hence, although the build run's fine using MSbuild on developer machine as well as on CI server this is not the right fix!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My second attempt at fixing the CI server:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Googling a little I found that, there are only two options to fix this particular issue.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Install Visual Studio 2010 on the CI server&lt;/li&gt;&lt;li&gt;Copy the &lt;i&gt;"Microsoft.WebApplication.targets"&lt;/i&gt; file manually from any developer machine to the CI server&lt;/li&gt;&lt;/ul&gt;It was sad to see that there was no standalone installer that installed the &lt;i&gt;"Microsoft.WebApplication.targets" &lt;/i&gt;at the desired location.&amp;nbsp; We had to either install the full Visual Studio 2010 or copy the file manually.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I decided to chose the lesser evil of the two.&amp;nbsp; We copied the file &lt;i&gt;"Microsoft.WebApplication.targets"&lt;/i&gt; from my machine (located at path &lt;i&gt;&lt;b&gt;C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications&lt;/b&gt;&lt;/i&gt; on a Windows 7 64 Bit installation) onto the CI server (at the path &lt;i&gt;&lt;b&gt;C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications&lt;/b&gt;&lt;/i&gt;.&amp;nbsp; CI server has Windows 2003 OS installed on it.) and then ran the build.&amp;nbsp; Yep! It worked!&amp;nbsp; The build went green on the CI server.&lt;br /&gt;&lt;br /&gt;I know, its just an hack, but for now I had no other option!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-9174634256544810884?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/9174634256544810884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/05/how-to-build-web-project-on-ci-server.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/9174634256544810884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/9174634256544810884'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/05/how-to-build-web-project-on-ci-server.html' title='How to build the web project on the CI server without Visual Studio 2010'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-dYNLrUmi0TQ/TeCM_nxZudI/AAAAAAAABIM/bRhRk429A0Q/s72-c/VisualStudio2010ConversionWizard.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-4126467120451752180</id><published>2011-05-21T11:35:00.000+05:30</published><updated>2011-05-21T11:35:14.506+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='UIRequiresPersistentWiFi'/><category scheme='http://www.blogger.com/atom/ns#' term='wifi'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='wifi connection closed after 30 minutes'/><category scheme='http://www.blogger.com/atom/ns#' term='30 minutes'/><title type='text'>iOS: Fixing the WiFi connection closed after 30 minutes</title><content type='html'>One nice Saturday afternoon when I was doing almost nothing, I got a phone call.&amp;nbsp; The number was big and didn't look like it was from India.&amp;nbsp; I picked up the call and said "Hello...", a familiar voice replied back.&amp;nbsp; The voice was of one of my good friend.&amp;nbsp; This friend of mine had gone to Germany for a month, his &lt;a href="http://en.wikipedia.org/wiki/IOS_%28Apple%29"&gt;iOS&lt;/a&gt; project was going live.&amp;nbsp; He had called me that afternoon to discuss about a problem that he was facing in his app. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Problem&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The application was to be deployed on &lt;a href="http://www.apple.com/ipad/"&gt;iPad&lt;/a&gt;.&amp;nbsp; Application used to poll the server for updates every 10 seconds.&amp;nbsp; For the application to work correctly, &lt;span style="font-size: large;"&gt;it was necessary that the polling should work flawlessly&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This polling worked well, however, he was facing one ugly little problem.&amp;nbsp; The issue was, &lt;span style="font-size: large;"&gt;after about 30 minutes, the polling would stop &lt;/span&gt;and because of this the application would not function correctly after 30 minutes.&amp;nbsp; This would happen &lt;span style="font-size: large;"&gt;only if the iPad is not connected to the charger or a computer.&amp;nbsp; &lt;span style="font-size: small;"&gt;If the iPad was &lt;span style="font-size: large;"&gt;connected to the charger or a computer polling would function correctly &lt;/span&gt;for any duration.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;The workaround&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To get the polling to work again user has to do one of the following&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Connect the iPad to a power source i.e. a charger or a computer&lt;/li&gt;&lt;li&gt;Pressing the home button on the iPad and reopen the application&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;The Fix&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I had not faced this issue earlier.&amp;nbsp; In fact, I have not done much iPhone development (at least non yet), but I decided to give it a shot anyways.&amp;nbsp; I decided to google about this issue and find a fix.&lt;br /&gt;&lt;br /&gt;After some intense googling, I found that, &lt;span style="font-size: large;"&gt;iPad switches off the WiFi connection automatically after 30 minutes to preserve battery&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;That's a good strategy alright but, what about the apps like my friends app?&amp;nbsp; The app need to poll the server every 10 seconds to function correctly.&amp;nbsp; How can we stop the iPad from switching off the WiFi connection automatically after 30 minutes?&lt;br /&gt;&lt;br /&gt;The fix was pretty simple, One needs to set a property in the &lt;a href="http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iphone_development/115-Configuring_Applications/configuring_applications.html"&gt;property list file&lt;/a&gt;.&amp;nbsp; The property is called &lt;a href="http://developer.apple.com/library/ios/#documentation/general/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html"&gt;&lt;span style="font-size: large;"&gt;UIRequiresPersistentWiFi.&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Quoting from the Apple developer documentation &lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: large;"&gt;&lt;i&gt;&lt;code&gt;UIRequiresPersistentWiFi&lt;/code&gt; (&lt;code&gt;Boolean&lt;/code&gt; - iOS) specifies whether the application requires a Wi-Fi connection. iOS maintains the active Wi-Fi connection open while the application is running.&lt;/i&gt;&lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;That was it!&amp;nbsp; I knew that, I have found a fix to my friends problem.&amp;nbsp; Asked him to add the property to the &lt;a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html#//apple_ref/doc/uid/10000048i"&gt;plist&lt;/a&gt; file and do a test again.&amp;nbsp; As expected the problem was solved.&amp;nbsp; Now, the app was able to poll the server for any duration without a problem even when the iPad was not connected to the power source!&lt;br /&gt;&lt;br /&gt;Simple things like this waste a lot of developer time, but once you learn something the hard way, you will never forget it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-4126467120451752180?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/4126467120451752180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/05/ios-fixing-wifi-connection-closed-after.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4126467120451752180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/4126467120451752180'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/05/ios-fixing-wifi-connection-closed-after.html' title='iOS: Fixing the WiFi connection closed after 30 minutes'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-2164981011548591548</id><published>2011-05-14T15:39:00.004+05:30</published><updated>2011-05-14T16:35:06.854+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='ImageView'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='BitmapFactory'/><category scheme='http://www.blogger.com/atom/ns#' term='decode returned false'/><category scheme='http://www.blogger.com/atom/ns#' term='FlushedInputStream'/><category scheme='http://www.blogger.com/atom/ns#' term='web image'/><category scheme='http://www.blogger.com/atom/ns#' term='skip method'/><category scheme='http://www.blogger.com/atom/ns#' term='fixing'/><category scheme='http://www.blogger.com/atom/ns#' term='InputStream'/><category scheme='http://www.blogger.com/atom/ns#' term='BufferedInputStream'/><category scheme='http://www.blogger.com/atom/ns#' term='HttpClient'/><category scheme='http://www.blogger.com/atom/ns#' term='skia decoder'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='Bitmap'/><title type='text'>Fixing the "skia decoder-&gt;decode returned false" error while downloading images on Android</title><content type='html'>I had to implement a common requirement in one of my Android project.&amp;nbsp; I had to show a image that was hosted on the web, in my &lt;a href="http://www.android.com/"&gt;Android &lt;/a&gt;application.&amp;nbsp; Now that is a very common situation right?&amp;nbsp; I am sure you must have faced this situation before.&lt;br /&gt;&lt;br /&gt;I would have imagined, showing the images from the web would be as simple as setting the correct image source URL to the &lt;a href="http://developer.android.com/reference/android/widget/ImageView.html"&gt;ImageView&lt;/a&gt;.&amp;nbsp; But as it turns out life is not always that simple.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;So how do we show the images from the web using the ImageView?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We have to first &lt;span style="font-size: large;"&gt;download the image &lt;/span&gt;using the &lt;a href="http://developer.android.com/reference/org/apache/http/client/HttpClient.html"&gt;HttpClient&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Decode the image &lt;/span&gt;data using &lt;a href="http://developer.android.com/reference/android/graphics/BitmapFactory.html"&gt;BitmapFactory&lt;/a&gt; and convert it into &lt;a href="http://developer.android.com/reference/android/graphics/Bitmap.html"&gt;Bitmap&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: large;"&gt;Associate the Decoded Bitmap with the ImageView&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Lets look at the code to show the web image in the ImageView&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class ImageDownloader {  /**  *  This method will download the image specified by the imageURL  *  and show it with the imageView  *  @param imageView The imageView which will show the image   *                   that is hosted online.  *  @param imageURL the url of the image to be shown.  */ public void downloadAndShowImage(                      final ImageView imageView, final String imageURL) {        try {            Log.d("ImageDownloader", "About to do an HTTPRequest to: "                                                              + imageURL);            final HttpParams httpParameters = new BasicHttpParams();            // Set the timeout in milliseconds until a connection is established.            HttpConnectionParams.setConnectionTimeout(httpParameters, 7000);            // Set the default socket timeout (SO_TIMEOUT)            // in milliseconds which is the timeout for waiting for data.            HttpConnectionParams.setSoTimeout(httpParameters, 10000);            final HttpClient client = new DefaultHttpClient(httpParameters);            final HttpResponse response = client.execute(new HttpGet(imageURL));            //Getting the response entity.            final HttpEntity entity = response.getEntity();            //Getting the input stream of the imae content.            final InputStream imageContentStream = entity.getContent();               //Decoding the image input stream using the             //BitmapFactory and converting the InputStream into Bitmap.            final Bitmap imageBitmap =                   BitmapFactory.decodeStream(imageContentStream);               //Attaching the imageBitmap with the imageView             //this step actually shows the downloaded image            imageView.setImageBitmap(imageBitmap);        } catch (Exception e) {            Log.e("ImageDownloader",                   "Error while downloading the image: "                                    + e.getMessage(), e);        } }}]]&gt;&lt;/script&gt;&lt;br /&gt;The above code works and works well, it does show the image hosted on the web in the ImageView.&amp;nbsp; However, sometimes, I get an error in the log saying&lt;br /&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[DEBUG/skia(260): --- decoder-&gt;decode returned false]]&gt;&lt;/script&gt;&lt;br /&gt;Now, this is something unexpected.  Whenever I get this error the &lt;span style="font-size: large;"&gt;image download stops and image is not shown in the ImageView.&lt;/span&gt;&lt;br /&gt;&lt;b&gt;The Cause:&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Googled a little and as usual, I was not the only one to face this issue.&amp;nbsp; There are lots of threads online, that mention this particular issue (&lt;a href="http://stackoverflow.com/questions/1630258/android-problem-bug-with-threadsafeclientconnmanager-downloading-images"&gt;here&lt;/a&gt; and &lt;a href="http://stackoverflow.com/questions/2787015/skia-decoder-fails-to-decode-remote-stream"&gt;here&lt;/a&gt;), "&lt;span style="font-size: large;"&gt;&lt;i&gt;decoder returned false&lt;/i&gt;&lt;/span&gt;".&amp;nbsp; &lt;br /&gt;&lt;br /&gt;It seems that when &lt;span style="font-size: large;"&gt;skip &lt;/span&gt;method of the &lt;a href="http://developer.android.com/reference/java/io/InputStream.html"&gt;InputStream &lt;/a&gt;class &lt;span style="font-size: large;"&gt;does not skip the given number of bytes &lt;/span&gt;then, the &lt;span style="font-size: large;"&gt;BitmapFactory fails to decode the InputStream.&lt;/span&gt;&amp;nbsp; Usually, the issue occurs on a slow internet connection.&amp;nbsp; However, I cant confirm that, I have a 2Mbps dedicated internet connection, even on this connection issue is reproduicable!&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;b&gt;The Fix:&lt;/b&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There are two ways of fixing this issue.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Method 1 - Method that involves writing some custom code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This method makes sure that, &lt;span style="font-size: large;"&gt;the skip method of InputStream actually skip's the mentioned number of bytes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To do this, we will need to &lt;span style="font-size: large;"&gt;wrap the InputStream into a custom class, override the skip method and ensure that we skip the given number of bytes no matter what.&lt;/span&gt;&amp;nbsp; This can be achieved by subclassing the &lt;a href="http://developer.android.com/reference/java/io/FilterInputStream.html"&gt;FilterInputStream&lt;/a&gt; class and overriding the skip method.&amp;nbsp; Lets look at how the new implementation of the skip method.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[/** * The class that will provide the correct implementation of the skip method * this class extends the FilterInputStream * * @author Deep Shah */class FlushedInputStream extends FilterInputStream {    /**     * The constructor that takes in the InputStream reference.     *     * @param inputStream the input stream reference.     */    public FlushedInputStream(final InputStream inputStream) {        super(inputStream);    }    /**     * Overriding the skip method to actually skip n bytes.     * This implementation makes sure that we actually skip      * the n bytes no matter what.     * {@inheritDoc}     */    @Override    public long skip(final long n) throws IOException {        long totalBytesSkipped = 0L;        //If totalBytesSkipped is equal to the required number         //of bytes to be skipped i.e. "n"        //then come out of the loop.        while (totalBytesSkipped &lt; n) {            //Skipping the left out bytes.            long bytesSkipped = in.skip(n - totalBytesSkipped);            //If number of bytes skipped is zero then             //we need to check if we have reached the EOF            if (bytesSkipped == 0L) {                //Reading the next byte to find out whether we have reached EOF.                int bytesRead = read();                //If bytes read count is less than zero (-1) we have reached EOF.                //Cant skip any more bytes.                if (bytesRead &lt; 0) {                    break;  // we reached EOF                } else {                    //Since we read one byte we have actually                     //skipped that byte hence bytesSkipped = 1                    bytesSkipped = 1; // we read one byte                }            }            //Adding the bytesSkipped to totalBytesSkipped            totalBytesSkipped += bytesSkipped;        }                return totalBytesSkipped;    }}]]&gt;&lt;/script&gt;&lt;br /&gt;As seen in the above code, the skip method simply makes sure that we skip the give number of bytes.&amp;nbsp; The &lt;i&gt;class FlushedInputStream&lt;/i&gt; now needs to be used while we &lt;i&gt;decode the image.  &lt;/i&gt;The updated code with the &lt;i&gt;FilteredInputStream &lt;/i&gt;looks like&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[/** * Created by IntelliJ IDEA. * * @author Deep Shah */public class ImageDownloader {    /**     * This method will download the image specified by the imageURL     * and show it with the imageView     *     * @param imageView The imageView which will show the      *        image that is hosted online.     * @param imageURL  the url of the image to be shown.     */    public void downloadAndShowImage(final ImageView imageView,                                            final String imageURL) {        try {            Log.d("ImageDownloader", "About to do an HTTPRequest to: "                                                              + imageURL);            final HttpParams httpParameters = new BasicHttpParams();            // Set the timeout in milliseconds until a connection is established.            HttpConnectionParams.setConnectionTimeout(httpParameters, 7000);            // Set the default socket timeout (SO_TIMEOUT)            // in milliseconds which is the timeout for waiting for data.            HttpConnectionParams.setSoTimeout(httpParameters, 10000);            final HttpClient client = new DefaultHttpClient(httpParameters);            final HttpResponse response = client.execute(new HttpGet(imageURL));            final HttpEntity entity = response.getEntity();            final InputStream imageContentInputStream = entity.getContent();            //Notice that we are now wrapping the             //imageContentInputStream in FlushedInputStream.            final Bitmap imageBitmap =                        BitmapFactory.decodeStream(                           new FlushedInputStream(imageContentInputStream));            imageView.setImageBitmap(imageBitmap);        } catch (Exception e) {            Log.e("ImageDownloader", e.getMessage(), e);        }    }}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;Method 2 - Method that involves using the &lt;a href="http://developer.android.com/reference/java/io/BufferedInputStream.html"&gt;BufferedInputStream&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This method is very simple and straight forward we simply need to &lt;span style="font-size: large;"&gt;wrap the imageContentInputStream with the BufferedInputStream.&lt;/span&gt;  This also seems to fix the problem.  The updated code looks like&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class ImageDownloader {    /**     * This method will download the image specified by the imageURL     * and show it with the imageView     *     * @param imageView The imageView which will show      *                  the image that is hosted online.     * @param imageURL  the url of the image to be shown.     */    public void downloadAndShowImage(                final ImageView imageView, final String imageURL) {        try {            Log.d("ImageDownloader", "About to do an HTTPRequest to: "                                                             + imageURL);            final HttpParams httpParameters = new BasicHttpParams();            // Set the timeout in milliseconds until a connection is established.            HttpConnectionParams.setConnectionTimeout(httpParameters, 7000);            // Set the default socket timeout (SO_TIMEOUT)            // in milliseconds which is the timeout for waiting for data.            HttpConnectionParams.setSoTimeout(httpParameters, 10000);            final HttpClient client = new DefaultHttpClient(httpParameters);            final HttpResponse response = client.execute(new HttpGet(imageURL));            final HttpEntity entity = response.getEntity();            final InputStream imageContentInputStream = entity.getContent();            //Notice that we are wrapping the             //imageContentInputStream with BufferedInputStream.            final Bitmap imageBitmap =                          BitmapFactory.decodeStream(                           new BufferedInputStream(imageContentInputStream));            imageView.setImageBitmap(imageBitmap);        } catch (Exception e) {            Log.e("ImageDownloader", e.getMessage(), e);        }    }}]]&gt;&lt;/script&gt;&lt;br /&gt;Yep, these two methods fix the &lt;i&gt;&lt;span style="font-size: large;"&gt;"decode returned false&lt;/span&gt;" &lt;/i&gt;issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-2164981011548591548?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/2164981011548591548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/05/fixing-skia-decoder-decode-returned.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2164981011548591548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2164981011548591548'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/05/fixing-skia-decoder-decode-returned.html' title='Fixing the &quot;skia decoder-&gt;decode returned false&quot; error while downloading images on Android'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-6127302030317828771</id><published>2011-05-07T13:44:00.004+05:30</published><updated>2011-05-07T14:00:33.185+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='ICICI'/><category scheme='http://www.blogger.com/atom/ns#' term='ICICI Bank'/><category scheme='http://www.blogger.com/atom/ns#' term='security laps'/><category scheme='http://www.blogger.com/atom/ns#' term='security problem'/><category scheme='http://www.blogger.com/atom/ns#' term='is your bank account safe'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile number'/><title type='text'>Is your Bank Account safe with ICICI bank?</title><content type='html'>&lt;a href="http://www.icicibank.com/"&gt;ICICI Bank&lt;/a&gt;&amp;nbsp;is one of the biggest bank in India. &amp;nbsp;Its&amp;nbsp;renowned&amp;nbsp;for having most number of &lt;a href="http://en.wikipedia.org/wiki/Automated_teller_machine"&gt;ATM&lt;/a&gt;&amp;nbsp;(after &lt;a href="http://www.statebankofindia.com/"&gt;SBI&lt;/a&gt;) in the country. &amp;nbsp;I always though that, ICICI Bank has a good security model to prevent online thefts. &lt;br /&gt;&lt;br /&gt;No, this post is not an advertisement of ICICI bank, I wanted to share a weird experience that I had with ICICI Bank. &amp;nbsp;This experience will expose the security model of ICICI Bank. &amp;nbsp;Over and above it, I wanted to help them correct their mistake, but they didn't do anything as yet.&lt;br /&gt;&lt;br /&gt;So what was the incident, how did I try to help and what was their response?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Incident&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;One fine Monday morning, I got 4 SMS'es from ICICI Bank, informing me that for a certain account XXXXXXX12345&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Address has been updated&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;ATM pin number has changed to 1234&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Land line number has been changed to 020-30212345&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Mobile number has been changed to 9912345678&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;When I got those SMS'es, I was a little surprised. &amp;nbsp;I was holding an account with ICICI Bank but I never requested them to change all this information for my account. &amp;nbsp;I had not called them for any such requests, then,&amp;nbsp;&lt;span class="Apple-style-span" style="font-size: large;"&gt;who call them for changing all this information? &amp;nbsp;Was my Bank Account hacked?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After some initial&amp;nbsp;anxiety, I calmed down and rechecked those SMS'es. &amp;nbsp;When I reread the messages, this time a little carefully, I realized that, &lt;span class="Apple-style-span" style="font-size: large;"&gt;my bank account number does not end with "12345".&lt;/span&gt; &amp;nbsp;Analyzing further I realized, &lt;span class="Apple-style-span" style="font-size: large;"&gt;I do not have a land line whose number is 020-30212345&lt;/span&gt;. &amp;nbsp;Surprising thing was, &lt;span class="Apple-style-span" style="font-size: large;"&gt;the mobile number was indeed correct. &amp;nbsp;9912345678 was indeed my mobile number&lt;/span&gt;. &amp;nbsp;Rest of the details (except the mobile number) were no way related to me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Response&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By now it was clear to me that there has been a mistake. &amp;nbsp;I decided to call up the ICICI Bank call center to find out what was wrong. &amp;nbsp;I cleared the &lt;a href="http://en.wikipedia.org/wiki/Interactive_voice_response"&gt;IVR&lt;/a&gt;&amp;nbsp;authentication, got my call transferred to the Customer Service Executive. &amp;nbsp;First, I wanted to confirm that my Bank Account was not hacked. &amp;nbsp;I asked them if there were any requests made for changing the address, phone number, atm pin of &amp;nbsp;my account. &amp;nbsp;Thankfully, &lt;span class="Apple-style-span" style="font-size: large;"&gt;there were no such requests made for my account&lt;/span&gt;. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now the question that was bothering me was, &lt;span class="Apple-style-span" style="font-size: large;"&gt;who holds the account that ends with "12345" and why was it associated with my mobile number?&lt;/span&gt; &amp;nbsp;I asked the Customer Service Executive about which accounts are associated with my mobile number?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;She said, &lt;span class="Apple-style-span" style="font-size: large;"&gt;there was indeed one account associated with my mobile number that ends with "12345". &amp;nbsp;Bingo!&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Being a decent man, I told her that, the account that ends with "12345" is not my account. &amp;nbsp;There seems to be a mistake, because of which my mobile number was associated with incorrect account. &amp;nbsp;She told me, she can see that the account is held by some&amp;nbsp;&lt;b&gt;"Mr. Pathak". &amp;nbsp;&lt;/b&gt;She also told me that the account was newly opened in the &lt;b&gt;"Bhandarkar Road Branch - Pune". &amp;nbsp;&lt;/b&gt;I requested her to kindly &lt;span class="Apple-style-span" style="font-size: large;"&gt;delink my mobile number from his account. &amp;nbsp;She agreed and said this will be done in 2 days&lt;/span&gt;. &amp;nbsp;I was&amp;nbsp;relieved.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By now I was thinking, this is such a big problem. &amp;nbsp;If someone gave an incorrect mobile number, or the bank's customer service executive made a mistake noting down the mobile number, &lt;span class="Apple-style-span" style="font-size: large;"&gt;All vital information will be SMS'ed to the incorrect mobile number&lt;/span&gt;&lt;b style="font-size: x-large;"&gt;. &amp;nbsp;&lt;/b&gt;I knew the other guys ATM pin number, I knew his account number, I knew his address, his land line number. &amp;nbsp;&lt;span class="Apple-style-span" style="font-size: large;"&gt;If this information falls in wrong hands, anything is possible.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By now you must be thinking that the issue must have been resolved. &amp;nbsp;But unfortunately, the issue does not end here. &amp;nbsp;After about 5 days I got an &lt;span class="Apple-style-span" style="font-size: large;"&gt;SMS informing that 25000 Rs. were credited into the account ending with "12345"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;My first reaction to this was, &lt;span class="Apple-style-span" style="font-size: large;"&gt;WTF!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I called up the ICICI Bank call center again, to find out why my mobile number was not delinked. &amp;nbsp;This time they informed me that &lt;span class="Apple-style-span" style="font-size: large;"&gt;they cannot delink my mobile number from "Mr. Pathak's" account on my request. &amp;nbsp;I need to prove that, the mobile number under question is actually my mobile &amp;nbsp;number.&lt;/span&gt;&amp;nbsp; I asked them, what should I do to prove it. &amp;nbsp;They said visit any nearest ICICI Bank branch with and ID proof and the post paid Bill of my mobile number.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My reply to that was, I have no motivation to go to the bank to prove this. &amp;nbsp;Its a clear case of human error, they should have delinked my mobile number from Mr. Pathak's bank account. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;I wanted to help them rectify their mistake, but they will not let me do so.&lt;/span&gt; &amp;nbsp;Why the hell should I waste my time? &amp;nbsp;I&amp;nbsp;definitely&amp;nbsp;have better things to do!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The conversation ended there. &amp;nbsp;I was frustrated, &lt;span class="Apple-style-span" style="font-size: large;"&gt;why do people stop using their brains? &amp;nbsp;Why are processes so rigorously implemented that people stop using common sense?&lt;/span&gt; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few days passed, &lt;span class="Apple-style-span" style="font-size: large;"&gt;I got two more SMS informing that 25000 Rs were&amp;nbsp;withdrawn from the account ending with "12345" and the account balance was 0.0 Rs. &amp;nbsp;The other message informed that, the balance of bank account ending with "12345" had fallen below the allowed limit of 10000 Rs&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This was the limit, I decide to actually visit the ICICI Bank branch and once and for all get my mobile number delinked from Mr Pathak's bank account. &amp;nbsp;I carried a photo identification proof (my &lt;a href="http://www.incometaxindia.gov.in/pan/overview.asp"&gt;PAN Card&lt;/a&gt;) and the post paid bill of my mobile number. &amp;nbsp;I went to the&lt;b&gt; "Shivaji Nagar - Pune Branch"&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The response that I got from the branch was&amp;nbsp;unbelievable. &amp;nbsp;The lady at the bank said &lt;span class="Apple-style-span" style="font-size: large;"&gt;she cannot delink Mr. Pathak's account from my mobile number. &amp;nbsp;I showed the bank lady, my pan card, even the post paid mobile bill for my mobile number with my name written all over it!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Unfortunately nothing helped, she said she cannot do it. &amp;nbsp;She said &lt;span class="Apple-style-span" style="font-size: large;"&gt;it was against the processes of ICICI Bank!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;I urged her that, there has to be a way to do it. &amp;nbsp;Inform Mr. Pathak about the mistake, get him to rectify this problem. &amp;nbsp;She assured me that something will be done. &amp;nbsp;But &lt;span class="Apple-style-span" style="font-size: large;"&gt;till date nothing has been done. &amp;nbsp;Till now I get SMS'es about Mr. Pathak's bank details on my mobile number!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How did I try to help&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Called up the call center twice to inform them about the mistake&lt;/li&gt;&lt;li&gt;Went to the bank and proved that the mobile number indeed belonged to me but still they didn't delink it from Mr. Pathak's bank account.&lt;/li&gt;&lt;li&gt;Wasted 5 hrs of my life fixing a problem that didn't impact me much.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;What should we learn from this incident&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Software is meant to reduce&amp;nbsp;human effort. &amp;nbsp;Processes are meant to reduce human mistakes. &amp;nbsp;&lt;span class="Apple-style-span" style="font-size: large;"&gt;This incident is a perfect example of what happens when people follow processes and use software without using their brains!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;PS:&amp;nbsp;All events and conversations mentioned in the post are real. &amp;nbsp;However,&amp;nbsp;all Names and Numbers have been changed to preserve the privacy of a certain person.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-6127302030317828771?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/6127302030317828771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/05/is-your-bank-account-safe-with-icici.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6127302030317828771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/6127302030317828771'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/05/is-your-bank-account-safe-with-icici.html' title='Is your Bank Account safe with ICICI bank?'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-5044723190239146817</id><published>2011-04-30T21:27:00.004+05:30</published><updated>2011-04-30T21:49:17.121+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='one dll per folder'/><category scheme='http://www.blogger.com/atom/ns#' term='fixing'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='aspnet_compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='msbuild'/><category scheme='http://www.blogger.com/atom/ns#' term='circular file references are not allowed'/><title type='text'>How to fix the “circular file references are not allowed” Error in ASP.Net</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;On one of my .Net projects, I came across an interesting issue. &amp;nbsp;I wasted couple of hours fixing it. &amp;nbsp;Hence, I decided to share my findings, so that others do not have to waste their time fixing the same issue.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;&lt;b&gt;The issue&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #0f243e;"&gt;The issue was pretty simple, the app would not build. &amp;nbsp;The error that I was getting while building a ASP.Net web project using MSBuild was:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[/someProject/Controls/A/ucA.ascx(2): error ASPPARSE: Circular file references are not allowed.]]&gt;&lt;/script&gt;&lt;br /&gt;Of course the error said there is some sort of circular reference in my code.&amp;nbsp; I looked around to check and recheck, if I have created a circular reference by mistake. &amp;nbsp;However, if there was any circular reference, the code would not compile. &amp;nbsp;Code was compiling fine but it was failing when we ran &lt;i&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms229863%28v=vs.80%29.aspx"&gt;aspnet_compiler.exe&lt;/a&gt;&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;ASP.Net Compilation tool (aspnet_compiler.exe) &lt;/i&gt;enables you to compile an ASP.Net Web application, this helps application performance because end users do not encounter a delay on the first request to the application.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;I checked again, but certainly there was no code related circular dependency then why the &lt;i&gt;aspnet_compiler.exe&lt;/i&gt; was complaining about the circular file references?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Explanation&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Googling a little, I found that, by default, in a Website Project, &lt;span class="Apple-style-span" style="font-size: large;"&gt;ASP.Net creates one DLL per folder&lt;/span&gt;. Hence, if you have the following setup:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;User control ucA.ascx is present in the directory "A". &amp;nbsp;ucA.ascx refers another user control ucB.ascx&lt;/li&gt;&lt;li&gt;User control ucB.ascx is present in the directory "B". &amp;nbsp;ucB.ascx refers another user control ucC.ascx&lt;/li&gt;&lt;li&gt;User control ucC.ascx is present in the directory "A".&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div&gt;The folder &lt;span class="Apple-style-span" style="font-size: large;"&gt;A's DLL will reference the folder B's DLL, which will again reference the folder A's DLL, causing a "circular file reference"&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is the reason why the &lt;span class="Apple-style-span" style="font-size: large;"&gt;aspnet_compiler.exe fails with the "circular file reference" error&lt;/span&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Fix&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;There are two ways this issue could be fixed&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Rearrange the user controls (or MasterPages) to remove the circular references.&lt;/b&gt; &amp;nbsp;Usually this means moving the user controls in separate directories. &amp;nbsp;In our example, moving &lt;i&gt;ucC.ascx to a new directory "C"&lt;/i&gt;&amp;nbsp;&lt;i&gt;(Preferred Solution).&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Use batch=”false” in the compilation tag of the web.config file&lt;/b&gt;. &amp;nbsp;This will cause a new DLL to be created for each control/page in the site. This should fix the error but&lt;b&gt; is really lousy for performance&lt;/b&gt;, so it should be avoided.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I &lt;b&gt;moved the ucC.ascx in a different directory &lt;/b&gt;and yes the error went away!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-5044723190239146817?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/5044723190239146817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/04/how-to-fix-circular-file-references-are.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5044723190239146817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/5044723190239146817'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/04/how-to-fix-circular-file-references-are.html' title='How to fix the “circular file references are not allowed” Error in ASP.Net'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-7584354785211885333</id><published>2011-04-24T12:15:00.001+05:30</published><updated>2011-04-24T12:18:58.686+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='htc desire hd'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='PathClassLoader'/><category scheme='http://www.blogger.com/atom/ns#' term='object to JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON to object'/><category scheme='http://www.blogger.com/atom/ns#' term='ClassNotFoundException'/><category scheme='http://www.blogger.com/atom/ns#' term='jarjar'/><category scheme='http://www.blogger.com/atom/ns#' term='Gson'/><category scheme='http://www.blogger.com/atom/ns#' term='htc mytouch 4g'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Fixing the java.lang.ClassNotFoundException com.test.model.SomeModelClass in loader dalvik.system.PathClassLoader on Android</title><content type='html'>Recently, I had faced a very interesting issue on one of my Android project. &amp;nbsp;The issue was the &lt;span class="Apple-style-span" style="font-size: large;"&gt;dreadful &lt;i&gt;java.lang.ClassNotFoundException&lt;/i&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The Android App, that was facing the&lt;i&gt; ClassNotFoundException&lt;/i&gt; was tested on multiple devices. &amp;nbsp;Some of the devices that we tested the app on were&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.motorola.com/Consumers/US-EN/Consumer-Product-and-Services/Mobile-Phones/Motorola-DROID-US-EN"&gt;&lt;span class="Apple-style-span" style="color: #0000ee;"&gt;&lt;u&gt;Motorola&lt;/u&gt;&lt;/span&gt;&amp;nbsp;Droid&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.motorola.com/Consumers/US-EN/Consumer-Product-and-Services/Mobile-Phones/Motorola-DROID-X-US-EN"&gt;Motorola Droid X&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.htc.com/www/product/desire/overview.html"&gt;HTC Desire&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.htc.com/www/product/wildfire/overview.html"&gt;HTC WildFire&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dell.com/in/p/mobile-streak/pd?cs=indhs1"&gt;Dell Streak&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.htc.com/www/product/nexusone/overview.html"&gt;Nexus One&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.samsung.com/in/consumer/mobile-phone/mobile-phone/smartphone/GT-I5801DKAINU/index.idx?pagetype=prd_detail&amp;amp;returnurl="&gt;Samsung Galaxy 3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.lg.com/uk/mobile-phones/all-lg-phones/LG-android-mobile-phone-P500.jsp"&gt;LG Optimus One&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The app worked fine on all devices without any problems at all. &amp;nbsp;We decided to go live with the App on Android Market. &lt;br /&gt;&lt;br /&gt;Everything looked great till one day when one of the QA's downloaded the app on &lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;HTC MyTouch 4G&lt;/span&gt;&lt;/b&gt;. &amp;nbsp;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;The app refused to work on this device&lt;/b&gt;.&lt;/span&gt; &amp;nbsp;The app threw &lt;i&gt;ClassNotFoundExceptions&lt;/i&gt;. &amp;nbsp;The stack trace looked like&lt;/div&gt;&lt;/div&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[Type com.test.model.SomeModelClass not presentjava.lang.TypeNotPresentException: Type com.test.model.SomeModelClass not present at org.apache.harmony.luni.lang.reflect.ImplForType.getRawType(ImplForType.java:64) at org.apache.harmony.luni.lang.reflect.ImplForType.getResolvedType(ImplForType.java:73) at org.apache.harmony.luni.lang.reflect.ListOfTypes.getResolvedTypes(ListOfTypes.java:68) at org.apache.harmony.luni.lang.reflect.ImplForType.getResolvedType(ImplForType.java:72) at org.apache.harmony.luni.lang.reflect.Types.getType(Types.java:29) at java.lang.reflect.Field.getGenericType(Field.java:191) at com.google.gson.TypeInfoFactory.getTypeInfoForField(TypeInfoFactory.java:53) at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:148) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123) at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73) at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51) at com.google.gson.Gson.fromJson(Gson.java:495) at com.google.gson.Gson.fromJson(Gson.java:444) at com.google.gson.Gson.fromJson(Gson.java:396) at com.google.gson.Gson.fromJson(Gson.java:372) at com.test.locator.SomeTask.fetchSomething(SomeTask.java:110) at java.lang.Thread.run(Thread.java:1102)Caused by: java.lang.ClassNotFoundException: com.test.model.SomeModelClass  at java.lang.Class.classForName(Native Method) at java.lang.Class.forName(Class.java:235) at org.apache.harmony.luni.lang.reflect.ImplForType.getRawType(ImplForType.java:62) ... 23 moreCaused by: java.lang.NoClassDefFoundError: com.test.model.SomeModelClass  ... 26 moreCaused by: java.lang.ClassNotFoundException: com.test.model.SomeModelClass  in loader dalvik.system.PathClassLoader[.] at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243) at java.lang.ClassLoader.loadClass(ClassLoader.java:573) at java.lang.ClassLoader.loadClass(ClassLoader.java:532) ... 26 more]]&gt;&lt;/script&gt;&lt;br /&gt;After looking at the stack trace, I was thinking, Hmm this is weird, the app works on all these devices without an issue. &amp;nbsp;Moreover, the app cannot compile if the &lt;i&gt;class com.test.model.SomeModelClass &lt;/i&gt;was not found. &amp;nbsp;Then why it&amp;nbsp;doesn't&amp;nbsp;work on &lt;i&gt;HTC MyTouch 4G&lt;/i&gt;?&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;My initial reaction was, may be the app was not downloaded correctly from the Market. &amp;nbsp;May be the downloaded APK was corrupt?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I requested the QA's to uninstall the app and re-install it again from the market. &amp;nbsp;I was hoping that this could fix the issue. &lt;br /&gt;&lt;br /&gt;But software development has taught me one thing&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Nothing changes, If Nothing changes&lt;/span&gt;&lt;/i&gt;&lt;/blockquote&gt;Yep, the reinstall didnt work. &amp;nbsp;The app was still throwing the &lt;i&gt;ClassNotFoundException&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;We were using &lt;a href="http://proguard.sourceforge.net/"&gt;ProGuard&lt;/a&gt;. &amp;nbsp;Proguard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. &amp;nbsp;Another thought that crossed my mind was, Is ProGuard removing the class &lt;i&gt;com.test.model.SomeModelClass&lt;/i&gt;? &lt;br /&gt;&lt;br /&gt;I created the APK without running ProGuard on it. &amp;nbsp;Requested the QA to test it. &lt;br /&gt;&lt;br /&gt;That didn't work either. &amp;nbsp;ProGuard was not at fault.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;By now, I was really confused. &amp;nbsp;What could be the issue with the app? &amp;nbsp;I thought, may be, if I try to &lt;b&gt;load the class explicitly&lt;/b&gt; as the first thing in the app, then would it fix the issue? &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I updated the APK, loaded the class explicitly when the app starts, requested the QA to retest the APK.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Nope, that didn't fix the issue. &amp;nbsp;Interesting thing that I noticed about about this change was,&amp;nbsp;the class loads successfully when I load it explicitly, but the class is not found when the app really needs it at a later stage!&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;History has shown us, class loader issues are not easy to fix.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;I was quickly running out of options. &amp;nbsp;People were downloading the app on their device from the Market and may be some of them were facing the &lt;i&gt;ClassNotFoundException&lt;/i&gt; issue with the app. &amp;nbsp;I needed a solution and that too quickly! &amp;nbsp;We didn't want to make a wrong first impression. &amp;nbsp;What should I try next?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;At the back of my mind, I was sure that its some sort of a class loader issue. &amp;nbsp;When I explicitly load the class its found, but when the class is needed later in the app, its not found. &amp;nbsp;Surely something to do with a different class loader. &amp;nbsp;I decided to go back to basics, let's to do it step by step.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First step,&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;When does the app need the class?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The app makes a HTTP call to get some information. &amp;nbsp;The information is returned in form of &lt;i&gt;JSON responses&lt;/i&gt;. &amp;nbsp;As mentioned in my &lt;a href="http://www.gitshah.com/2011/04/how-to-work-with-json-on-android.html"&gt;previous post&lt;/a&gt;, I was using &lt;a href="http://code.google.com/p/google-gson/"&gt;Gson&lt;/a&gt; to parse the &lt;i&gt;JSON response&lt;/i&gt;. &amp;nbsp;Gson is an excellent library with it comes to &lt;i&gt;JSON manipulation&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Gson converts JSON response into Java Model Objects. &amp;nbsp;&lt;/i&gt;This is the point when the &lt;i&gt;Java Model Class com.test.model.SomeModelClass &lt;/i&gt;is loaded. &amp;nbsp;The problem lies here, &lt;span class="Apple-style-span" style="font-size: large;"&gt;Gson tries to load the class com.text.model.SomeModelClass dynamically&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;and its unable to find it!&lt;/span&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Why Gson does not find the class?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The real confusion in my mind was, why Gson is able to load the class on all other devices but HTC MyTouch 4G? &amp;nbsp;My reasoning to that was, may be, &lt;span class="Apple-style-span" style="font-size: large;"&gt;Gson is loaded in a different class loader in HTC MyTouch 4G? &amp;nbsp;Is that even possible? &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After some intense googling and trying our numerous things, I finally figured out what was issue and what was solution.&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;This issue occurs only when all of the following conditions are met&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The App uses &lt;span class="Apple-style-span" style="font-size: large;"&gt;Gson to&amp;nbsp;manipulate&amp;nbsp;JSON&lt;/span&gt;&lt;/li&gt;&lt;li&gt;The device is &lt;span class="Apple-style-span" style="font-size: large;"&gt;HTC Desire HD or MyTouch 4G on T-Mobile&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div&gt;The issue is &lt;span class="Apple-style-span" style="font-size: large;"&gt;HTC - The device manufacturer, also uses Gson library and they have made it public&lt;/span&gt;. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Somehow, &lt;i&gt;when the JVM is loaded on such devices, the Gson is also loaded along with it&lt;/i&gt;. &amp;nbsp;Because of this, the &lt;i&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Gson library that is bundled with the app never gets loaded&lt;/span&gt;&lt;/i&gt;. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When the &lt;span class="Apple-style-span" style="font-size: large;"&gt;global Gson tries to load classes from our domain model, it fails to find them&lt;/span&gt;. &amp;nbsp;This is because, &lt;span class="Apple-style-span" style="font-size: large;"&gt;the class loader that loaded the global Gson library does not have our app on its classpath!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;That explained what the problem was, let's see how we can fix it!&lt;/div&gt;&lt;div style="font-size: x-large;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;The Fix&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The fix was pretty simple. &amp;nbsp;We need to &lt;span class="Apple-style-span" style="font-size: large;"&gt;change the package name of the Gson library so that the global Gson library does not&amp;nbsp;interfere&amp;nbsp;with the local Gson library&lt;/span&gt;. &amp;nbsp;To change the package name of local Gson library, I used &lt;i&gt;&lt;a href="http://code.google.com/p/jarjar/"&gt;JarJar&lt;/a&gt; project&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I followed the following steps to change the package name of the local Gson library&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Download &lt;a href="http://code.google.com/p/jarjar/downloads/list"&gt;jarjar&lt;/a&gt;&amp;nbsp;project.&lt;/li&gt;&lt;li&gt;Put &lt;i&gt;jarjar-1.1.jar and gson-1.6.jar&lt;/i&gt; in the same directory&lt;/li&gt;&lt;li&gt;Create a new text file in this directory, lets call it &lt;i&gt;rules.txt.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Write the following line in the &lt;i&gt;rules.txt file&lt;/i&gt;: &lt;i&gt;&lt;b&gt;rule com.google.gson.** com.google.myproject.@1&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Open a command prompt and execute the command, &lt;i&gt;&lt;b&gt;java -jar jarjar.jar process rules.txt gson-1.6.jar myproject-gson-1.6.jar.&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Replaced the &lt;i&gt;gson library reference&lt;/i&gt; in the project with &lt;i&gt;myproject-gson-1.6.jar&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Update the imports to use the new package name&lt;/li&gt;&lt;li&gt;Compile and build the new APK&lt;/li&gt;&lt;li&gt;Requested the QA to test the updated APK&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;To look at more details visit &lt;a href="http://code.google.com/p/google-gson/issues/detail?id=255"&gt;this link&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;And that was it, It worked!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It was such a&amp;nbsp;relief! &amp;nbsp;I am glad that, I faced this issue, makes me love the job that I am doing!&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-7584354785211885333?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/7584354785211885333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/04/fixing-javalangclassnotfoundexception.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/7584354785211885333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/7584354785211885333'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/04/fixing-javalangclassnotfoundexception.html' title='Fixing the java.lang.ClassNotFoundException com.test.model.SomeModelClass in loader dalvik.system.PathClassLoader on Android'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-2278463248175630619</id><published>2011-04-16T13:58:00.002+05:30</published><updated>2011-04-16T14:04:21.936+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='deserializer'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON to object'/><category scheme='http://www.blogger.com/atom/ns#' term='JsonSerializer'/><category scheme='http://www.blogger.com/atom/ns#' term='Gson'/><category scheme='http://www.blogger.com/atom/ns#' term='object to JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='serializer'/><category scheme='http://www.blogger.com/atom/ns#' term='fromJson'/><category scheme='http://www.blogger.com/atom/ns#' term='JsonDeserializer'/><category scheme='http://www.blogger.com/atom/ns#' term='toJson'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>How to work with JSON on Android - Part - 2</title><content type='html'>As mentioned in my &lt;a href="http://www.gitshah.com/2011/04/how-to-work-with-json-on-android.html"&gt;previous post&lt;/a&gt;, &lt;a href="http://code.google.com/p/google-gson/"&gt;Gson&lt;/a&gt;&amp;nbsp;is an excellent lightweight opensource library to do &lt;a href="http://json.org/"&gt;JSON&lt;/a&gt;&amp;nbsp;manipulations. &amp;nbsp;I have used this library on the Android platform, it works great!&lt;br /&gt;&lt;br /&gt;We have seen that, converting JSON to Java model objects and Java model Objects to JSON is pretty straight forward with Gson.&lt;br /&gt;&lt;br /&gt;In this post lets look at the various hooks that Gson provides to deal with not so straight forward&amp;nbsp;scenarios.&lt;br /&gt;&lt;br /&gt;Lets take an example. &amp;nbsp;Lets say you want to convert the &lt;i&gt;JSON string value "08:00" into Java model Time object&lt;/i&gt;. &amp;nbsp;A very valid&amp;nbsp;scenario right?&lt;br /&gt;&lt;br /&gt;Basically, we need to &lt;i&gt;serialize and deserialize the Time object in a special way&lt;/i&gt;. &amp;nbsp;Gson provides a way in which we can hookup our own serializer and&amp;nbsp;deserializer for a given type. &amp;nbsp;This serializer and deserializer will be invoked to convert the &lt;i&gt;Java model object into JSON String and JSON string into Java model object&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;The approach taken by Gson to do this task is pretty natural and easy to follow. &amp;nbsp;Great job guys!&lt;br /&gt;&lt;br /&gt;Lets look at the code to put things in perspective.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class Time {    /** The hour of the day. */    private int hour;    /** The minute of the hour. */    private int minute;    /**     * The constructor that takes the hour and minute as arguments.     * @param hour the hour part.     * @param minute the minute part.     */    public Time(final int hour, final int minute) {        this.hour = hour;        this.minute = minute;    }    /**     * Getter for the hour.     * @return the value of the hour.     */    public int getHour() {        return hour;    }    /**     * Getter for the minute.     * @return the value of minute.     */    public int getMinute() {        return minute;    }}]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;i&gt;Time class&lt;/i&gt; has two fields one to represent the hour and other represents the minute of the day. &amp;nbsp;Let's say that, we want the &lt;i&gt;JSON representation of Time objects&lt;/i&gt; to be of in the format &lt;i&gt;"HH:MM". &amp;nbsp;&lt;/i&gt;Let's first look at the code to convert Java model Time object into JSON&lt;br /&gt;&lt;br /&gt;Gson provides an interface called&amp;nbsp;&lt;i&gt;JsonSerializer. &amp;nbsp;&lt;/i&gt;We can provide an implementation of JsonSerializer to serialize the Time object in the way we want. &amp;nbsp;The code to do this would look like&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class TimeSerializer implements JsonSerializer&lt;time&gt; {    /**     * Implementing the interface JsonSerializer.       * Notice that the the interface has a generic     * type associated with it.       * Because of this we do not have ugly casts in our code.     * {@inheritDoc}     */    public JsonElement serialize(                   final Time time,                    final Type type,                   final JsonSerializationContext jsonSerializationContext) {        /**          * Returning the reference of JsonPremitive          * which is nothing but a JSONString.         * with value in the format "HH:MM"         */         return new JsonPrimitive(String.format("%1$02d:%2$02d",                               time.getHour(), time.getMinute()));    }]]&gt;&lt;/script&gt;&lt;br /&gt;Ok so the serializer does not look very complex.  How do we tell Gson to use TimeSerializer when it serializes the Time object?&lt;br /&gt;&lt;br /&gt;Turns out, Gson providers a class called&amp;nbsp;&lt;i&gt;GsonBuilder. &amp;nbsp;&lt;/i&gt;This class can be used to register custom serializers and deserializers with Gson. &amp;nbsp;&lt;i&gt;GsonBuilder&amp;nbsp;&lt;/i&gt;class has the responsibility to construct an instance of&amp;nbsp;&lt;i&gt;Gson &lt;/i&gt;with registered serializers and deserializers. &amp;nbsp;Let's look at the code&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[        final GsonBuilder gsonBuilder = new GsonBuilder();        /**          * Registering the TimeSerializer with the GsonBuilder.         * The Gson instance created from this builder will have TimeSerializer          * registered with it.  Hence, when it serializes the Time object it uses         * our TimeSerializer.  End result we get the serialized JSON string in         * "HH:MM" format.         */        gsonBuilder.registerTypeAdapter(Time.class, new TimeSerializer());        /** Creating an instance of Gson from the builder. */        Gson gson = gsonBuilder.create();        /** Serializing the Time object. */        String jsonString = gson.toJson(new Time(8, 9));        /** Asserting that the jsonString is what we expect it to be. */        assertEquals("\"08:09\"", jsonString);]]&gt;&lt;/script&gt;&lt;br /&gt;Does not look too difficult right?&lt;br /&gt;&lt;br /&gt;Serialization done, let's look at deserialization. &amp;nbsp;Any guesses?&lt;br /&gt;&lt;br /&gt;I am sure you got it right. &amp;nbsp;Gson provider an interface called&amp;nbsp;&lt;i&gt;JsonDeserializer. &amp;nbsp;&lt;/i&gt;We have implement this interface to provide a custom deserializer for the Time Java model class. &amp;nbsp;Let's look at the deserializer code.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class TimeDeserializer implements JsonDeserializer&lt;time&gt; {    /**     * Implementing the interface JsonDeserializer.       * Notice that the the interface has a generic     * type associated with it.       * Because of this we do not have ugly casts in our code.     * {@inheritDoc}     */    public Time deserialize(                    final JsonElement jsonElement,                    final Type type,                    final JsonDeserializationContext jsonDeserializationContext) {        /** Splitting the jsonString, using colon - : as the separator. */        final String[] timeParts = jsonElement.getAsString().split(":");        /** Constructing the instance of Time using the split string. */        return new Time(Integer.parseInt(timeParts[0]),                                  Integer.parseInt(timeParts[1]));    }}]]&gt;&lt;/script&gt;&lt;br /&gt;The code of deserializer looks pretty simple.  The code to integrate the deserializer is exactly the same as the code to integrate the serializer.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[        final GsonBuilder gsonBuilder = new GsonBuilder();        /**          * Registering the TimeDeserializer with the GsonBuilder.         * The Gson instance created from this builder will have TimeDeserializer          * registered with it.  Hence, when it deserializes the string in "HH:MM" format         * it uses our TimeDeserializer.           * End result we get the deserialized Time object.         */        gsonBuilder.registerTypeAdapter(Time.class, new TimeDeserializer());        /** Creating an instance of Gson from the builder. */        final Gson gson = gsonBuilder.create();        /** Deserializing the Time object from string 08:09. */        final Time time = gson.fromJson("\"08:09\"", Time.class);        /** Asserting that the time object has the values we expect. */        assertEquals(8, time.getHour());        assertEquals(9, time.getMinute());]]&gt;&lt;/script&gt;&lt;br /&gt;Thats all folks!  Gson is a really good framework to manipulate JSON.  &lt;br /&gt;&lt;br /&gt;We have effectively used it in Android projects.  If you have to do JSON manipulation in your project, I would suggest to have a look at Gson for sure!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-2278463248175630619?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/2278463248175630619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gitshah.com/2011/04/how-to-work-with-json-on-android-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2278463248175630619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/776222647855423698/posts/default/2278463248175630619'/><link rel='alternate' type='text/html' href='http://www.gitshah.com/2011/04/how-to-work-with-json-on-android-part-2.html' title='How to work with JSON on Android - Part - 2'/><author><name>Deep Shah</name><uri>http://www.blogger.com/profile/14535815256818279199</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://1.bp.blogspot.com/_qt-96pMuMZk/S8Q4X7i722I/AAAAAAAAAqs/tV-TG_sRdGE/S220/deep_shah.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-776222647855423698.post-3725345923532774348</id><published>2011-04-11T19:42:00.001+05:30</published><updated>2011-04-12T09:50:41.317+05:30</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='object to JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='fromJson'/><category scheme='http://www.blogger.com/atom/ns#' term='toJson'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON to object'/><category scheme='http://www.blogger.com/atom/ns#' term='Gson'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>How to work with JSON on Android</title><content type='html'>Recently, I have been working quite a bit on &lt;a href="http://www.android.com/"&gt;Android&lt;/a&gt;. &amp;nbsp;In my experience, there are lot of times when one has to deal with &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; while building apps for Android.&lt;br /&gt;&lt;br /&gt;In one of my projects, I had a situation where, I had to invoke a web-service which returned JSON response. &amp;nbsp;JSON response has to be parsed, information has to be extracted from it and shown to the user.&lt;br /&gt;&lt;br /&gt;The JSON response returned by the web-service was pretty big, with lots of fields, objects, lists and lists of objects. &amp;nbsp;In sort, the JSON response was pretty complex, it would have been a lot of work to extract information out of it, construct domain objects and then use it to show the information on the GUI.&lt;br /&gt;&lt;br /&gt;Android provides a package &lt;a href="http://developer.android.com/reference/org/json/package-summary.html"&gt;org.json&lt;/a&gt;&amp;nbsp;which has class like &lt;a href="http://developer.android.com/reference/org/json/JSONObject.html"&gt;JSONObject&lt;/a&gt;,&amp;nbsp;&lt;a href="http://developer.android.com/reference/org/json/JSONArray.html"&gt;JSONArray&lt;/a&gt;, etc&amp;nbsp;which help us parse the JSON responses. &amp;nbsp;I could have used those class and parsed the JSON response, extracted the information out of it, converted that into domain objects and used them to show it on the GUI. &amp;nbsp;But I am a lazy developer! &amp;nbsp;I am always in an hunt for ways to reduce my work!&lt;br /&gt;&lt;br /&gt;I was in no mood to write the such a lot of code just to parse the JSON response. &amp;nbsp;Over and above it, there are multiple problems with writing such code&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Quite some code just to parse the JSON response&lt;/li&gt;&lt;li&gt;Code has to be tested very well. &amp;nbsp;We have to make sure that it works in all situations.&lt;/li&gt;&lt;li&gt;This approach is error prone. &amp;nbsp;For example, if we decide to change the JSON keys, a lot of code have to be updated and there is no compile time check to find out errors if any while updating the keys.&lt;/li&gt;&lt;/ul&gt;So what is the alternate? &amp;nbsp;Simple, search for a library that does the job for you :)&lt;br /&gt;&lt;br /&gt;The perfect library for the task is &lt;a href="http://code.google.com/p/google-gson/"&gt;Gson&lt;/a&gt;. &amp;nbsp;Gson is an opensource project that helps us convert JSON to JavaBeans or JavaBeans to JSON using one line of code!&lt;br /&gt;&lt;br /&gt;This effectively means we could convert the JSON response to our model Objects with one line of code. &amp;nbsp;Isn't it awesome!&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;How do they do it?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An example explains things much faster. &amp;nbsp;So lets not waste any time and head straight to see Gson in action.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lets say that the JSON response returned by the service looked like&lt;/div&gt;&lt;script class="brush: plain" type="syntaxhighlighter"&gt;&lt;![CDATA[{"searchedAddress":{"state": "WI", "country": "USA"}, "pois":[ {"name":"Shopping Complex","latitude":41.909296,"longitude":87.738608},  {"name":"Fast Food","latitude":39.909296,"longitude":83.738608} ]}]]&gt;&lt;/script&gt;&lt;br /&gt;As we can see, the web services returns us the searched Address and Points of Interest (POI) around the searched address in the JSON response.&lt;br /&gt;&lt;br /&gt;We want to convert this JSON response into the &lt;i&gt;POIResponse&lt;/i&gt; Java domain object. &amp;nbsp;Lets look at how the &lt;i&gt;POIResponse class&lt;/i&gt; looks like&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public class POIResponse {    /** The searched address. */    private Address searchedAddress;    /** The list of POIs. */    private List&lt;poi&gt; pois;}public class Address {    /** The state. */    private String state;        /** The zip. */    private String zip;}public class POI {    /** The name of the POI. */    private String name;    /** The latitude of the POI. */    private double latitude;    /** The longitude of the POI. */    private double longitude;}]]&gt;&lt;/script&gt;&lt;br /&gt;The model class are pretty standard. &amp;nbsp;They just have fields with the same name as the keys in the JSON response. &amp;nbsp;Notice that we do have complex objects like &lt;i&gt;Address and POI and list of POI in POIResponse class.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;For Gson to work only one condition has to meet and that is, &lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;the name of fields in the model class should be same as the JSON keys&lt;/b&gt;&lt;/span&gt;. &amp;nbsp;This is based on the convention over configuration principal.&lt;br /&gt;&lt;br /&gt;Also notice that we do not have getters and setters in our domain classes. &amp;nbsp;Gson uses reflection to set the values directly into the fields. &amp;nbsp;Gson find private fields as well.&lt;br /&gt;&lt;br /&gt;Lets look at the code to convert the JSON response into model Java object.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[        /** To use Gson we need to get an instance of Gson.         *  On the instance invoke the fromJson method          *  to convert JSON response into model object.         */        final POIResponse poiResponse = new Gson().fromJson(            "{\"searchedAddress\":{\"state\": \"WI\", \"zip\": \"90210\"}, " +            "\"pois\":[" +            "{\"name\":\"Slow Food\",\"latitude\":41.909296,\"longitude\":87.738608},"+            "{\"name\":\"Fast Food\",\"latitude\":39.909296,\"longitude\":83.738608}" +            "]}", POIResponse.class);]]&gt;&lt;/script&gt;&lt;br /&gt;Thats all we need to do to convert JSON response into POIResponse object! &amp;nbsp;As promised its just one line of code.&lt;br /&gt;&lt;br /&gt;Gson has excellent support for Generics. &amp;nbsp;Notice that, we did not have to caste the return type of &lt;i&gt;fromJson method to POIResponse&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Gson can convert&amp;nbsp;&lt;i&gt;POIResponse&amp;nbsp;to JSON&lt;/i&gt; with the same ease.&lt;br /&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[String json = new Gson().toJson(poiResponse)]]&gt;&lt;/script&gt;&lt;br /&gt;The &lt;i&gt;string reference json &lt;/i&gt;holds the JSON representation of the poiResponse instance.&lt;br /&gt;&lt;br /&gt;Gson is an excellent lightweight library when it comes to working with JSON. &lt;br /&gt;&lt;br /&gt;In the next post I will show how Gson provides enough hooks to provide custom&amp;nbsp;serializers&amp;nbsp;and deserializers. &lt;br /&gt;&lt;br /&gt;Till then, stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/776222647855423698-3725345923532774348?l=www.gitshah.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.gitshah.com/feeds/3725345923532774348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.gits
