tag:blogger.com,1999:blog-80401154721863520732024-02-19T23:31:40.206+01:00my.netMarkus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.comBlogger84125tag:blogger.com,1999:blog-8040115472186352073.post-1790624242371547562013-02-15T10:13:00.001+01:002013-02-15T10:13:08.333+01:00SI-SE 2013 Azure Tutorial<p>Please find the slides from my Microsoft Azure tutoral at the SI-SE <a title="http://si-se.ch/2013/" href="http://si-se.ch/2013/">http://si-se.ch/2013/</a> conference <a href="http://si-se.ch/2013/presentations/azure_tutorial.pdf">here</a>. This was a hands-on session for beginners and non-.NET people.</p> <p>Everybody had its solution running in the cloud…</p> <p><a href="http://lh5.ggpht.com/-yxklgrYzqek/UR38HmKxDuI/AAAAAAAAB4c/OKnw2Cz81vE/s1600-h/WP_001454%25255B4%25255D.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="WP_001454" border="0" alt="WP_001454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8zhCgta8533fWOZcZ8-ud0IJMsovwiR-GwlGQ_U6xuuFyuhIY0Er8jJ6-8JQucFu5KNWsC6ym2FAh_8wKgN3C1LWEhaHL8f-R1FEt-_huU1GgNMosdSZTd6byWv4QTx2TJh8prsy9xNJO/?imgmax=800" width="505" height="388" /></a></p> <p>… and not on-premise <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smiley" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsQ2IEtfmcOSSCKGbgigH_tbgAdmu5VCeAKFYBN499UH2gjEtxqffltgfbGjKkrxFUoR5l0r-kWIHuQVK2p2sBAhCfI3yQTwEpvYnpM6RyHRGmWPZOuMHSZ27iq-GCNwDsVyfoLkVApuFJ/?imgmax=800" /></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-55515805795965361822012-12-14T10:48:00.001+01:002012-12-14T10:48:56.246+01:00Azure Tutorial @ SI-SE<p>On Thursday, 24.1.2013 I give an Azure Tutorial targeted at (non-Microsoft technology stack) developers and architects at SI-SE.ch <a title="http://si-se.ch/2013/tutorials" href="http://si-se.ch/2013/tutorials">http://si-se.ch/2013/tutorials</a></p> <p>Come and see me introducing to the Azure platform services – and develop and deploy your first Azure cloud application yourself!</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-85116396882695763362012-11-23T17:39:00.001+01:002012-11-23T17:39:29.396+01:00Azure Deployment of Certificate fails<p>I came accross an issue today where I wanted to deploy a .NET 4.5 (osVersion=”3”) cloud service using a self-signed SSL certificate to protect the web service traffic:</p> <p><font face="Courier New">11:55:44 AM - Preparing deployment for <solution> - 11/23/2012 11:55:30 AM with Subscription ID ‘<subscription>' using Service Management URL '</font><a href="https://management.core.windows.net/'.."><font face="Courier New">https://management.core.windows.net/'..</font></a><font face="Courier New">. <br />11:55:44 - Connecting... <br />11:55:46 - Warning: Error: <strong><font color="#ff0000">Certificate: ‘SSLCertificate’ with Thumbprint: <thumbprint> for Role: <solution>Service has not been uploaded to the cloud service: <solution>. <br /></font></strong>11:55:46 - The deployment cannot be completed because <strong>it requires certificates or OS images which are not present in the cloud</strong>. <br />11:55:46 - Deployment failed with a fatal error</font></p> <p>I investigated around my projects certificate settings, thumbprint or certificate store location – in vain. Then I solved the problem:</p> <ul> <li>Go to the Azure portal and upload the pfx file directly into your cloud service (certificate tab)</li> </ul> <p><a href="http://lh6.ggpht.com/-N89ZxmcWDWA/UK-muEMCstI/AAAAAAAAB4A/cbAqKI_J7bw/s1600-h/image%25255B3%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqLzzLXho49qRHZUCuS3VzlUIuok1MSSw4jkljHNyEhTnyr6hcatStxLKoLeXvsxS5Gx9mXoUAX_vNbUMZsc_7MzXkF2J4569_ix1PJqH6_zD5G3kze3F4bBLvVw6oAJsVjAbdlpbRROyw/?imgmax=800" width="980" height="175" /></a></p> <ul> <li>After this manual upload the deployment will succeed</li> </ul> <p><strong>NOTE</strong></p> <p>Looks like this being by design: conforming to some best security practices where developers should not have access to the production certificates – so deployment stops here. Took me some time so see it – but is perfectly true.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com2tag:blogger.com,1999:blog-8040115472186352073.post-10342352304725339202012-02-15T21:42:00.001+01:002012-02-15T21:46:47.409+01:00SQL Azure pricing reduced<p>As <a href="http://blogs.msdn.com/b/windowsazure/archive/2012/02/14/announcing-reduced-pricing-on-sql-azure-and-new-100mb-database-option.aspx">published</a> today in the Azure Team Blog, pricing is reduced for SQL Azure (by about 50%). 5 GB are now 26$ instead of 50$.</p> <p>Furthermore SQL Azure is getting more attractive for small data apps with the new 100MB option:</p> <table border="0" cellspacing="0" cellpadding="2" width="400"><tbody> <tr> <td valign="top" width="200"> <p><strong>Database Size <br /></strong></p> </td> <td valign="top" width="200"> <p><strong>Price Per Database Per Month</strong></p> </td> </tr> <tr> <td valign="top" width="200"> <p>0 to 100 MB</p> </td> <td valign="top" width="200"> <p>Flat $4.995</p> </td> </tr> <tr> <td valign="top" width="200"> <p>Greater than 100 MB to 1 GB</p> </td> <td valign="top" width="200"> <p>Flat $9.99</p> </td> </tr> </tbody></table> <p>-> 4 CHF/Mt for high availability, reliability and self-management.</p> <p>See <a title="https://www.windowsazure.com/en-us/pricing/details/" href="https://www.windowsazure.com/en-us/pricing/details/">https://www.windowsazure.com/en-us/pricing/details/</a> for details.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-78077736602999669932012-01-30T18:05:00.001+01:002012-01-30T18:06:46.569+01:00SQL Server Database Restore for Dummies – like me<p>I got a SQL server (express) database backup (.bak file) from a customer to do a test against. In the past, I just restored from my own, previously existing databases, so I never came across the issue of restoring one from a complete different machine. Using SSMS I got the following error messages</p> <p><em>The backup set holds a backup of a database other than the existing database</em> – or</p> <p><em>File 'Db' cannot be restored to 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.CUSTOMER\MSSQL\DATA\Db.mdf'. Use WITH MOVE to identify a valid location for the file</em>.</p> <p>The path does not exist on my machine. After browsing the web I found out the following:</p> <ol> <li>create a new and empty database named as the one from the customer (in this case ‘Db’) </li> <li>use a script to run <p>RESTORE DATABASE [Db] <br />FROM DISK = 'c:\theDbBackup.bak' <br />WITH <strong><font color="#809ec2">REPLACE</font> <br /></strong></p> </li> </ol> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-51901957489642628712012-01-29T22:02:00.001+01:002012-01-29T22:02:28.781+01:00Excellence in Software Engineering Conference 2012 - in Zurich<h4> </h4> <p>This year the ESE conference 2012 will take place in Zurich April 24. and 25. – hosted by Zühlke Engineering AG.</p> <p>That’s where software experts from around the world meet their peers and prominent speakers. The conference targets software architects, project managers, IT manager, process experts and all kinds of techies. Interactive discussion and talks are a major part of the two days.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhG9SLIux8N9Vu_DyngufG988GjvYdxzpw2aorHyYXl6EYmd8kpOMNJGyhFcjXJ9JOboEO090Xm-m2qDmRbyxkONhNRVZ-T7Zci_eYPRbfNDEFOhYXSltHBLJeZjP2aHa9n86tkcRLsZe_/s1600-h/image%25255B2%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-Jr-NXovsfH0/TyWz4-sJMmI/AAAAAAAABgk/KWCOgkEWFb0/image_thumb.png?imgmax=800" width="244" height="189" /></a></p> <p>There are three trendy tracks: Agile, Cloud and Mobile. See <a href="http://eseconf.com/">this</a> for more details. </p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1tag:blogger.com,1999:blog-8040115472186352073.post-89722322364803871092012-01-16T10:47:00.001+01:002012-01-16T10:47:20.420+01:00Struggling with Azure SDK Samples –> use Microsoft.ServiceBus.dll Version 1.6! or still 1.5?<p>Got some issues recently with the Azure SDK samples (e.g. RelayedConnectionSample with NetTcp, MulticastSample, etc.). SecurityExceptions were thrown, etc.</p> <p>Until I noticed that the samples still reference the Microsoft.ServiceBus.dll in </p> <ul> <li>version 1.5.0.0 under <em>c:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies\NET4.0\</em> instead of the latest one </li> <li>version 1.6.0.0 which is now installed under <em>C:\Program Files\Windows Azure SDK\v1.6\ServiceBus\ref</em> </li> </ul> <p>So you need to</p> <ol> <li>change assembly references to Microsoft.ServiceBus 1.6.0.0 </li> <li>change .config settings to 1.6.0.0 to: </li> </ol> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">extensions</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <</span><span style="color: #a31515">bindingExtensions</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">        <</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">netEventRelayBinding</span>"<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Version=<font style="background-color: #ffff00">1.6.0.0</font>, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="color: blue"> /></span></p> <p style="margin: 0px"><span style="color: blue">      </</span><span style="color: #a31515">bindingExtensions</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    </</span><span style="color: #a31515">extensions</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  </</span><span style="color: #a31515">system.serviceModel</span><span style="color: blue">></span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">runtime</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">assemblyBinding</span><span style="color: blue"> </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">urn:schemas-microsoft-com:asm.v1</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <</span><span style="color: #a31515">dependentAssembly</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">        <</span><span style="color: #a31515">assemblyIdentity</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">Microsoft.ServiceBus</span>"</p> <p style="margin: 0px"><span style="color: blue">                          </span><span style="color: red">publicKeyToken</span><span style="color: blue">=</span>"<span style="color: blue">31bf3856ad364e35</span>"</p> <p style="margin: 0px"><span style="color: blue">                          </span><span style="color: red">culture</span><span style="color: blue">=</span>"<span style="color: blue">neutral</span>"<span style="color: blue"> /></span></p> <p style="margin: 0px"><span style="color: blue">        <</span><span style="color: #a31515">bindingRedirect</span><span style="color: blue"> </span><span style="color: red">oldVersion</span><span style="color: blue">=</span>"<span style="color: blue">1.0.0.0</span>"</p> <p style="margin: 0px"><span style="color: blue">                         </span><span style="color: red">newVersion</span><span style="color: blue">=</span>"<span style="color: blue"><font style="background-color: #ffff00">1.6.0.0</font></span>"<span style="color: blue">/></span></p> <p style="margin: 0px"><span style="color: blue">      </</span><span style="color: #a31515">dependentAssembly</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    </</span><span style="color: #a31515">assemblyBinding</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  </</span><span style="color: #a31515">runtime</span><span style="color: blue">></span></p> </div> <p>and it works again.</p> <p>However, some of the samples did not with 1.6 but only with 1.5. Maybe I messed up with the latest SDK installation.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1tag:blogger.com,1999:blog-8040115472186352073.post-37824673485221230022012-01-16T10:42:00.001+01:002012-01-16T10:42:13.371+01:00Azure Connect<p>Using Windows “Azure Connect” - a service from the Windows Azure platform – one can establish a protected network connection between enterprise computers and the cloud roles (E2C). This virtual IPsec network allows for:</p> <ul> <li>easier migration of tiers of an applications to the cloud </li> <li>tunnel firewalls, proxies, NATs </li> <li>hybrid (cloud to on-premise) apps </li> <li>various higher-level communication protocols </li> <li>apps where the protocol might change </li> <li>have high number of communicating endpoints </li> <li>domain joins (some ActiveDirectory; logins) </li> <li>remote administration, debugging and troubleshooting </li> <li>DNS </li> <li>etc. </li> </ul> <p>Setting up Connect is a 3 step process. There is a <a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg508836.aspx">tutorial</a> showing all the details.</p> <p>1. Get an activation token from the Azure portal and configure your Azure roles to use it.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihT8NDdMcrzSjaBJMovLqruhx5LZtiD6DDC1sUNsdZ4JHz_N28E_enJ5b3kqdt9ssLrowA-OGg_Oqnp7ynRrHis3tnPuicSdSo396cluwemojOz2AZ6vTlJcHAjO2uj_kApTqTos5MPX-f/s1600-h/image31.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-eEot1yRR60s/TxPw3DSqPeI/AAAAAAAABfY/F6TH6Dj6YkI/image_thumb1.png?imgmax=800" width="731" height="180" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirqP2kBmZlWAHDxfeDxkiJ-jvD56htz8xgqgYA5ccLrV21ZuGKXCzQ8IVxRofv5i9wUaMulRV6LMiSGnrjYDMQSz4Hq7-_fSIOzjT6nyNIN7kB7bxydVaA_fCjuGPD5qcde8Cly6bs9Cz7/s1600-h/image%25255B5%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-Z-3iaHCrlSI/TxPw5Aic85I/AAAAAAAABfo/YPQie_mFkSU/image_thumb%25255B3%25255D.png?imgmax=800" width="737" height="335" /></a></p> <p>Copy the token into your role’s properties / virtual network settings</p> <p><a href="http://lh6.ggpht.com/-TU1GhRtikGg/TxPw5kQUq-I/AAAAAAAABfs/tVlwkVl4PZs/s1600-h/image12.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEzOHP4mDFBT8GqPZRBC6_maxCkXDFuZOAMPF_bDzZP_OB1HkVBNwRw-Bqi-d2Gyv82l65LxJRmxIt9e9RAO4jHDFYPMlvtl_-Hux3C1X9GKvdCf7HH8bm7ECld87LINesD51v6I6Ms2ML/?imgmax=800" width="737" height="267" /></a></p> <p>Now you publish your Azure roles to the staging or production environment in the cloud. Wait until the service is ready and check that it appears in the portals “Virtual network” –> “Groups and Roles” and “Activated Endpoints”.</p> <p>2. Enable local machines to connect to roles in the cloud. Install the Connect Agent on local machines. Copy the link URL to a browser, download the configured executable and run it. A system tray icon like the following should appear</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNxmTRZPdbdD7WCDH_4DrwalF64GJsRQD6PZIaKxYmd-Uwu6NUWpy4T4CEcg8JThyphenhyphen3BvdnRu3zsLO4JYA6fVwmZFQDKjzQTtRPbkHWEChgLnoxJrQO255EeK7DKT_dFDt9S-3ozTfQ6d2F/s1600-h/image3.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFcXRsIziF1eGpjvnUpPlRaggmTTv2Z17864e1yXIn9Sr7jjA6AoNYTy4UZI8eIrcPhJ_xPmepVIt3QGRAx1i-IRvE8LfpCn8ERnOqTpw-I0Z0NOR5mHjDety5d5pz5VusMRlA3w0SxwxU/?imgmax=800" width="69" height="50" /></a></p> <p>3. Pair the local machines and Azure roles in a “Group” (network policy). In the portal click Create Group</p> <p><a href="http://lh3.ggpht.com/-SIWlMAT2uPM/TxPw8NOD6wI/AAAAAAAABgM/LPtvoucJu2o/s1600-h/image9.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-ydzpCgLmAu8/TxPw86EG8UI/AAAAAAAABgU/JEvXJLqrYyw/image_thumb41.png?imgmax=800" width="639" height="451" /></a></p> <p>The system tray icon should change to connected now.</p> <p>Please note that ping will not work until you enable it in your role using a startup task script. From my limited home network I experienced some significant (first-hit) network delays</p> <p><em>Pinging RD00155D3A622D [2a01:111:f102:121:858:cf20:a9dd:5639] with 32 bytes of data: <br />Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=299ms <br />Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=258ms <br />Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=359ms <br />Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=368ms</em></p> <p><em>Ping statistics for 2a01:111:f102:121:858:cf20:a9dd:5639: <br />Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), <br />Approximate round trip times in milli-seconds: <br />    Minimum = 258ms, Maximum = 368ms, Average = 321ms</em></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-56553000345590606112012-01-16T10:36:00.001+01:002012-01-16T10:36:03.562+01:00Microsoft Azure SQL Data Sync<p>Azure Data Sync let’s you synchronize enterprise (on-premise) SQL Server (2005 and above) databases with SQL Azure databases – or several SQL Azure databases. There is a local agent and a cloud sync group service necessary for it to work.</p> <p>This is the first preview from Nov 14 2011; let’s have a try.</p> <p>In the management portal navigation tree go to Data Sync, select a subscription, a data center region, </p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHpBwiqeseKfRxwpK4b_Pm4-Z8ZmYj261mmXu_bntS98zstYy58QKA3M03RI60FGuxi7DdY8TX8Vvv0yw20lGi-IYJUnKfeCh-TRq6tUy356by-RrHCP_r9wL3HnUCWeh2Vbt7ky-Nu6Ts/s1600-h/image4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYWeuV9EBzG-U3qccibIsUk2nnGxb-562uPTxhJ3u4W3pj2A9g6BVZuuvUd04c3mO0_zF-AtLICqw17epUcQ3GrVq9lyr5k4wR68jyvG7VW3PMQg3qjExJyfvwO4GGw3_FAILRVQhQZdYi/?imgmax=800" width="522" height="318" /></a></p> <p>You now have two options: </p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYGEu3ILsrZUdYITmg5oU5tDcH5LUqaQmM96GSXPSNgw4WzD_B5w8N6jkF5x7GBaD4IrJ-_VBHXAfsOMHEl6Xhwpwv5pdYIHZlh1RhjjNq1OamarkSjO4rFwfhrK-XbA8tgQUfEzJ7KDLN/s1600-h/image15.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8TuyhZHrSmYgzGsIUJ380fdv16KrDhy1VzJMJqUjCOevtWHGUJgIL7r6LExeLc02kde8y5FORS8iNT9LIXiV7SceuEPcFf5AV-m7ioYmCC1pbw9GjVBLHEeUM9vo4eeYQGjXZXVVdvu5d/?imgmax=800" width="1028" height="303" /></a></p> <p>Let’s synchronize on-prem and a cloud SQL Azure database. The wizard leads you through the configuration of a sync group</p> <p><a href="http://lh6.ggpht.com/-W14jLc_DexU/TxPvEgawVzI/AAAAAAAABaw/WxiHTOAaZKk/s1600-h/image16.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTTcQdJ5ck6E4V1nzd-E3TZr-DM539tYFzsSANFgn9KwhCOF4Olqdp5oii4zWBoILPAiAzau5S12_N4hIKaDgILns1Pzljt00FxFgSqiduuT11S5_DxfULqlEORRN17m5STz8ecroJkvRX/?imgmax=800" width="876" height="421" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB7aeUC73y3I8k1wDLd0fV9stOlrnmaR2XimhZ3xVlIbiFXwbvj3bSX0v7RLugKrHdqpia8O0voM0sxZjDK77JdLV1usEGmFuLrSvE-3qmTIIWqytbC3y9LkLNne_SkYVbljVu3y2FZ4eC/s1600-h/image21.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-JjZ4Sb0pQ88/TxPvG-qC0yI/AAAAAAAABbI/AidiNm5kfZ8/image_thumb13.png?imgmax=800" width="574" height="450" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH-eg86f2pan3aMJuG2HryGq6OtWrCE1oc2qI954FQLjhUOZijJZHFXufnHm6ZkROUXWKN88uHb7KXt1JfBfgJE5Sief8r0qoeww8CpoR8f1PVgL-58s101e91rSfqKuMBPocU-yicVJED/s1600-h/image26.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-Qx75Ai5Mmvg/TxPvJPUYkSI/AAAAAAAABbY/dMhE1vA7YNg/image_thumb16.png?imgmax=800" width="577" height="502" /></a></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_Qhv0Ad8KTqx1kOyCL_FR0akmxmyld1B0G_9irPiE1CzR_uTSuYX9bLVP0aOCdQvipRmMYVTtIvkS4oKARevYd2jbBXLZpP-ezioxX4fePku1EmXHl6AT89k3g5cyaQg_2taYyaFtKbgH/s1600-h/image31.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu4m190KCcIcbLr1I_3nHM5OeYJj1_vq3hcvFIevtw1Va0-ElKhDBxJd2CFRYXs6g_NQs1UMLMdu29XVpmhV-2vLyMyhHnpMenj427Ks-BR9bhNGnu4vRcub-QSqkyJ9MpRIuBpxZL7HV0/?imgmax=800" width="579" height="572" /></a></p> <p><a href="http://www.microsoft.com/download/en/details.aspx?id=27693">Download</a> and install the so called Sync Agent for the local server.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS7V8VBblroHNGgpIGjsJrzsyo-sYq2zQ_Z6rO_AcCvgiNac1sMB__0UQ9hU2-y6-Any3ucC5C7s5toFbpyiLmAuAP1Qtj6fo0jonkGk37KaFUhvD10IHjSNWKMEFo8bqJ3Vjkx6jqq5sR/s1600-h/image36.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjIOtTz1tzVWvPnfl8eaU97COmiFO8bt5UYyFKSOJFTHPhhFx-9nuMPT4bvEW-wQoTpWyfV6ouY8OqYoc9dh3QawqG2peslR8qiR32vL1HzJ6rJ5uksm4okv-wWEYaa5n9xf9rlNNSu6SR/?imgmax=800" width="584" height="495" /></a></p> <p>Then start the Data Sync Agent Preview from the start menu.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguQC0VNDzVRpY8BynMzc7JoC4mmaaidosF_Kn0Lq5vpbUvb6nBOeHI4zjhpPpizK00iFYwU8nXhXhwI6wd6XJUSDMo5UDB6-VAiqmelTe9WUpjbXY3BXoJXSf_F6J70GcXXKDtLiXAOhkb/s1600-h/image%25255B4%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/--gLprKmCClI/TxPvNsy1o6I/AAAAAAAABcI/xRuwtxW4KBw/image_thumb%25255B1%25255D.png?imgmax=800" width="589" height="587" /></a></p> <p>Now generate an agent key from the management portal and copy it into the local agent wizard.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJdWTqs0j5aARb5S6CMCcl_2iBkb0Keb6iL0m-rLOsVRV0_VnrsUhbsWSOoCcemMukAqjPmiUTMPuiHtPCca0u68ZnRPruYSZDV1V1qUbT75gsSHmJ2n3Rdwu1fBNgvPgJ_RyngRp0et5P/s1600-h/image%25255B8%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-oMo-IX_QTd4/TxPvO1shT6I/AAAAAAAABcU/n-yWV7HSB_0/image_thumb%25255B3%25255D.png?imgmax=800" width="599" height="249" /></a></p> <p>Then register a SQL Server</p> <p><a href="http://lh4.ggpht.com/-nF7di2WngmY/TxPvPorm1hI/AAAAAAAABcg/AWfmnDWdzYI/s1600-h/image49.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-jDsx-bGmi2I/TxPvQTpCd1I/AAAAAAAABco/q6kbyJjF4Nc/image_thumb29.png?imgmax=800" width="586" height="484" /></a></p> <p>to get</p> <p><a href="http://lh4.ggpht.com/-my-uUkPGSkc/TxPvRE2sLiI/AAAAAAAABcs/T_-BW11DvRw/s1600-h/image54.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-LSw2xOSiswM/TxPvRgPqFQI/AAAAAAAABc0/rZN1bG67w8I/image_thumb32.png?imgmax=800" width="586" height="474" /></a></p> <p>Back in the portal we add the agent to the Sync Group</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1EOV-c2TeV7pmtc-WVnRkCdBZ8nQtwJrX1dniR4qGFFHeVtBJ3nGlBwK802Whphqq2Q4psUodknqIB_VpnxPBw6ogpuJgRuw6cjw3LoeObu5rboHBk0gDQTw1Erg5UVGypaGyU2LgaNxq/s1600-h/image59.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtgjHnKvwUbiUOnkJXkSPnMWKe6EVIt5a9_IwUfdD-NONdc7LjDnkMapDthZpuWIJrud0f9h7bYM2Z854VidtDOb1bN8eKgavA-MSxuBOfz1pyiNFSbFt9cz_zJ1f-bPaVto1gP2z2bzvH/?imgmax=800" width="587" height="599" /></a></p> <p>Now we are half way through. Now let’s add an SQL Azure database:</p> <p><a href="http://lh4.ggpht.com/-EXlnjwQhoVY/TxPvT5cVMkI/AAAAAAAABdQ/EARbPi9Loio/s1600-h/image63.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYobjJUSHhTMe1viRWikg4IEcgQoIPJcEHTm_cHgyfV680_Sl7BBbYxQaFinRCC9t1g0c1oPVaRN27JHHoeMpL5JvKBpal1GUXpBxnLi4U-w-TzZufOHDBNgYcakx9ohXSG9AyEkRv-RN2/?imgmax=800" width="594" height="378" /></a></p> <p>Just creating a new SQL Azure database for this demo – and selecting it in Step 3 above.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXEaKAWUiw3C0EY16oQhJtZhq7_cr-Q787twvXRsI_LesXDfCo_nw73ZoAsJFIZBMoXroc7MiUloaLZhmfXmpbday25ZRTvrfBb12XvYZWtDf46XcrOf3hvpnVP4E7lrZe17jZtJTi5SLQ/s1600-h/image%25255B12%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-KB5rbdGubGw/TxPvWhZv8tI/AAAAAAAABdo/JHxloukGQxU/image_thumb%25255B5%25255D.png?imgmax=800" width="603" height="566" /></a></p> <p>In the following step (4) we configure the scheduling, and the conflict resolution (client or hub wins)</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt6mpC5lQ3u9vLaTfqxdMDxCTF1zzdaFxm_g0PdwRGPPIUW0hph-_ycLFbCzNtoi011DD1hpUM7x9vqzHU_VOSsn6_kMF7_5UpIyU5Yl_cC4_HqHyE9eow235LPcE63SDm8qVAzSJ3SXm2/s1600-h/image73.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-3VALrSg7TGM/TxPvX3QWRcI/AAAAAAAABd4/-pMtjdI1Ymc/image_thumb43.png?imgmax=800" width="598" height="445" /></a></p> <p>Select the on-premise SQL database</p> <p><a href="http://lh4.ggpht.com/-nxkMYekXI-8/TxPvY2IBLzI/AAAAAAAABeA/VRMv7ajHxUU/s1600-h/image79.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhAxmDaofjrs9J0je89ShhBRcgVVnr8xqgVzPxImzrjupcaU3jGWVWL-GFLixVPSfFO5ojAkg29gkMx9Dh5oz3JKNGdLvSwks4D2QlwLm5ttfyX8H9MZADvxZfrAtQa-QU1oEcbClwlBNJ/?imgmax=800" width="598" height="775" /></a></p> <p>Click deploy now</p> <p><a href="http://lh3.ggpht.com/-k6L4oFsJTR8/TxPvbXoibQI/AAAAAAAABeQ/87EPPbRmfys/s1600-h/image83.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPKoxq363J8zMvsjVpDoKGrOyOfzR0adVmkKVJKjnSFvhqFHR5uXgkIsoz9doB14D5ZEuQonf1qQHzEopxXN7yUMX6mwXw5JCCfKvx8LEwyaKTMNTS3cQ1aUTD1b2IdXt4jix23MHwVCIe/?imgmax=800" width="842" height="147" /></a></p> <p>Done!</p> <p>Now, let’s see that it worked correctly. In the local Northwind database there are 2 people from Switzerland, add a row filter for Country = ‘Switzerland’. Then go the SSMS, connect the SQL Azure DB. There is a new dbo.Customers table now. Please also note the added tables for the change tracking. There are also some triggers and stored procedures added to your database. This may impact your runtime performance.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWgrnNlzgZH4VkE4cd9eRLENhFL6XQXAZzcDPxFzcc0wZAXfa96qYcD47g17xiVlDPko6eUpMbRznYRm_C1ssf3Kjt3WY3aIw3JC6vML1Deq9orvp8P2C9PJbX34wnyeevZ0gmbeIq5SyF/s1600-h/image87.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtTdNgvPjf7cSFaq_5yD3rIEqr8kDFuS9869E-TJ5hbJNJBdQBDyNkEmiR4p2lvfiHtoiDNrikPhoIawIbvr4ssMrvjEA5dSnFPxVz-n1R8CvDOI4aOBsj0b8Wr8Q9UlDb47NEMc8oRZmG/?imgmax=800" width="397" height="399" /></a></p> <p>There are the 2 rows as expected:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBpYK-fV_UfP-zGeNqCvU3bzUFb-alwsL_PHwlXstkwWZ1-z0Ydn7miLK40JeTDzI9GfEnuDbtofHw4D-qCC2CFvKaCMXoVONzJTldLoDMqK5jrIWNm_YK7gML8_crzaKcN0wyatlGnZm0/s1600-h/image91.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBbYES6_QKRj0OGaixSFZLBXPwNStRllNnEsWPRBNh_0EXIjxz13f6iXF9ys-SZ4WNZF-nTcdCzzp4DzF_RTfeGzoQkYwtE6Ow727-eSW-aQFz3qoM-dYVqxH-51gBi8zpiy_DRYSKLipe/?imgmax=800" width="947" height="126" /></a></p> <p>That’s it again in the portal</p> <p><a href="http://lh4.ggpht.com/-j0_VUTIOVDg/TxPvfTTjy_I/AAAAAAAABfA/0-RjZNKQCMI/s1600-h/image98.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-HGOXZAp0yC4/TxPvgnoK73I/AAAAAAAABfI/GZnz1nKJ5cM/image_thumb58.png?imgmax=800" width="1488" height="698" /></a></p> <p>This was actually super simple to setup. There are some best practices out <a href="http://social.technet.microsoft.com/wiki/contents/articles/2172.aspx">there</a>.</p> <p>Negative point: there does not seem to exist an API or .NET library for scripted configuration and operation.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-59950125091479931372011-11-25T20:38:00.001+01:002011-11-25T20:38:06.168+01:00Fun Project: DotNetNuke module views<p>Last time I showed you how to create, build, package, upload and use a simple DNN module, developed in C# using Visual Studio <br /> 2010. Let’s get started by thinking (and writing down <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh5.ggpht.com/-yfaSEogB8qw/Ts_uf7cC9II/AAAAAAAABY0/0QaEhPJjNjk/wlEmoticon-smile2.png?imgmax=800" />) some requirements.</p> <h4>Requirements</h4> <p>Non-functional</p> <p>R-NFR1 DotNetNuke 05.06 <br />R-NFR2 ASP.NET 4 <br />R-NFR3 local testability without DNN installation <br /></p> <p>Use Cases</p> <p>As a client I want to:</p> <p>R-U1 – Create an online account on the site <br />R-U2 – Log in and out <br />R-U3 – Choose a treatment <br />R-U4 – Choose a time/date <br />R-U5 – Book a massage  <br />R-U6 – Got sent an email confirmation <br />R-U6.1 with an outlook appointment attached to it <br />R-U7 – get shown my booked treatments in detail</p> <p>As an administrator I want to:</p> <p>R-A1 – Define treatments (duration, title, description) <br />R-A2 – Define time windows (opening or working hours) <br />R-A3 – Show (todays, etc.) bookings <br />R-A4 – Got sent an email with a client booking information <br />R-A5 – Manage accounts (list, add, edit, delete)</p> <h4>New Web Project</h4> <p>To separate DotNetNuke module stuff from booking web functionality I added a new ASP.NET web project to the solution</p> <p><a href="http://lh5.ggpht.com/-arQfuvHFL3A/Ts_ugWuY1jI/AAAAAAAABY4/jgWsn9szvPg/s1600-h/image3.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-xp9cryYgEoI/Ts_ugxO86aI/AAAAAAAABZA/ody3H8AyuNI/image_thumb1.png?imgmax=800" width="343" height="127" /></a></p> <p>remove the generated pages, sub folders and strip down the web.config file to a minimum.</p> <p>Now add a web user control to the BookingViews project</p> <p><a href="http://lh5.ggpht.com/-98XjVcB1axM/Ts_uhZYEsZI/AAAAAAAABZI/_gXBLjn_axU/s1600-h/image15.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-RXebIHby1nM/Ts_uiIwTJLI/AAAAAAAABZQ/5AUZqu9Q-eg/image_thumb9.png?imgmax=800" width="827" height="244" /></a></p> <h4>Telerik</h4> <p>Writing an outlook style schedule/calendar control in ASP.NET seems like a huge effort. Let’s get a commercial control library suite including a <a href="http://demos.telerik.com/aspnet-ajax/scheduler/examples/overview/defaultcs.aspx">schedule control</a>. As DNN already contains Telerik controls the evaluation was short. They have an excellent reputation when talking to colleagues.</p> <h4>Data Model</h4> <p>First let’s show the data access layer where the massage bookings and treatment offerings are persisted. Using the Entity Framework 4.0 model first approach, I create the following model:</p> <p><a href="http://lh4.ggpht.com/-kYtXwjzmSYk/Ts_ui5457WI/AAAAAAAABZc/uwCQXm9pS7g/s1600-h/image5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXcgiIyOPjCEev6ypAWygkJdce_u3dGyebwuM3FsnhoA6DekDz9xyCeiIc_Vzj-r8-kALt2TrnoGt-gerISFvlC11j_OGULSf0gc6ANbXJNLKfh88LBtnsoXlFgm4p_oTQLUAqsA171ldk/?imgmax=800" width="830" height="516" /></a></p> <p>The BookingEntry and Treatment entities were added in the model edmx in VS design view. However, the User entity was imported from the existing DotNetNuke database (table first). Adding some relations and I can take advantage of the DNN register/login/user functionality in my bookings.</p> <h4>View</h4> <p>Learning and configuring the module view took more effort. This is the resulting aspx:</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="background: yellow"><%</span><span style="color: blue">@</span> <span style="color: maroon">Page</span> <span style="color: red">Language</span><span style="color: blue">="C#"</span> <span style="color: red">AutoEventWireup</span><span style="color: blue">="true"</span> <span style="color: red">CodeBehind</span><span style="color: blue">="BookingForm.aspx.cs"</span> <span style="color: red">Inherits</span><span style="color: blue">="BookingViews.BookingForm"</span> <span style="background: yellow">%></span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="background: yellow"><%</span><span style="color: blue">@</span> <span style="color: maroon">Register</span> <span style="color: red">Assembly</span><span style="color: blue">="Telerik.Web.UI"</span> <span style="color: red">Namespace</span><span style="color: blue">="Telerik.Web.UI"</span> <span style="color: red">TagPrefix</span><span style="color: blue">="telerik"</span> <span style="background: yellow">%></span><span style="color: blue"><!</span><span style="color: maroon">DOCTYPE</span> <span style="color: red">html</span> <span style="color: red">PUBLIC</span> <span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"</span> <span style="color: blue">"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><</span><span style="color: maroon">html</span> <span style="color: red">xmlns</span><span style="color: blue">="http://www.w3.org/1999/xhtml"><</span><span style="color: maroon">head</span> <span style="color: red">runat</span><span style="color: blue">="server"><</span><span style="color: maroon">title</span><span style="color: blue">></</span><span style="color: maroon">title</span><span style="color: blue">></</span><span style="color: maroon">head</span><span style="color: blue">><</span><span style="color: maroon">body</span><span style="color: blue">><</span><span style="color: maroon">form</span> <span style="color: red">id</span><span style="color: blue">="form1"</span> <span style="color: red">runat</span><span style="color: blue">="server"></span></p> <p style="margin: 0px"><span style="color: blue"></span></p> <p style="margin: 0px">    <span style="color: blue"><</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ScriptManager</span> <span style="color: red">ID</span><span style="color: blue">="ScriptManager1"</span> <span style="color: red">runat</span><span style="color: blue">="server"></span></p> <p style="margin: 0px">    <span style="color: blue"></</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ScriptManager</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></span></p> <p style="margin: 0px">    <span style="color: blue"><</span><span style="color: maroon">div</span> <span style="color: red">style</span><span style="color: blue">="height: 527px; width: 827px"></span></p> <p style="margin: 0px">        <span style="color: blue"><</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">RadScheduler</span> <span style="color: red">ID</span><span style="color: blue">="RadScheduler1"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span> <span style="color: red">Culture</span><span style="color: blue">="de-CH"</span> <span style="color: red">DayEndTime</span><span style="color: blue">="19:00:00"</span></p> <p style="margin: 0px">            <span style="color: red">DayStartTime</span><span style="color: blue">="07:00:00"</span> <span style="color: red">FirstDayOfWeek</span><span style="color: blue">="Monday"</span> <span style="color: red">Height</span><span style="color: blue">="558px"</span> <span style="color: red">SelectedView</span><span style="color: blue">="WeekView"</span></p> <p style="margin: 0px">            <span style="color: red">ShowViewTabs</span><span style="color: blue">="False"</span> <span style="color: red">Skin</span><span style="color: blue">="Forest"</span> <span style="color: red">Width</span><span style="color: blue">="800px"</span> <span style="color: red">WorkDayEndTime</span><span style="color: blue">="19:00:00"</span> <span style="color: red">WorkDayStartTime</span><span style="color: blue">="07:00:00"</span></p> <p style="margin: 0px">            <span style="color: red">SelectedDate</span><span style="color: blue">="2011-11-01"</span> <span style="color: red">DataEndField</span><span style="color: blue">="End"</span> <span style="color: red">DataKeyField</span><span style="color: blue">="Id"</span> </p> <p style="margin: 0px">            <span style="color: red">DataStartField</span><span style="color: blue">="Start"</span> <span style="color: red">DataSubjectField</span><span style="color: blue">="Subject"</span> </p> <p style="margin: 0px">            <span style="color: red">onappointmentcommand</span><span style="color: blue">="RadScheduler1_AppointmentCommand"</span> </p> <p style="margin: 0px">            <span style="color: red">ontimeslotcreated</span><span style="color: blue">="RadScheduler1_TimeSlotCreated"</span> </p> <p style="margin: 0px">            <span style="color: red">DataSourceID</span><span style="color: blue">="BookingEntryDataSource"</span> <span style="color: red">DataDescriptionField</span><span style="color: blue">="Remarks"</span> </p> <p style="margin: 0px">            <span style="color: red">EnableDescriptionField</span><span style="color: blue">="True"></span></p> <p style="margin: 0px">            <span style="color: blue"><</span><span style="color: maroon">ResourceTypes</span><span style="color: blue">></span></p> <p style="margin: 0px">                <span style="color: blue"><</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">ResourceType</span> <span style="color: red">DataSourceID</span><span style="color: blue">="TreatmentDataSource"</span> </p> <p style="margin: 0px">                    <span style="color: red">ForeignKeyField</span><span style="color: blue">="TreatmentId"</span> <span style="color: red">KeyField</span><span style="color: blue">="Id"</span> <span style="color: red">Name</span><span style="color: blue">="TreatmentResource"</span> </p> <p style="margin: 0px">                    <span style="color: red">TextField</span><span style="color: blue">="Name"</span> <span style="color: blue">/></span></p> <p style="margin: 0px">            <span style="color: blue"></</span><span style="color: maroon">ResourceTypes</span><span style="color: blue">></span></p> <p style="margin: 0px">            <span style="color: blue"><</span><span style="color: maroon">WeekView</span> <span style="color: red">DayEndTime</span><span style="color: blue">="19:00:00"</span> <span style="color: red">DayStartTime</span><span style="color: blue">="07:00:00"</span> <span style="color: red">HeaderDateFormat</span><span style="color: blue">="dd.MM.yyyy"</span></p> <p style="margin: 0px">                <span style="color: red">WorkDayEndTime</span><span style="color: blue">="19:00:00"</span> <span style="color: red">WorkDayStartTime</span><span style="color: blue">="07:00:00"</span> <span style="color: blue">/></span></p> <p style="margin: 0px">            <span style="color: blue"><</span><span style="color: maroon">AppointmentTemplate</span><span style="color: blue">></span></p> <p style="margin: 0px">                <span style="color: blue"><</span><span style="color: maroon">span</span> <span style="color: red">style</span>        <span style="color: blue">="font-weight: bold; font-size: small"></span></p> <p style="margin: 0px">                    <span style="background: yellow"><%</span><span style="color: blue">#</span> Eval("Subject") <span style="background: yellow">%></span></p> <p style="margin: 0px">                <span style="color: blue"></</span><span style="color: maroon">span</span><span style="color: blue">></span></p> <p style="margin: 0px">                <span style="color: blue"><</span><span style="color: maroon">br</span> <span style="color: blue">/></span></p> <p style="margin: 0px">                <span style="color: blue"><</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ImageButton</span> <span style="color: red">ID</span><span style="color: blue">="ImageButton1"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span> <span style="color: red">ImageUrl</span><span style="color: blue">="~/Resources/Calendar.png"</span> <span style="color: red">OnClick</span><span style="color: blue">="ExportOutlook"</span> <span style="color: red">CommandName</span><span style="color: blue">="ExportOutlook"</span> <span style="color: blue">/></span></p> <p style="margin: 0px">            <span style="color: blue"></</span><span style="color: maroon">AppointmentTemplate</span><span style="color: blue">></span></p> <p style="margin: 0px">        <span style="color: blue"></</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">RadScheduler</span><span style="color: blue">></span></p> <p style="margin: 0px">    <span style="color: blue"></</span><span style="color: maroon">div</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></span></p> <p style="margin: 0px">    <span style="color: blue"><</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">RadAjaxManager</span> <span style="color: red">runat</span><span style="color: blue">="server"></span></p> <p style="margin: 0px">        <span style="color: blue"><</span><span style="color: maroon">AjaxSettings</span><span style="color: blue">></span></p> <p style="margin: 0px">            <span style="color: blue"><</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">AjaxSetting</span> <span style="color: red">AjaxControlID</span><span style="color: blue">="RadScheduler1"></span></p> <p style="margin: 0px">                <span style="color: blue"><</span><span style="color: maroon">UpdatedControls</span><span style="color: blue">></span></p> <p style="margin: 0px">                    <span style="color: blue"><</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">AjaxUpdatedControl</span> <span style="color: red">ControlID</span><span style="color: blue">="RadScheduler1"</span> <span style="color: blue">/></span></p> <p style="margin: 0px">                <span style="color: blue"></</span><span style="color: maroon">UpdatedControls</span><span style="color: blue">></span></p> <p style="margin: 0px">            <span style="color: blue"></</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">AjaxSetting</span><span style="color: blue">></span></p> <p style="margin: 0px">        <span style="color: blue"></</span><span style="color: maroon">AjaxSettings</span><span style="color: blue">></span></p> <p style="margin: 0px">    <span style="color: blue"></</span><span style="color: maroon">telerik</span><span style="color: blue">:</span><span style="color: maroon">RadAjaxManager</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></span></p> <p style="margin: 0px">    <span style="color: blue"><</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ObjectDataSource</span> <span style="color: red">ID</span><span style="color: blue">="BookingEntryDataSource"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span> </p> <p style="margin: 0px">        <span style="color: red">DataObjectTypeName</span><span style="color: blue">="My.DotNetNuke.Modules.BookingModule.BookingEntry"</span> </p> <p style="margin: 0px">        <span style="color: red">DeleteMethod</span><span style="color: blue">="Delete"</span> <span style="color: red">InsertMethod</span><span style="color: blue">="Add"</span> <span style="color: red">SelectMethod</span><span style="color: blue">="GetAll"</span> </p> <p style="margin: 0px">        <span style="color: red">TypeName</span><span style="color: blue">="My.DotNetNuke.Modules.BookingModule.Data.BookingEntryDataRepository"</span> </p> <p style="margin: 0px">        <span style="color: red">UpdateMethod</span><span style="color: blue">="Update"></</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ObjectDataSource</span><span style="color: blue">></span></p> <p style="margin: 0px">    <span style="color: blue"><</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ObjectDataSource</span> <span style="color: red">ID</span><span style="color: blue">="TreatmentDataSource"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span> </p> <p style="margin: 0px">        <span style="color: red">DataObjectTypeName</span><span style="color: blue">="My.DotNetNuke.Modules.BookingModule.Treatment"</span> </p> <p style="margin: 0px">        <span style="color: red">DeleteMethod</span><span style="color: blue">="Delete"</span> <span style="color: red">InsertMethod</span><span style="color: blue">="Add"</span> <span style="color: red">SelectMethod</span><span style="color: blue">="GetAll"</span> </p> <p style="margin: 0px">        <span style="color: red">TypeName</span><span style="color: blue">="My.DotNetNuke.Modules.BookingModule.Data.TreatmentDataRepository"</span> </p> <p style="margin: 0px">        <span style="color: red">UpdateMethod</span><span style="color: blue">="Update"></</span><span style="color: maroon">asp</span><span style="color: blue">:</span><span style="color: maroon">ObjectDataSource</span><span style="color: blue">></span></p> <p style="margin: 0px">    <span style="color: blue"></</span><span style="color: maroon">form</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">body</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">html</span><span style="color: blue">></span></p> </div> <p>The control’s data sources are of type ObjectDataSource. BookingEntryDataSource and TreatmentDataSource both implement the IRepository<T> interface. This hides the EF stuff behind a façade and allowed better testability than the EntityDataSource:</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: gray">    ///</span><span style="color: green"> </span><span style="color: gray"><summary></span></p> <p style="margin: 0px">    <span style="color: gray">///</span><span style="color: green"> Interface to decouple entities from data access.</span></p> <p style="margin: 0px">    <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary></span></p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">interface</span> <span style="color: #2b91af">IRepository</span><T> <span style="color: blue">where</span> T: <span style="color: blue">class</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">void</span> Add(T entity);</p> <p style="margin: 0px">        <span style="color: blue">void</span> Delete(T entity);</p> <p style="margin: 0px">        <span style="color: #2b91af">ICollection</span><T> GetAll();</p> <p style="margin: 0px">        T GetById(T entryWithKeyOnly);</p> <p style="margin: 0px">        <span style="color: blue">void</span> Update(T entity);</p> <p style="margin: 0px">    }</p> </div> <p>Note that I added the telerik rad scheduler, configured a week view, added some appointment resources and DataSources to be bound in the scheduler control.</p> <p>And this is the final result:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRLu4vc0fnxhCs8wYQwYh3T5B3syf5flh3tNvrYUfC3dWr6ShylNcZTYjVSm2EnaowSnLVLq5aeXIyeYVcygyP8nCy_ByhlBVsQ_Lei_CyUvzsXKDNBBjDXv82fm9E3lX9XdchT6M8__RO/s1600-h/image%25255B10%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-i5yqALz4O38/Ts_ulguUCaI/AAAAAAAABZ0/xATG6CSJ-Bw/image_thumb%25255B5%25255D.png?imgmax=800" width="752" height="546" /></a></p> <p>Double clicking shows or edits the details of the appointment</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZws2aQEomJk6VWI-XNSowN-Cs7HEPXp0strewg5it0y0IpRB66IcTaiRW2ASzuO5doaIoUNEujRE5q6v4txas43FucWEwhNMhjTXRAuc1s6jBhnS1UvFbeLPDGSIdI9rkJWyvMjMXSP5z/s1600-h/image%25255B15%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-3I3VpiahxXY/Ts_unNQS7QI/AAAAAAAABaA/Nqyh961Pjxs/image_thumb%25255B8%25255D.png?imgmax=800" width="754" height="551" /></a></p> <p>I hope this 3-part series of my (hobby project) development “minutes” gave you some insight around DotNetNuke module development in Visual Studio using C#.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com3tag:blogger.com,1999:blog-8040115472186352073.post-59629816548384289552011-11-25T09:35:00.001+01:002011-11-25T09:40:28.240+01:00Azure AppFabric Caching ASP.NET Session State Provider – not working with 2 Instances in the local Compute Emulator<p> </p> <p>A customer asked me for help about this.</p> <p><strong>Introduction</strong></p> <p>Windows Azure AppFabric Cache is a subset of the Windows Server 2008 R2 AppFabric distributed in-memory cache (aka “Velocity”) and typically provides it’s services for ASP.NET session provider and output caching.</p> <p><strong>Enable Cache</strong></p> <p>To speed up your web apps performance you first need to enable this Azure feature on the management portal</p> <p><a href="http://lh5.ggpht.com/-RM3-X8XJoRs/Ts9TBQIgsqI/AAAAAAAABW0/PVSedjCEPzA/s1600-h/image%25255B15%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/--dufSSbHgJo/Ts9TCNDo3pI/AAAAAAAABW8/GTdpiGZHxgs/image_thumb%25255B8%25255D.png?imgmax=800" width="793" height="315" /></a></p> <p>Click New Service Namespace –> select Cache –> select your Azure subscription (for the billing) –> the region of the data center –> and a name.</p> <p><strong>Configure Web App to use the cache</strong></p> <p>In the management portal Properties copy your host name and authentication token </p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRqd6eMEQfY0duIJLXOUGTQd8tNQwNsr6CmRShdN7fhe2cTg-mJOEJ-FJTnHcWKQ-MAKiRhD4GoFv3UIWpt8LNlVKTbhwbG-86ree17M0rlw-BZiodNo9AWGE3RC_ICsz0DfoXhA8DDhV6/s1600-h/image%25255B16%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQQ-Ubht1u3CJ8Ee3LP1cjAY8iOX0E9APVG5Dby6LAmIc0ggJVa0Kl9j0tVbCqgqm2gjni9GDJHDyZ2gTEhU4bFcDNKKrqrz8fOYEEBgm8_ry6da-JIznsdJ3aCfk2bSZwTTVfPcTOPuAV/?imgmax=800" width="317" height="452" /></a></p> <p><a href="http://lh6.ggpht.com/-X4yO6QN6rGc/Ts9TEl4UnAI/AAAAAAAABXQ/WPLLM2jCFWA/s1600-h/image14.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp_lC9zP7x_pFNDqGOTP0IuJtvOHkFvlf_0onlZ6Xav57tT4hGV7tf0fmdn5gCTkpmJcmUq-jNpTW9zaQZDuoPtMM5vl6ToxYSH0yQviXfnPqycYtukpPAyYszea0fVT0aYApPU_GoJfob/?imgmax=800" width="662" height="200" /></a></p> <p>to your web.config <Configuration> section:</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: #a31515">configSections</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">section</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dataCacheClients</span>"<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core</span>"<span style="color: blue"> </span><span style="color: red">allowLocation</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"<span style="color: blue"> </span><span style="color: red">allowDefinition</span><span style="color: blue">=</span>"<span style="color: blue">Everywhere</span>"<span style="color: blue">/></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: #a31515">configSections</span><span style="color: blue">></span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: #a31515">dataCacheClients</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">dataCacheClient</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">hosts</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <</span><span style="color: #a31515">host</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">[SERVICE-HOST-NAME]</span>"<span style="color: blue"> </span><span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>"<span style="color: blue"> /></span></p> <p style="margin: 0px"><span style="color: blue">    </</span><span style="color: #a31515">hosts</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">securityProperties</span><span style="color: blue"> </span><span style="color: red">mode</span><span style="color: blue">=</span>"<span style="color: blue">Message</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <</span><span style="color: #a31515">messageSecurity</span></p> <p style="margin: 0px"><span style="color: blue">        </span><span style="color: red">authorizationInfo</span><span style="color: blue">=</span>"<span style="color: blue">[AUTHORIZATION INFO]</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      </</span><span style="color: #a31515">messageSecurity</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    </</span><span style="color: #a31515">securityProperties</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  </</span><span style="color: #a31515">dataCacheClient</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: #a31515">dataCacheClients</span><span style="color: blue">></span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: #a31515">system.web</span><span style="color: blue">></span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">sessionState</span><span style="color: blue"> </span><span style="color: red">mode</span><span style="color: blue">=</span>"<span style="color: blue">Custom</span>"<span style="color: blue"> </span><span style="color: red">customProvider</span><span style="color: blue">=</span>"<span style="color: blue">AppFabricCacheSessionStoreProvider</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">providers</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">AppFabricCacheSessionStoreProvider</span>"</p> <p style="margin: 0px"><span style="color: blue">            </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache</span>"</p> <p style="margin: 0px"><span style="color: blue">            </span><span style="color: red">cacheName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"</p> <p style="margin: 0px"><span style="color: blue">            </span><span style="color: red">useBlobMode</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"</p> <p style="margin: 0px"><span style="color: blue">            </span><span style="color: red">dataCacheClientName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue"> /></span></p> <p style="margin: 0px"><span style="color: blue">    </</span><span style="color: #a31515">providers</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  </</span><span style="color: #a31515">sessionState</span><span style="color: blue">></span></p> <p style="margin: 0px"> </p> </div> <p>Add assembly references to the Azure libraries</p> <p><font face="Courier New">Microsoft.ApplicationServer.Caching.Client.dll <br />Microsoft.ApplicationServer.Caching.Core.dll <br />Microsoft.Web.DistributedCache.dll <br />Microsoft.WindowsFabric.Common <br />Microsoft.WindowsFabric.Data.Common</font></p> <p><strong>2 Instances</strong></p> <p>Configure your web role to use 2 instances. Otherwise you won’t notice the problem.</p> <p><strong>Attention</strong></p> <p>Make sure, you do not confuse with the Windows Server 2008 R2 AppFabric caching libraries. Use the ones under </p> <p>C:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies\NET4.0\Cache</p> <p><strong>Access the cache from code</strong></p> <p>In the following example from the <a href="http://www.microsoft.com/windowsazure/appfabric/">AppFabric Lab Samples</a>, store some shopping cart entries into the session</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: #2b91af">List</span><<span style="color: blue">string</span>> cart = <span style="color: blue">this</span>.Session[<span style="color: #a31515">"Cart"</span>] <span style="color: blue">as</span> <span style="color: #2b91af">List</span><<span style="color: blue">string</span>> ?? <span style="color: blue">new</span> <span style="color: #2b91af">List</span><<span style="color: blue">string</span>>();</p> <p style="margin: 0px">cart.Add(selectedItem);</p> <p style="margin: 0px">Session[<span style="color: #a31515">"Cart"</span>] = cart;</p> </div> <p>and read back</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue">var</span> itemsInSession = <span style="color: blue">this</span>.Session[<span style="color: #a31515">"Cart"</span>] <span style="color: blue">as</span> <span style="color: #2b91af">List</span><<span style="color: blue">string</span>> ?? <span style="color: blue">new</span> <span style="color: #2b91af">List</span><<span style="color: blue">string</span>>();</p> </div> <p><strong>Test it</strong></p> <p>Now when I start the app and add a product to the cart, stop the compute emulator, do an iisreset.exe and refresh the page – then I still see the product. This now comes from the Azure AppFabric Cache:</p> <p><a href="http://lh6.ggpht.com/-1hA8JRKzn9U/Ts9TFwo_xII/AAAAAAAABXk/Fcb38bmHW7E/s1600-h/image19.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgNPHensm2vBFguObEiJOOZNHUzCDhC1Y78NXGLg-mHVZAWgnBlJHY8DcbBm52baL24Ctdzlfa_JrfTNTdNsfjwg6YPEKC8mFtzcSTgBIt9k2TXvJl7Qdy7TCBzgsJCqwuyjzQlGUffouq/?imgmax=800" width="589" height="416" /></a></p> <p>on instance 1. From the debugger:</p> <p>Checkout on instance deployment16(44).AzureStoreService.<font color="#ff0000">MVCAzureStore_IN_1</font></p> <p>Pressing F5 to refresh the page again in the browser I suddenly don’t see the product anymore</p> <p><a href="http://lh6.ggpht.com/-BrQQN7end9E/Ts9TH8qvYFI/AAAAAAAABX0/kGqKG26LzV8/s1600-h/image23.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZJLIQnsxZLA_0ICp_r2hgwpVkOp-RwDDY42nPDD1uhFE5kg8DEDlwUCdPRuEJm7xijL7i7hLkFLOxZo1rganrguGQdYrr-iKjPh2bAMQAbW-2deSloxn9d2YVuzDvl9rfcS-4d40PpWcx/?imgmax=800" width="594" height="412" /></a></p> <p>on instance 0. From debugger</p> <p>Checkout on instance deployment16(44).AzureStoreService.<font color="#ff0000">MVCAzureStore_IN_0</font></p> <p>Pressing IEs F5 again and again, shows or don’t shows the product …. ?!?</p> <p><strong>Problem</strong></p> <p>So the findings are, that the session cache basically works, but not in a (load-balanced) multi-instance environment on the local development fabric compute emulator! Depending on the web role instance (0 or 1) a different session cache is used.</p> <p>It looks like each web role instance is still using default ASP.NET in-proc session state, meaning you'd have different session state on each instance.</p> <p>However, the session id is the same </p> <p><a href="http://lh3.ggpht.com/-Eu-PhWJadgg/Ts9TJcP2rkI/AAAAAAAABYE/ghuJzjZOBAU/s1600-h/image27.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI4ptJpm94c3dFIZa60cWFnadR0Iay-ry-j1xv6PjPFB7BlbpyjeYC9AijVPCIExU03zwXhvkSSPtlPmWgMZzZFjqdAD3HID_HM_1h9EwvDjNCMh0UgWNiHia1Kng2zcmuhhv8CDvcIAzZ/?imgmax=800" width="754" height="148" /></a></p> <p>I made sure the default in-proc session state provider is removed by commenting it and <font color="#ff0000"><clear/></font>ing the providers list:</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue"><!--</span><span style="color: green"><sessionState mode="InProc" customProvider="DefaultSessionProvider"></span></p> <p style="margin: 0px"><span style="color: green">  <providers></span></p> <p style="margin: 0px"><span style="color: green">    <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" /></span></p> <p style="margin: 0px"><span style="color: green">  </providers></span></p> <p style="margin: 0px"><span style="color: green"></sessionState></span><span style="color: blue">--></span></p> <p style="margin: 0px"><span style="color: blue"><!--</span><span style="color: green"> If session state needs to be saved in AppFabric Caching service, add the following to web.config inside system.web. If SSL is required, then change dataCacheClientName to "SslEndpoint". </span><span style="color: blue">--></span></p> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: #a31515">sessionState</span><span style="color: blue"> </span><span style="color: red">mode</span><span style="color: blue">=</span>"<span style="color: blue">Custom</span>"<span style="color: blue"> </span><span style="color: red">customProvider</span><span style="color: blue">=</span>"<span style="color: blue">AppFabricCacheSessionStoreProvider</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">providers</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">   <font color="#9b00d3"> <</font></span><font color="#9b00d3"><span style="color: #a31515">clear</span><span style="color: blue">/></span></font></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">AppFabricCacheSessionStoreProvider</span>"</p> <p style="margin: 0px"><span style="color: blue">          </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache</span>"</p> <p style="margin: 0px"><span style="color: blue">          </span><span style="color: red">cacheName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"</p> <p style="margin: 0px"><span style="color: blue">          </span><span style="color: red">useBlobMode</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"</p> <p style="margin: 0px"><span style="color: blue">          </span><span style="color: red">dataCacheClientName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue"> /></span></p> <p style="margin: 0px"><span style="color: blue">  </</span><span style="color: #a31515">providers</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: #a31515">sessionState</span><span style="color: blue">></span></p> </div> <p><strong>All over again – it works in the Cloud</strong></p> <p>Not sure I did something wrong in the Lab sample – I started all over again from scratch with a simple app that stores the text box value into the Session[] state and reads it back using the buttons. Value/InstanceId/SessionID are written to the label below.</p> <p>Same problem on the local fabric – BUT …</p> <p>… storing from IE’s first tab the value “m5” to web role instance 0 in session 5WJJ:</p> <p><a href="http://lh4.ggpht.com/-Sr7KgzPSy8Y/Ts9TLqP-jrI/AAAAAAAABYU/GewGEMsnPzQ/s1600-h/image%25255B14%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx90-6OaYOOuAj4yugkwmly1CkC2_JxDbsle09OUEMK8mst7vSy_OOyF4qOyB36b1B5EqgoxJJTeWsSn11CrwH_1JsZ7z5LceCam18xc9hk5cLXg8RoKP6ja8KUTblsc3eN0egxFYDqkGL/?imgmax=800" width="764" height="429" /></a></p> <p>Reading back from IE’s second tab the value “m5” from web role instance 1 in session 5WJJ:</p> <p><a href="http://lh3.ggpht.com/-cBwrQ6KGzNg/Ts9TNiUBGmI/AAAAAAAABYk/B_HqDR-bgiQ/s1600-h/image%25255B9%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-33eWl8CSEDg/Ts9TOdrDiCI/AAAAAAAABYo/P1UHi4UGv5I/image_thumb%25255B4%25255D.png?imgmax=800" width="768" height="431" /></a></p> <p>gives me what I expected.</p> <p><strong>Help</strong></p> <p>As I understand this should not be the case? Seems to be an issue in the local compute emulator using the AppFabric cache service! It works in the cloud – but still makes local testing hard. Any ideas?</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com2tag:blogger.com,1999:blog-8040115472186352073.post-66644456826021341562011-11-23T17:10:00.001+01:002011-11-23T17:10:05.514+01:00Fun Project: DotNetNuke module development<p>This post shows you how to create a DNN module in C# using Visual Studio 2010 – from beginner to beginner – to make expectations clear.</p> <h5>Requirements</h5> <p>In time with the site going live, new requirements popped up:</p> <ul> <li>online bookings of treatments by clients </li> <li>manage massage treatments through my wife </li> <li>booking selected treatments using a kind of schedule/calendar view (clients) in predefined time windows / opening hours (admin). </li> <li>email confirmations (client and admin) </li> </ul> <p>I found no module for these <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Sad smile" src="http://lh3.ggpht.com/-RHI1M7KGqdY/Ts0afcKk_EI/AAAAAAAABTc/pB_hDQsv3dg/wlEmoticon-sadsmile2.png?imgmax=800" />.</p> <h5>Visual Studio Project Template</h5> <p>As Visual Studio and C# are my friends, I downloaded the DNN template from <a href="http://dotnetnuke.codeplex.com/releases/view/59419">dotnetnuke.codeplex.com</a> and added a new project to my VS 2010 solution:</p> <p><a href="http://lh6.ggpht.com/-b-ntB-o9j9o/Ts0afyi9QVI/AAAAAAAABTk/oR_Pxg_4K7s/s1600-h/image4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnmmoOmRfCjx2BnYtpfaa0-EqRS4BVG0UQqWJZUB8UKJMvm-Oxw7JdKJA_Lg6JoxmkNg7lTYHdz7Fg9OO19soT1LNx3l6ilj1iLVPeVdtecPwhqlDehN8rtydJadp3Cvj2l3ftr8s4Lqca/?imgmax=800" width="470" height="115" /></a></p> <p>which added the following structure:</p> <p><a href="http://lh4.ggpht.com/-XmCVA4PYuV4/Ts0ahf1h96I/AAAAAAAABT0/TcREQwIIHZg/s1600-h/image14.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHdKlVChLPWwhgtYq170iBLvbVNctgxYYmmhrcV0aLO0idQWOp1615Yx-a3GD2d9Ebcv2kbedqkwqsFzRnp1W6LN7z1kCDQZqh3HVVZnRvEVPtpdXPZI3TtYMCGBki6vLTY3mKm3rSCDA1/?imgmax=800" width="473" height="568" /></a></p> <p>changed to .NET framework to 4.0 and added my custom namespace</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaXTGD_wGN-YdCF_w5zWFdNelRc4HhiBjASJBSTTG-bjuHqWXCi_dD71Yd4hpF2QKoAPQAWIWuzfmjBdJ1eM0zME6zho0N3wzWXgRFwYNiJjNO7VMFraRKrnyJRhJ1ANzbd6TKlxEfs-Al/s1600-h/image19.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-Cj_db9X-lOM/Ts0alGK4HaI/AAAAAAAABUI/UMfv4ptXov4/image_thumb11.png?imgmax=800" width="894" height="224" /></a></p> <p>Performing a Release build</p> <p><a href="http://lh3.ggpht.com/-gS1dRpyML_E/Ts0alk-PgZI/AAAAAAAABUQ/2AAySw-J984/s1600-h/image22.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrtcHKtlgQYfh7Oi6Y0qwibR0ZCn0NvXDPCVrpB_Pb8pewf-iAwoMLebNJZK17UlYAO9ZuV-sML_iJKI7CBSqtxo6LT8Q8KIh4evd2jRC6zhZLruPIOGySwoB0rSdJj3zGZucVGMQk9C8z/?imgmax=800" width="190" height="92" /></a></p> <h5>Packaging</h5> <p>Right clicking the module project in the solution explorer and choosing <em>“Build Deployment Package”</em> creates the necessary CMS upload package BookingModule_00.00.01_Source.zip in the packages sub folder.</p> <p>The packing script error: </p> <p><em>Error    1    The target "Package" does not exist in the project.</em>    </p> <p>can probably be ignored. It indicates the build script references the solution file rather than the csproj project file.</p> <p><a href="http://lh6.ggpht.com/-2EDcdnT5AzU/Ts0amxctzOI/AAAAAAAABUg/bpCvahW0HVc/s1600-h/image39.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6RD5V2YAhUdPQn0y_Tq01UXzDP4TLPpy_mJP8DbX5bPKuXFjGU3XgQVUsVLytAyNSL2JX5v1aOz_KtAJXM8EsO0L_4yrtUEnKzUtFj0e7VyKe4tiUP5g6aIvV-B-Sbe0O9J-qodCQRvLs/?imgmax=800" width="444" height="147" /></a></p> <p>Note the packaging scripts are included in your DNN module project folder “BuildScripts”</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjKfJBrWNLxEdLD-UEL-Vwdj6cpD1ndddWWHbOfL7bG0iZr8MEh0-kMSHkoMO0C6OqewSRDeXwjxmuPIpzKbiTOLZJqBXl68us41PhBMCJg70Zr2ZbD-qnMduZM802IfLUl-Hr6VkYiZgY/s1600-h/image44.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTM7dlVi1De_gLn0svkWJaIRS4QgZ_LB3acirRswWMUIj0p0v43acBB3hNXqqvbBWLg-XqY2tmRABRUIrDSa0TEfaiCuLqayigoV59fnizsppKTKhA8taBTlY3sL_nUMeZYvUN3Zhv5q28/?imgmax=800" width="358" height="95" /></a></p> <p> </p> <h5><strong>Host Login</strong></h5> <p>When I created the DNN site within my hoster’s portal, I got asked to create two login account credentials:</p> <ol> <li>Administrator: create pages, add installed modules to pages, change skins and styles, etc. </li> <li>Host: same as the administrator, but with additional rights, one of these is <em>installing new modules</em> </li> </ol> <p>So you must log in with your host account</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG4waNiQk8fZY5gHoZvpZbzFv4fBn3h2gCX4f036FycO-ATT_OJvmlGVcVijhTwOqZM8Uhjev9C1qhqPikF9Yl1kktR2cSBBk_4VM5gyGvW8tSBT6-kOWN0PGBoYnA4AhKQeOacRTXjq1L/s1600-h/image25.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQajyRpRtuf2fiALhRd6vEfk4iTapnoKY5gS1Aiis_y-ZYmsPBDe_Ehrt7IYxqsA-zPuImZmqpAlE6StrCgw7P6x2333qTkOWgpEvepT5nGm259vv8F6Cteyi6918K7wVuGNytfAHsk69e/?imgmax=800" width="175" height="244" /></a></p> <p>to see the additional site menu items “Admin” and “Host”. Clicking host shows the Extensions icon:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuzWQ51GFdoTumky_TPw33qQokLtv9QjJW7GMEUk8yDwSk1jXX5sbmkxrpYkV1ULZ_bZk5k1CiyBosGt2SgebrZolHZviDe869IpWrM3kHxBnCn293IqQ96rYepSRrv0YCpS44mpdpZmok/s1600-h/image29.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgbkryGhhhAMSVZLZrS9cNwesys1yclm58cC3tRjg_fZRtlbHTmfs8nhR3S1EezTo5jtfnixXVqkoFQm3TxnQq9WghjcocxucHdBqjTh-ubIrN4gVObATlipCHAw4gK2hKb7Hu600ZIhTj/?imgmax=800" width="1115" height="212" /></a></p> <p>to see the DNN framework (version), Authentication System, Container, Library, Module, Provider, Skin, Skin Objects and in the bottom right pane the command to install a new module <em>Install Extension Wizard</em>:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimCW-j0XvhPr1hEMLJ5QezQCqcxENCgTiduXJ1YWwwRIxo5DTwATI8QvWWBL2EN75-gVizlO8IKRwQ9Nq6SPViIlb4Zy7BGe4SZYcezi_5kNXSKxUKCn2dfTDuungrs5xnacqNzAAp2kDG/s1600-h/image33.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh41S4dlNU7wFYTMusa_NvsMPmph-ED_E4LgGjmPWIMejrhwL9nVvLM1VhKXmjKLe98JDVDQMlxkA4_duorAOtpU9dbOYhmFrk4uSWWd_yMC32Mc_4W66Pnt6hi3zXMDExVYljY4pPnsrwy/?imgmax=800" width="754" height="95" /></a> </p> <p>selecting and uploading the previously built release package, next, booom!</p> <h5><em>Install Extension</em></h5> <p><em>Upload Results <br />If you have reached this page it is because the installer needs to gather some more information, before proceeding.</em></p> <p><em><strong>Error reading the zip package</strong> - see below</em></p> <p><em>StartJob <br />Reading Installation <strong>Manifest file</strong></em></p> <p><em>Info <br />Reading Package Manifest - Module - BookingModule</em></p> <p><em>Failure <br />Install aborted - The <strong>module being installed is not compatible with your host application</strong> version ( an upgrade is required )</em></p> <p>I spent some time googling for answers, found some useful <a href="http://www.dotnetnuke.com/Resources/Forums/forumid/136/postid/198561/scope/posts.aspx">hints</a>, saying the module is not compatible with my DNN version. But my problem remains: I cannot update my CMS with my hoster and I’ve got the latest Visual Studio template!? Hm. The solution was in the VS project DNN manifest file (project.dnn):</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: #a31515">dotnetnuke</span><span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Package</span>"<span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>"<span style="color: blue">5.0</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">  <</span><span style="color: #a31515">packages</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">    <</span><span style="color: #a31515">package</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">BookingModule</span>"<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Module</span>"<span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>"<span style="color: blue">00.00.01</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">      <…/></span></p> <p style="margin: 0px"><span style="color: blue"></span><span style="color: blue">      <</span><span style="color: #a31515">dependencies</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue">       <strong><</strong></span><strong><span style="color: #a31515">dependency</span><span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">CoreVersion</span>"<span style="color: blue">></span>06.00.00<span style="color: blue"></</span><span style="color: #a31515">dependency</span><span style="color: blue">></span></strong></p> <p style="margin: 0px"><span style="color: blue">      </</span><span style="color: #a31515">dependencies</span><span style="color: blue">></span></p> </div> <p>You need to delete the dependencies node, rebuild, repackage, upload again:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTp7lNBINSomTAXPa3FCl9bnYq1IUtUieIREF4E7Guts1b23h8cdozlPnNnnYg5VCUt5LY3wVXVr06MTfLGk0-YF0BB-KkhE5KpknyYAXP2IO2C0HkJJOmkvxoBHkP-IjUQZYXtJhv4Rhb/s1600-h/image51.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZCZXIZlVAJIobd0ROqWId63R7lBEethZXr9hsoHasEGW8TntW1PEXUiNHSRPrnE_NDQg-cVYbY_ylCZP8YeWbX7TxCf954myb8PG6Psg7oDWPNQWW68y8fMRRn89i3UTycMUtMiMOKRLH/?imgmax=800" width="779" height="421" /></a></p> <p>Yeah.</p> <p><a href="http://lh4.ggpht.com/-ULaSh1MRB5M/Ts0aygnoC0I/AAAAAAAABWA/efu-kwjn8Xk/s1600-h/image56.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguB61m1bS37HXnCMBGUaJp2IbatvmpbyiUjY6vOlaPF-tRiU4jKBRvKxQDBu1zTGQ1fnzuZaMevjruZUyrAD22Auv1946j-ENgq1_YF3TuC_M9Ws2AJNNnIaixg7acWUb5SVu4FJWmRjCz/?imgmax=800" width="780" height="219" /></a></p> <p>You can now add it to you page / pane as host –> edit mode –> common task –> add module</p> <p><a href="http://lh5.ggpht.com/-1nPdgR0ZhsM/Ts0a0dDiPrI/AAAAAAAABWQ/khbHJXuiO50/s1600-h/image60.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-ulnR4cHZKik/Ts0a1bYMa9I/AAAAAAAABWc/9OWJNBQRUNo/image_thumb34.png?imgmax=800" width="716" height="215" /></a></p> <p>and when the module has the same rights as the page, then you can see it. There’s a context menu added</p> <p><a href="http://lh6.ggpht.com/-SDKOT-F7xxg/Ts0a2fZbQ2I/AAAAAAAABWk/qumYKlQ3hrg/s1600-h/image63.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwpnEA2fasvkaSkFqWfcWaDMpfLwW6Klkj6qmkOBfQCi-IRpNr6VDLcx3SHwLgDofCNmGmg1Moop0qZny54F8sugegQYg-PtOXhuqa7B_hztHPRisvMSoLE4pEvyvVQc7VdbdyYitdJtup/?imgmax=800" width="178" height="173" /></a></p> <p>that let’s you switch to an “Edit Module” view or “Settings” view. Do you remember the three .ascx asp.net user controls in the above module project?</p> <p>I hope this blog post gave you some overview of DotNetNuke module developments to get started with, including some pitfalls (I have fallen into).</p> <p>Next time, I plan to show you the development of the web stuff, including the database model, data access, UI.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com3tag:blogger.com,1999:blog-8040115472186352073.post-18417922506809860342011-11-23T17:04:00.001+01:002011-11-23T17:04:13.193+01:00Fun Project: DotNetNuke – Failing with WebMatrix/ Orchard<p>No, I’ve not been in jail – but I’ve been very busy in a project recently and could not share my .NET insights with you. So I start again with a fun project, in a field I never work or accept customer mandates so far: web development, CMS, homepages.</p> <p>It all started in an evening effort to create a web site for my wife’s new hobby (ehm, business): wellness, wellbeing, massage. </p> <h4><strong>Microsoft WebMatrix / Orchard</strong></h4> <p>I started with the latest and smallest .NET (what else) open source content management system (CMS) out there: <a href="http://orchard.codeplex.com/">Microsoft Orchard</a> using <a href="http://www.microsoft.com/web/webmatrix/">WebMatrix</a>. Learned the tool basics, got into the CMS, created some content, browsed through some free skins, modified CSS (with blood and sweat), had fun and insights …</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2jJ6gLTlSCpkMwyuv2iS2CT-ddUfPjz5oTtmgPeH4UBrpmp1-VffQtw0mZO3eiWuLauKZUONNXWlhtt1ne_aW0_miJpKqDD4XYroKe7uX2SslyyAwNL0OP6Vw1C85yxJtLHFecIOFB-Is/s1600-h/image4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMygKgz4EbRSp7XsNA2kxVSJe0uBUSzi89kHl2LKzy4TogOzpjEB6BmPYfeMaEvzs6x3VtW8d8hlppN9zf_VvVRYShnSWE7-63fRc38T8S_C_7CVAITSp16x0dcZ0sXOW6QsKFaadJiVKf/?imgmax=800" width="1196" height="745" /></a></p> <p>… but failed due to hosting restrictions from my shared web hoster (Microsoft Orchard 1.2.41 / ASP.NET 4.0 / SqlCompact 4) with a security exception (<em>Exception Details: System.Security.SecurityException: That assembly does not allow partially trusted callers</em>.). As I did not want to update my subscription to a more expensive one, I went back to “field 1” to start all over again.</p> <p>Learning: Orchard needs full trust shared hosting.</p> <h4><strong>DotNetNuke</strong></h4> <p>But my hoster supports <a href="http://www.dotnetnuke.com/">DotNetNuke</a> (DNN) 05.06 Community Edition! Another new experience for me. </p> <p><strong>Installation</strong></p> <p>It took a couple of web forms filling (SQL connection, accounts, etc.) and 10 minutes waiting time for the installation on <a href="http://www.webland.ch/">my hoster</a>’s management portal. A no brainer.</p> <p><strong>Customization</strong></p> <p>After log-in to the deployed CMS you can start adding pages, adding modules to pages, adding content to modules. </p> <p><img src="http://kimmtech.all-around-us.com/wp-content/uploads/2008/10/addexisitngmodule.gif" width="500" height="105" /></p> <p>Modules are added to panes of a page. Panes are typically the following areas:</p> <p><a href="http://www.developerfusion.com/article/84462/dotnetnuke-8211-the-easy-way-to-an-aspnet-website/"><img src="http://www.developerfusion.com/pix/articleimages/jul08/dnn1.jpg" width="395" height="354" /></a></p> <p>Blood and sweat again: there just the so called “MinimalExtropy” skin to start with – or get a bunch of commercial skins or create your own using commercial tools. But I wanted to migrate my Orchard CSS to <strong>MinimalExtropy</strong>, which took me another (long) evening.</p> <p><span style="color: blue">@import</span> url("css/menu.css");</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: #006400">/* CSS Document */</span></p> <p style="margin: 0px"><span style="color: maroon">#Body</span> {<span style="color: red">background</span>: <span style="color: blue">url(images/body_bg.png)</span> <span style="color: blue">#c6e29f</span> <span style="color: blue">fixed</span> <span style="color: blue">no-repeat</span> <span style="color: blue">center</span> <span style="color: blue">bottom</span>; <span style="color: red">height</span>:<span style="color: blue">100%</span>; <span style="color: red">margin</span>:<span style="color: blue">0</span>; <span style="color: red">padding</span>:<span style="color: blue">0</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: #006400">/* ControlPanel style */</span></p> <p style="margin: 0px"><span style="color: maroon">.ControlPanel</span>{<span style="color: red">background</span>:<span style="color: blue">transparent</span> <span style="color: blue">url(images/cpanel_center.png)</span> <span style="color: blue">repeat-x</span> <span style="color: blue">bottom</span> <span style="color: blue">left</span>; <span style="color: red">border</span>:<span style="color: blue">none</span>;<span style="color: red">padding-bottom</span>:<span style="color: blue">10px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">.cpanel_left</span> {<span style="color: red">background</span>: <span style="color: blue">url(images/cpanel_left.png)</span> <span style="color: blue">no-repeat</span> <span style="color: blue">bottom</span> <span style="color: blue">left</span>;<span style="color: red">padding-left</span>:<span style="color: blue">21px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">.cpanel_right</span> {<span style="color: red">background</span>: <span style="color: blue">url(images/cpanel_right.png)</span> <span style="color: blue">no-repeat</span> <span style="color: blue">bottom</span> <span style="color: blue">right</span>;<span style="color: red">padding-right</span>:<span style="color: blue">33px</span>;}</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: #006400">/*-------- Default Style --------*/</span></p> <p style="margin: 0px"><span style="color: maroon">body</span>,<span style="color: maroon">th</span>,<span style="color: maroon">td</span>,<span style="color: maroon">table</span>,<span style="color: maroon">h1</span>,<span style="color: maroon">h2</span>,<span style="color: maroon">h3</span>,<span style="color: maroon">h4</span>,<span style="color: maroon">h5</span>,<span style="color: maroon">h6</span>,<span style="color: maroon">.Normal</span>,<span style="color: maroon">.NormalDisabled</span>,<span style="color: maroon">.Head</span>,<span style="color: maroon">.SubHead</span>,<span style="color: maroon">.SubSubHead</span>, <span style="color: maroon">a:link</span>, <span style="color: maroon">a:visited</span>, <span style="color: maroon">a:hover</span>, <span style="color: maroon">input</span>, <span style="color: maroon">.CommandButton</span>{<span style="color: red">color</span>:<span style="color: blue">#2E3D47</span>; <span style="color: red">font-family</span>:<span style="color: blue">Verdana,</span> <span style="color: blue">Arial,</span> <span style="color: blue">Helvetica,</span> <span style="color: blue">sans-serif</span>;}</p> <p style="margin: 0px"><span style="color: maroon">body</span>,<span style="color: maroon">th</span>,<span style="color: maroon">td</span>,<span style="color: maroon">table</span>,<span style="color: maroon">.Normal</span>,<span style="color: maroon">.NormalDisabled</span>,<span style="color: maroon">.Head</span>,<span style="color: maroon">.SubHead</span>,<span style="color: maroon">.SubSubHead</span>, <span style="color: maroon">a:link</span>, <span style="color: maroon">a:visited</span>, <span style="color: maroon">a:hover</span>{<span style="color: red">font-size</span>:<span style="color: blue">12px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h1</span>, <span style="color: maroon">h2</span>, <span style="color: maroon">h3</span>, <span style="color: maroon">h4</span>, <span style="color: maroon">h5</span>, <span style="color: maroon">h6</span>, <span style="color: maroon">h2</span> <span style="color: maroon">input</span>{<span style="color: red">color</span>:<span style="color: blue">#375162</span>;<span style="color: red">font-weight</span>:<span style="color: blue">bold</span>;<span style="color: red">margin</span>:<span style="color: blue">1ex</span> <span style="color: blue">0</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h1</span>{<span style="color: red">font-size</span>:<span style="color: blue">18px</span>;<span style="color: red">margin</span>:<span style="color: blue">10px</span> <span style="color: blue">0</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h2</span>, <span style="color: maroon">h2</span> <span style="color: maroon">input</span>{<span style="color: red">font-size</span>:<span style="color: blue">14px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h3</span>{<span style="color: red">font-size</span>:<span style="color: blue">13px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h4</span>{<span style="color: red">font-size</span>:<span style="color: blue">12px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h5</span>{<span style="color: red">font-size</span>:<span style="color: blue">11px</span>;}</p> <p style="margin: 0px"><span style="color: maroon">h6</span>{<span style="color: red">font-size</span>:<span style="color: blue">10px</span>;}</p> </div> <p>… and the like.</p> <p>There are a couple of pre-installed <strong>modules</strong> for DNN and an ecosystem of free and commercial modules out there. A module is a kind of a web part like blogging, picture gallery, etc.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbYFLYDP0-1ewUF2-UWpJlIzuU42wVC7c_roNKb1-1KBmiB2neMadpeYr-kBhML9aPcHJf44RSUlAb_JSZtGq7UZZ1sWJ7Orwa58gG4jaINIhQZU9vy-P0B2FQIL6_3h0Dxj7HrXCxeIc/s1600-h/image9.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM2uvylYWHgn_zW6983JcrPZtUi-sefd2hi3rFdwDgWU08O0EyFSlYrxW0OPEjQnaOQatIxVXWf_kSXLTchr-ZBYFg8F4cRRb3nyxbDOQUI1pRAlXGLpRzp3UeQqblUOJH4yC3cljP1oV_/?imgmax=800" width="250" height="401" /></a></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1tag:blogger.com,1999:blog-8040115472186352073.post-24477397626194585092011-07-19T15:36:00.001+01:002011-07-19T15:36:41.865+01:00Windows Mobile Device Center crashing with "Services is not a valid partnership ID"<p>Almost drove me crazy, this error on my Windows 7 64bit Ultimate, connecting Outlook 2010 with my Windows Mobile 6.5 HTC Touch Diamond 2. From one day to the other synchronization did not work any more because the WMDC process crashed. Un- and re-install did not help.</p> <p>The solution was to delete all sub keys (partnerships) from the following registry node:</p> <p>HKEY_CURRENT_USER\Software\Microsoft\Windows CE Services\Partners</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-21766931888439404012010-11-02T09:50:00.001+01:002010-11-02T09:50:40.282+01:00ESE Software Engineering Conference in Zürich – Call for Papers<p>The international Software Engineering Conference ESE Conference 2011 (12.-14. April) opens the <a href="http://www.eseconf.com/2011/Konferenz/CallforpaperInfos.aspx">Call for Papers</a>.</p> <p><a href="http://www.eseconf.com"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_8SuFzywowiM/TM_Q38pW1zI/AAAAAAAABE4/LNFHb6gNzsE/image%5B3%5D.png?imgmax=800" width="244" height="186" /></a></p> <p>So, if you are an expert in a technical software topic you can submit your talk until 12. December 2010.</p> <p>The conference allows the discussion and exchange of experts and participants. </p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-14649284415993794382010-08-11T10:54:00.001+01:002010-08-11T10:54:25.350+01:00Silverlight 3 Trap : OneWayToSource<p>Silverlight is missing some details you may be using in WPF. One of them is the missing data binding mode OneWayToSource. Another one is the missing SelectionChanged command of a ComboBox. Both created a funny behavior in my current project.</p> <p><a href="http://derstandard.at/1271378039203/Kreisrundes-Loch-in-Guatemalas-Hauptstadt-aufgeklafft?sap=2&_slideNumber=1&_seite=7"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbqciSxyvkesrJsPPujRIQndG3NSh5shTGPrQKnIwt50kBHw_e9XXScJ0TmwUfD9-Vc5zvUx0qPU4-FWacozud_AIvZbIajKt9cdIPz15U7XYFHM_pBvp3M4W2RdN05cMwIs8y5kexM-XJ/?imgmax=800" width="604" height="413" /></a></p> <p>I have a ViewModel property</p> <div style="font-family: courier new; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">string</span> Selected</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">get</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">return</span> <span style="color: blue">this</span>._selected;</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">    <span style="color: blue">set</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">this</span>._selected = <span style="color: blue">value</span>;</p> <p style="margin: 0px">        <span style="color: blue">this</span>.RaisePropertyChanged(<span style="color: #a31515">"Selected"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> </div> <p>and two ComboBox TwoWay (OneWayToSource does not exist) binding on it with SelectedItem</p> <p><ComboBox Name="c1" mycmd:SelectionChangedCommand.Command="{Binding C1SelectionChangedCommand}" ItemsSource="{Binding Selections}" SelectedItem="{Binding Selected, Mode=TwoWay}" /> <br /></p> <p><ComboBox Name="c2" mycmd:SelectionChangedCommand.Command="{Binding C2SelectionChangedCommand}" ItemsSource="{Binding Selections}" SelectedItem="{Binding Selected, Mode=TwoWay}" /></p> <p>The funny thing was, that when I made a selection on combo box c1 the command handler of my c2 fired (too) – due to the <span style="color: blue">this</span>.RaisePropertyChanged(<span style="color: #a31515">"Selected"</span>) above:</p> <p>- c1 copies the SelectedItem from the target to the source</p> <p>- the source property raises the property changed event and</p> <p>- copies the Selected property value to the other c2 target</p> <p>- c2 fires the SelectionChanged command</p> <p>Et voilà, your in the Guatemala City trap…it would be better to have more fine-grained data binding control with OneWayToSource in the first place.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-47822779373588014872010-07-02T11:27:00.001+01:002010-07-02T11:27:08.822+01:00Silverlight 3 Debugging in Visual Studio 2008: Breakpoint not hit<p>Today I hit the problem, that I could not any longer debug Silverlight client applications (it worked yesterday).</p> <p>A lot of solutions have been posted out there, which did not help for me. The most common cause with other people was that the web project had the Silverlight Debugger option unticked. So enable it again.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhePT8eIIPdBZ4RQOmRkBkDCl5i_3wr17uOUYOnpGS_BaBBlZjN3YU1nn37TmdGklDCGFh1TIhRMI6m8lBDNe9UqW7Lbx07YCSxOibx_8RVf_AkF7r2JvZS2_zUmsR3DWIXol3D2iX0xkOc/s1600-h/image%5B7%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_8SuFzywowiM/TC2-9e4J29I/AAAAAAAABDM/ZPg9P0ACMfI/image_thumb%5B3%5D.png?imgmax=800" width="664" height="84" /></a> </p> <p>Going back to the source code from yesterday and doing it again, showed me the following screen (“Do you want to enable Silverlight debugging for this project? …” – event when this tick was set!</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqrxobvp5JocaASFvGU_6Hp4ISwYO6RIw0SHBtWatgkaAq0DNMMDEmyhZYJlxZLIsETleGHHRRkvHq6Ivj4_H2UbyAIuEMqx0_iFOD5-0m74D6Y615_dY1h0b6WuD0WpqV80vgCkWj1hxv/s1600-h/image%5B3%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyifDTtj-I0wkJELs_dS3KwO8dwrpV2n0HzN9dukY6GDEgZ_acTlZfJ5blSSxVd4WgrvbMQUz-OzXxm0MmuWPjLU6MuBtn6yQOB0lUzgdA_Etm6PS02LWrt7gqly4tf5uh3wHGW-TIky1a/?imgmax=800" width="582" height="279" /></a> </p> <p>After some time struggling around I found out, that I had to set the “Set as Start Page” again on my .htm page. I looks like this fixes something (btw, even when the start project was set correctly before!).</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-62554860934468422452010-05-21T15:55:00.001+01:002010-05-21T15:55:01.768+01:00Entity Framework 4 : Cascaded Delete in Parent-Child Relationship?<p>Extending the previous post, let’s look at cascaded delete</p> <p><a href="http://lh3.ggpht.com/_8SuFzywowiM/S_aesY7T9KI/AAAAAAAABBA/YJSGPRGGeck/s1600-h/image%5B21%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ719pCsxRfsJF-EAk-p9Ez3c-1tE3cdKsLfZ8_oG3IDSTGp3xV7lakeq1ZzbdGqLdzhuicnK97CRcxBxYZ3r88NTdMpBu4HMcyKCiQ53IcW8F7MQnZUlNeaYoSYa514FaXSWr5bgeuKSU/?imgmax=800" width="525" height="290" /></a> </p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px">[<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">[<span style="color: #2b91af">ExpectedException</span>(<span style="color: blue">typeof</span>(System.Data.<span style="color: #2b91af">ObjectNotFoundException</span>))]</p> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">void</span> DeleteParentEntity_WithOneToOneChildEntityRelationshipConstraint_ChildIsAutomaticallyDeleted()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: green">// save parent and child (1:1)</span></p> <p style="margin: 0px">    <span style="color: #2b91af">FinanceMinister</span> financeMinister = <span style="color: blue">new</span> <span style="color: #2b91af">FinanceMinister</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        Name = <span style="color: #a31515">"Giulio Tremonti"</span>,</p> <p style="margin: 0px">        Email = <span style="color: #a31515">"gt@finanze.it"</span></p> <p style="margin: 0px">    };</p> <p style="margin: 0px">    <span style="color: #2b91af">Country</span> country = <span style="color: blue">new</span> <span style="color: #2b91af">Country</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        Name = <span style="color: #a31515">"Italy"</span>,</p> <p style="margin: 0px">        GDP = 2118.264M, <span style="color: green">// billions ? </span></p> <p style="margin: 0px">        ForeignDebt = 0M,</p> <p style="margin: 0px">        FinanceMinister = financeMinister</p> <p style="margin: 0px">    };</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Add(country);</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px">    <span style="color: blue">int</span> financeMinisterId = financeMinister.Id;</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// check if that was done right</span></p> <p style="margin: 0px">    <span style="color: #2b91af">Country</span> reloadedCountry = <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">Country</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">Country</span> { Id = country.Id });</p> <p style="margin: 0px">    <span style="color: #2b91af">Assert</span>.AreEqual<<span style="color: blue">string</span>>(country.FinanceMinister.Name, reloadedCountry.FinanceMinister.Name);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// delete Country and check that treasurer is also gone</span></p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Delete(country);</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">FinanceMinister</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">FinanceMinister</span> { Id = financeMinisterId });</p> <p style="margin: 0px">}</p> </div> <p>throws</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6LIGZI6UTkCT0_iZfb4qTfsEvgtb-U9ib1hI9VZe207nmf6njDNyqEo5eyOkQS_9WMmJFuqRYTjZiG0Wnr7G5evoS-ivk4qFm44OCUXkfDLDioxNw-zvcnrT_l6EuJLUvdQnacTX4EDt2/s1600-h/image%5B22%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfbMBosf2udESpbBKhfZS_qL196nODj1PBdHPnxJBVUtajo-cE9AYa-txe3PHw4Ne0e6RquT9fS7kHpKzylXolivS6LG5vEPbMdrwnPNB0LhZtFY2Ub_H02exxll2Iy_Pz7eQJJBvqc7ag/?imgmax=800" width="496" height="347" /></a> </p> <p>Now setting the relationship to “cascade”</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfM1AtvFCayHE8RH-FupYu2FWerAaCfLcpbI02Rf5LUJD_QoOUt9SOYjTdHcA5zclwpre1H3NfJHGbbeLsVrZ8vQvaHIRFsB3RWhdWaDUf7sbGuzenSD0U8XXqLQcajD_m9XYAeJPR_-JT/s1600-h/image%5B7%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_8SuFzywowiM/S_aevPoinoI/AAAAAAAABBU/bgMpWI_FivI/image_thumb%5B3%5D.png?imgmax=800" width="491" height="460" /></a> </p> <p>Runs OK, deleting the country and the corresponding finance minister in one go:</p> <p><a href="http://lh3.ggpht.com/_8SuFzywowiM/S_aev1-NuiI/AAAAAAAABBY/tXv17bmv_ZQ/s1600-h/image%5B12%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir973W-H5JGUiydHBIt6Ywi3J07YR7mCpicFUK11IIbmiylq1Z0-b10LPqhzDdOGTLGh1R9YJ09SBUtF4_Ey9MZyktOii1yDI4SvSyyY45UtZ-CScWbiWoa0yx1t-tlQdiYigfgoQ26Wnf/?imgmax=800" width="620" height="60" /></a> </p> <p><a href="http://lh3.ggpht.com/_8SuFzywowiM/S_aew7Y5KvI/AAAAAAAABBg/AI87I6_UTbc/s1600-h/image%5B17%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_8SuFzywowiM/S_aexFF45BI/AAAAAAAABBk/0-rOeW_JlnU/image_thumb%5B9%5D.png?imgmax=800" width="420" height="52" /></a></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-72913290204855114462010-05-21T15:00:00.001+01:002010-05-21T15:00:10.506+01:00Entity Framework 4 : Delete child from ParentChild Relationship – throws or what?<p>[topic from a discussion; addressing a colleague]</p> <p>Imagine the very common situation where you have a parent-child relationship like the following, and you want to delete the child (Currency; or better just remove the relation by setting the parent’s child navigation property to null):</p> <p><a href="http://lh5.ggpht.com/_8SuFzywowiM/S_aRy7FHvlI/AAAAAAAABAA/tj113FDUA3E/s1600-h/image9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_8SuFzywowiM/S_aRzVl9BLI/AAAAAAAABAE/541UZpbeKTY/image_thumb5.png?imgmax=800" width="309" height="692" /></a> </p> <p>Having code (show in an intergration test) like this</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px">[<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">void</span> RemoveChildEntityNavigationFromParentEntityProperty_WithManyToOneConstraint_Throws()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: green">// save parent and child with a 1:* relationship constraint</span></p> <p style="margin: 0px">    <span style="color: blue">int</span> dbGeneratedCityId = -1;</p> <p style="margin: 0px">    <span style="color: #2b91af">Currency</span> chf = <span style="color: blue">new</span> <span style="color: #2b91af">Currency</span> { Symbol = <span style="color: #a31515">"CHF"</span>, Name = <span style="color: #a31515">"Schweizer Franken"</span> };</p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> city = <span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Code = <span style="color: #a31515">"ZRH"</span>, Name = <span style="color: #a31515">"Zürich"</span>, Currency = chf };</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Add(city);</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px">    dbGeneratedCityId = city.Id;</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// get the parent again from the database and get rid of the child</span></p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> reloadedCity = <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">City</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Id = dbGeneratedCityId });</p> <p style="margin: 0px">    <span style="color: #2b91af">Assert</span>.IsNotNull(reloadedCity.Currency);</p> <p style="margin: 0px">    reloadedCity.Currency = <span style="color: blue">null</span>;</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// assert that the child was properly deleted</span></p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> reloadedUpdatedCity = <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">City</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Id = dbGeneratedCityId });</p> <p style="margin: 0px">    <span style="color: #2b91af">Assert</span>.IsNull(reloadedUpdatedCity.Currency);</p> <p style="margin: 0px">}</p> <p style="margin: 0px"> </p> </div> <p>Using SQLProfiler shows that the following queries are emitted for the first code block</p> <p><a href="http://lh5.ggpht.com/_8SuFzywowiM/S_aRzj7EIYI/AAAAAAAABAI/X65jZyjVcYY/s1600-h/image22.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV6Ap8iH5wny0zOt9lDPkixnSx7DQhqHJ-ylWmX2iSTK70w4E1-CXPN-UcfC4-y-e6QceEKveYsL1I7uOjcQ88i1KC5d1d2dzSA1VXpDRKmjlWXqimoWMPk0ckj8JBZxqpehJQ1Tl9bhj5/?imgmax=800" width="1004" height="109" /></a>  <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk9xpccMR2pLho9bg3cAK2OPC0jLOJbOM5hIXAqGWyuYZMR2Ce8sRNdl8A0YQMD4IN7gVOg8_rS9SdADyxm1bo3VCSF0f4Ruv0Heb0EXddc_qc51U99F3US3LHEy7jnCCTYqFcdM2e4wPb/s1600-h/image26.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_8SuFzywowiM/S_aR1DhBucI/AAAAAAAABAU/5n2YPpQ7AX0/image_thumb14.png?imgmax=800" width="1027" height="111" /></a> </p> <p>Calling Save() in the second block throws the following exception:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSUgE7uPmiyt0IEYTiRmyUdHA8LiqHdxVHtQU112KnqONllB262LrOTX4e48pIYsbkfY0qE3GqgG-eoTKQjqQ9yj_U9hyvHOcgv_3TAeDQNpKt5NKdF-IZqTxGLouPLSlxvhN6IGrdqfuw/s1600-h/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_8SuFzywowiM/S_aR2GpzD5I/AAAAAAAABAc/ziefF0icWwE/image_thumb1.png?imgmax=800" width="622" height="433" /></a></p> <p>Aha, sure, this is due to the “1” in the “1:*” relationship – no cities without a default local currency (not even south european EU contries … sorry, no, not funny).</p> <p>Let’s change this to “0..1”</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_ZWZLoTXFF5dNMqfo9BoYxeWdpbfpcQ-MbjqACoglGk33-ulx6ZF54hnOxGBR9392BRSDMIK5OL4sMRrZKvksulYlJjkOupY-rDCaMjXbadm3zkVRv9mA-pS_yUei4OkJ9h6vThKHTc5s/s1600-h/image31.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAMoiqpxSESbjDt49Ow082BhsehYOkTOIQOU4UoDUeN43G0-J425sNibfpEtZP5QYZ23OvW3kKUGmNiOleJZUNcVIfFPHbsPoMF1_JnmiAFi1B4iyf-jXbTdf7Bgp0TgAoXpIicXLAaNZJ/?imgmax=800" width="268" height="678" /></a> </p> <p>Running the same test again shows “green”</p> <p><a href="http://lh3.ggpht.com/_8SuFzywowiM/S_aR4eAnoqI/AAAAAAAABAo/luHr3du5nsk/s1600-h/image%5B6%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2jC1Rpx8Yft1anvCufm1sp5ZC9y0VbXlqN9C6NeQ8xcFYR9oo6hoW88Ipe0E78YO6xIKQwyJ6eCwb85cWfW6OUp47i25NdV3TB9BVZeJpc8zmDcPbtkeGtnvJo2UJvUmrr9x48HM8iqVh/?imgmax=800" width="718" height="121" /></a> </p> <p>emitting the Update statement.</p> <p><a href="http://lh4.ggpht.com/_8SuFzywowiM/S_aR5EZZxSI/AAAAAAAABAw/837DGdHrYeA/s1600-h/image35.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjuSKzXGN2RqdAGyKxlw_zec_AG8hP_S5SnQYiwWp5AFbTNOQabdE4AuOe2qRPAubmnsh-RJIXeQGqHTAyxhiQCUCHn0VyJdKbR6SRKaqk7AyehwF9Nr1og491GNj9QGnsUR4bv6n1znhc/?imgmax=800" width="493" height="97" /></a> </p> <p>Please note:</p> <ul> <li>depending on the constraint, there may be no Delete(chf) necessary </li> <li>relationship constraints violations throw exceptions </li> <li>simply set the parent’s child navigation property to null </li> <li>loosening the constraint to “0..1” leaves the child entity in the database </li> </ul> <p>In comparison we can do the following (with “0..1” relationship):</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px">[<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">void</span> DeleteChildEntityFromParent_WithManyToOneConstraint_Throws()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: green">// save parent and child with a 0..1:* relationship constraint</span></p> <p style="margin: 0px">    <span style="color: blue">int</span> dbGeneratedCityId = -1;</p> <p style="margin: 0px">    <span style="color: #2b91af">Currency</span> euro = <span style="color: blue">new</span> <span style="color: #2b91af">Currency</span> { Symbol = <span style="color: #a31515">"EUR"</span>, Name = <span style="color: #a31515">"Euro"</span> };</p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> city = <span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Code = <span style="color: #a31515">"ATH"</span>, Name = <span style="color: #a31515">"Athens"</span>, Currency = euro };</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Add(city);</p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px">    dbGeneratedCityId = city.Id;</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// get the parent again from the database and get rid of the child</span></p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> reloadedCity = <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">City</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Id = dbGeneratedCityId });</p> <p style="margin: 0px">    <span style="color: #2b91af">Assert</span>.IsNotNull(reloadedCity.Currency);</p> <p style="margin: 0px">   <strong> <span style="color: blue">this</span>.target.Delete(reloadedCity.Currency);  <span style="color: green">// Athens and no more Euro</span></strong></p> <p style="margin: 0px">    <span style="color: blue">this</span>.target.Save();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: green">// assert that the child was properly deleted</span></p> <p style="margin: 0px">    <span style="color: #2b91af">City</span> reloadedUpdatedCity = <span style="color: blue">this</span>.target.GetById<<span style="color: #2b91af">City</span>>(<span style="color: blue">new</span> <span style="color: #2b91af">City</span> { Id = dbGeneratedCityId });</p> <p style="margin: 0px">    <span style="color: #2b91af">Assert</span>.IsNull(reloadedUpdatedCity.Currency);</p> <p style="margin: 0px">}</p> </div> <p>and get</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnd6Kaf7K2wfw7gwphDMuCo2B6GRVuUyrlAp-e2dR03DSLFnA5BNng_yU63H4BeL99fRz9ScxcTWI1w2yw3pQ5gifwqeDNkiG78gUCk_hH3PJgC6x0tDUq8xPmxYbn-zup4qvk2TkPqj6C/s1600-h/image%5B5%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_8SuFzywowiM/S_aR6VPHbzI/AAAAAAAABA8/36d-oecwxF4/image_thumb%5B2%5D.png?imgmax=800" width="616" height="122" /></a></p> <p>Setting the constraint back to “1:*” throws too:</p> <p>DeleteChildEntityFromParent_WithManyToOneConstraint_Throws threw exception: <br />System.Data.UpdateException: A relationship from the 'CityCurrency' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'City' must also in the 'Deleted' state.</p> <p>Guessing the same behavior for NHibernate. Can anybody confirm this?</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1tag:blogger.com,1999:blog-8040115472186352073.post-78767108385773234942010-05-17T13:15:00.001+01:002010-05-17T13:15:12.420+01:00Public Interfaces of WCF in Silverlight 4<p>Microsoft seems to have added some more interfaces to System.ServiceModel in Silverlight 4 (came across a blog post from <a href="http://www.leastprivilege.com/AMoreElegantWayOfEmbeddingASOAPSecurityHeaderInSilverlight4.aspx">Dominick Baier</a>). These can be used as WCF extensibility points.</p> <p>Here is a list of all the public interfaces I found reflecting the assembly:</p> <p>System.ServiceModel.IDefaultCommunicationTimeouts <br />System.ServiceModel.ICommunicationObject <br />System.ServiceModel.Channels.IChannel <br />System.ServiceModel.Channels.IChannelFactory <br />System.ServiceModel.Channels.IChannelFactory`1[TChannel] <br />System.ServiceModel.Channels.IInputChannel <br />System.ServiceModel.Channels.IOutputChannel <br />System.ServiceModel.Channels.IDuplexChannel <br />System.ServiceModel.Channels.ISession <br />System.ServiceModel.Channels.IInputSession <br />System.ServiceModel.Channels.IOutputSession <br />System.ServiceModel.Channels.IDuplexSession <br />System.ServiceModel.Channels.ISessionChannel`1[TSession] <br />System.ServiceModel.Channels.IDuplexSessionChannel <br />System.ServiceModel.Channels.IInputSessionChannel <br />System.ServiceModel.Channels.IOutputSessionChannel <br />System.ServiceModel.Channels.IRequestChannel <br />System.ServiceModel.Channels.IRequestSessionChannel <br />System.ServiceModel.Channels.IHttpCookieContainerManager <br /><strong>System.ServiceModel.Description.IEndpointBehavior <br /></strong>System.ServiceModel.IExtensionCollection`1[T] <br /><strong>System.ServiceModel.Description.IContractBehavior <br /></strong>System.ServiceModel.IExtensibleObject`1[T] <br />System.ServiceModel.IExtension`1[T] <br /><strong>System.ServiceModel.Description.IOperationBehavior</strong> <br />System.ServiceModel.IContextChannel <br /><strong>System.ServiceModel.IClientChannel</strong> <br /><strong>System.ServiceModel.Dispatcher.IClientOperationSelector <br />System.ServiceModel.Dispatcher.IParameterInspector <br />System.ServiceModel.Dispatcher.IClientMessageFormatter</strong> <br /><strong>System.ServiceModel.Dispatcher.IClientMessageInspector <br />System.ServiceModel.Dispatcher.IDispatchMessageFormatter</strong> <br />System.ServiceModel.Channels.IMessageProperty</p> <p>generated (without Reflector) using</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: #2b91af">IList</span><<span style="color: #2b91af">Type</span>> types = <span style="color: blue">typeof</span>(<span style="color: #2b91af">IClientMessageInspector</span>).Assembly</p> <p style="margin: 0px">    .GetTypes()</p> <p style="margin: 0px">    .Where(t => t.IsInterface && t.IsPublic)</p> <p style="margin: 0px">    .ToList();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">I have not tried them, but the bold ones are interesting for WCF extensibility.</p> <p style="margin: 0px"></p> </div> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-80133349850701006542010-05-03T19:45:00.001+01:002010-05-03T19:45:38.677+01:00Exclude from Code Coverage (Visual Studio 2010)<div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"> </p> </div> <p>I was working on a library that adds some customer specific functionality to web services and WCF. I decided to have it very highly covered by unit tests. Unfortunately there is some static functionality in WCF (OperationContext) that is hard to be used in unit tests (it throws). So I wrapped this code behind a custom C# interface with a production implementation calling OperationContext and an (independant and fast) unit test implementation/mock. The small and simple production implementation had some negative impact on Visual Studio (instruction) code coverage (being below 100%). I figured out how to exclude this piece of code.</p> <p>The way to do this is to add the [<span style="color: #2b91af">ExcludeFromCodeCoverage</span>] attribute to class, property, method or event:</p> <div style="font-family: consolas; background: white; color: black; font-size: 10pt"> <p style="margin: 0px"><span style="color: blue">namespace</span> MyTrials</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: green">// [ExcludeFromCodeCoverage]</span></p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">NotCoveredClass</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        [<span style="color: #2b91af">ExcludeFromCodeCoverage</span>]</p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">string</span> NotCoveredProperty { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">string</span> CoveredProperty { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        [<span style="color: #2b91af">ExcludeFromCodeCoverage</span>]</p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: #2b91af">EventHandler</span><<span style="color: #2b91af">EventArgs</span>> OnNotCoveredEvent { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: #2b91af">EventHandler</span><<span style="color: #2b91af">EventArgs</span>> OnCoveredEvent { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        [<span style="color: #2b91af">ExcludeFromCodeCoverage</span>]</p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> NotCoveredMethod()</p> <p style="margin: 0px">        {</p> <p style="margin: 0px">        }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> CoveredMethod()</p> <p style="margin: 0px">        {</p> <p style="margin: 0px">        }</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">CoveredClass</span></p> <p style="margin: 0px">    {</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> </div> <p>Write some more useful unit tests than I did for this post:</p> <p style="margin: 0px">[<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">void</span> CodeCoverage_ExcludeWith_ExcludeFromCodeCoverage_FromClassMethodPropertyEvent()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: #2b91af">CoveredClass</span> target = <span style="color: blue">new</span> <span style="color: #2b91af">CoveredClass</span>();</p> <p style="margin: 0px">    <span style="color: #2b91af">NotCoveredClass</span> target2 = <span style="color: blue">new</span> <span style="color: #2b91af">NotCoveredClass</span>();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    target2.CoveredMethod();</p> <p style="margin: 0px">}</p> <p style="margin: 0px"> </p> <p style="margin: 0px">to have it excluded:</p> <p><a href="http://lh5.ggpht.com/_8SuFzywowiM/S98ZzT1sqYI/AAAAAAAAA_4/Ygbfv1VAdLk/s1600-h/image%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjul7Q1qV6ETBUyEdNqtIa7whL_xnl8l8DQ9anM9RZhe-yyxnZwGwzOwwgXhKJYiBsi_V5R4I-ng4641zmmBrVObkbkXCubUgQHDEuqrnHmFxCsh7ubSd1Nr7X-Hy0fs7QZoydGEoxLOnad/?imgmax=800" width="873" height="253" /></a></p> <p>Other ways I’ve seem were to add [System.Diagnostics.DebuggerHidden] or [System.Diagnostics.DebuggerNonUserCode] to methods – but with some side effects!</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-28649795004596111432010-04-12T22:30:00.001+01:002010-04-12T22:30:47.022+01:00Learning Tests<p>Robert C. Martin brought it into my world in his book “<a href="http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&s=books-intl-de&qid=1271076414&sr=8-1">Clean Code – A Handbook of Agile Software Craftmanship</a>” - “Learning tests”.</p> <p><strong>“Learning tests”</strong> (by K. Beck?) </p> <ul> <li>are unit tests </li> <li>to explore (learn) a new API or framework </li> <li>that builds a set of tests for regression when a new version of the component is used to validate that your expectations of the API is still fulfilled </li> </ul> <p>For an upcoming training I wanted to use <a href="http://automapper.codeplex.com/">AutoMapper</a> (by J. Bogard) for entity to/from DTO transformations. There is not a lot of documentation around for this open source library and my first trial with the API ended in a strange exception.</p> <p>So I decided to write some unit tests first (getting them red was rather easy ;-) and investigate on the common use of AutoMapper (<a href="http://www.google.com/codesearch">www.google.com/codesearch</a>).</p> <p><img src="http://www.cityofrockford.net/uploadedImages/government/HumanServices/HeadStart/Services/computer%20kids.jpg" width="369" height="240" /></p> <p>Here are some of my tests (please note the method names which should give you an idea about my expectations): </p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><summary></span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> Learning tests for automapper by Jimmy Bogard from http://automapper.codeplex.com/ </span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary></span></p> <p style="margin: 0px">[<span style="color: #2b91af">TestClass</span>]</p> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">AutoMapperTests</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    [<span style="color: #2b91af">TestInitialize</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> TestInitialize()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span>.Reset();</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    [<span style="color: #2b91af">ExpectedException</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">AutoMapperMappingException</span>))]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_NoMappingExists_Throws()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">DestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>(<span style="color: #2b91af">SourceType</span>.CreateSimple());</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMap_ReturnsMappingExpression()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">IMappingExpression</span><<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>> mappingExpression = <span style="color: #2b91af">Mapper</span>.CreateMap<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">DestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>(<span style="color: #2b91af">SourceType</span>.CreateSimple());</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.IsInstanceOfType(destination, <span style="color: blue">typeof</span>(<span style="color: #2b91af">DestinationType</span>), <span style="color: #a31515">"must return instance of destination type"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMapForOneMember_ReturnsDestinationWithOneMember()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span></p> <p style="margin: 0px">            .CreateMap<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.Text, c => c.MapFrom<<span style="color: blue">string</span>>(s => s.Text));</p> <p style="margin: 0px">        <span style="color: #2b91af">SourceType</span> source = <span style="color: #2b91af">SourceType</span>.CreateSimple();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">DestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>(source);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.AreEqual<<span style="color: blue">string</span>>(source.Text, destination.Text, <span style="color: #a31515">"member must be mapped"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMapForMembersIgnoreOne_ReturnsDestinationWithoutMember()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span></p> <p style="margin: 0px">            .CreateMap<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.Text, c => c.MapFrom<<span style="color: blue">string</span>>(s => s.Text))</p> <p style="margin: 0px">            .ForMember(d => d.Floating, c => c.Ignore())</p> <p style="margin: 0px">            .ForMember(d => d.Number, c => c.MapFrom<<span style="color: blue">int</span>>(s => s.Number));</p> <p style="margin: 0px">        <span style="color: #2b91af">SourceType</span> source = <span style="color: #2b91af">SourceType</span>.CreateSimple();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">DestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>(source);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.AreNotEqual<<span style="color: blue">double</span>>(source.Floating, destination.Floating, <span style="color: #a31515">"ignored member must not be mapped"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMapForChildMembers_ReturnDestinationWithChildMembers()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span></p> <p style="margin: 0px">            .CreateMap<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.Child, c => c.MapFrom<<span style="color: #2b91af">SourceType</span>>(s => s.Child));</p> <p style="margin: 0px">        <span style="color: #2b91af">SourceType</span> source = <span style="color: #2b91af">SourceType</span>.CreateSimple();</p> <p style="margin: 0px">        source.Child = <span style="color: #2b91af">SourceType</span>.CreateSimple();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">DestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>(source);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.AreEqual<<span style="color: blue">string</span>>(source.Child.Text, destination.Child.Text, <span style="color: #a31515">"child member (reference type) not mapped"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    [<span style="color: #2b91af">ExpectedException</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">AutoMapperMappingException</span>))]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMapWithoutRecursiveMaps_Throws()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: green">// map "outer" (root) type </span></p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span>.CreateMap<<span style="color: #2b91af">TopSourceType</span>, <span style="color: #2b91af">TopDestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.DestinationType, c => c.MapFrom<<span style="color: #2b91af">SourceType</span>>(s => s.SourceType));</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">TopSourceType</span> source = <span style="color: #2b91af">TopSourceType</span>.CreateSimple();</p> <p style="margin: 0px">        <span style="color: #2b91af">TopDestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">TopSourceType</span>, <span style="color: #2b91af">TopDestinationType</span>>(source);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.Fail(<span style="color: #a31515">"inner (reference type) map not done. Automapper must throw"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    [<span style="color: #2b91af">TestMethod</span>]</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">void</span> Map_CreateMapWithRecursiveMaps_ReturnsTreeDestination()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: green">// map "inner" type</span></p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span>.CreateMap<<span style="color: #2b91af">SourceType</span>, <span style="color: #2b91af">DestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.Text, c => c.MapFrom<<span style="color: blue">string</span>>(s => s.Number.ToString(<span style="color: #2b91af">CultureInfo</span>.CurrentCulture)));</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: green">// map "outer" (root) type </span></p> <p style="margin: 0px">        <span style="color: #2b91af">Mapper</span>.CreateMap<<span style="color: #2b91af">TopSourceType</span>, <span style="color: #2b91af">TopDestinationType</span>>()</p> <p style="margin: 0px">            .ForMember(d => d.DestinationType, c => c.MapFrom<<span style="color: #2b91af">SourceType</span>>(s => s.SourceType));</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">TopSourceType</span> source = <span style="color: #2b91af">TopSourceType</span>.CreateSimple();</p> <p style="margin: 0px">        <span style="color: #2b91af">TopDestinationType</span> destination = <span style="color: #2b91af">Mapper</span>.Map<<span style="color: #2b91af">TopSourceType</span>, <span style="color: #2b91af">TopDestinationType</span>>(source);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: #2b91af">Assert</span>.AreEqual<<span style="color: blue">string</span>>(</p> <p style="margin: 0px">            source.SourceType.Number.ToString(<span style="color: #2b91af">CultureInfo</span>.CurrentCulture), </p> <p style="margin: 0px">            destination.DestinationType.Text,</p> <p style="margin: 0px">            <span style="color: #a31515">"child member (of different reference types) not mapped"</span>);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    // … and more</p> <p style="margin: 0px">}</p> </div> <p>And here are my tests classes:</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><summary></span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> Tests-only source type for mapping tests.</span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary></span></p> <p style="margin: 0px"><span style="color: blue">internal</span> <span style="color: blue">class</span> <span style="color: #2b91af">SourceType</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">int</span> Number { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">string</span> Text { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">double</span> Floating { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: #2b91af">SourceType</span> Child { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">SourceType</span> CreateSimple()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">SourceType</span> { Floating = 1.1, Number = 13, Text = <span style="color: #2b91af">Guid</span>.NewGuid().ToString() };</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">internal</span> <span style="color: blue">class</span> <span style="color: #2b91af">TopSourceType</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">int</span>? Id { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: #2b91af">SourceType</span> SourceType { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">TopSourceType</span> CreateSimple()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">TopSourceType</span> { Id = 13, SourceType = <span style="color: #2b91af">SourceType</span>.CreateSimple() };</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><summary></span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> Tests-only destination type for mapping tests.</span></p> <p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary></span></p> <p style="margin: 0px"><span style="color: blue">internal</span> <span style="color: blue">class</span> <span style="color: #2b91af">DestinationType</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">int</span> Number { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">string</span> Text { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">double</span> Floating { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: #2b91af">DestinationType</span> Child { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">string</span> ToString()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">return</span> <span style="color: blue">string</span>.Format(<span style="color: #2b91af">CultureInfo</span>.CurrentCulture, <span style="color: #a31515">"Number = {0}, Text = {1}, Floating = {2}"</span>, <span style="color: blue">this</span>.Number, <span style="color: blue">this</span>.Text, <span style="color: blue">this</span>.Floating);</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">internal</span> <span style="color: blue">class</span> <span style="color: #2b91af">TopDestinationType</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">string</span> Id { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: #2b91af">DestinationType</span> DestinationType { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px">}</p> </div> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-55959080665967350502010-03-16T14:44:00.001+01:002010-03-16T14:44:26.259+01:00Specification Pattern with Func<><p>Specification is a pattern (Evans/Fowler) that can be used to apply rules for your domain entities:</p> <p><em>Create a specification that is able to tell if a candidate object matches some criteria. The specification has a method isSatisfiedBy (anObject) : Boolean that returns "true" if all criteria are met by anObject.</em></p> <p>It defines an interface like</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">interface</span> <span style="color: #2b91af">ISpecification</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">bool</span> IsSatisfiedBy<T>(T candidate);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: #2b91af">ISpecification</span> And(<span style="color: #2b91af">ISpecification</span> other);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: #2b91af">ISpecification</span> Or(<span style="color: #2b91af">ISpecification</span> other);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: #2b91af">ISpecification</span> Not();</p> <p style="margin: 0px">}</p> </div> <p>where IsSatisfiedBy() wraps the business logic (not contained in the entity as OO would suggest). </p> <p>That allows to write business logic code like</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px">price.And(seats).And(slow.Not())</p> </div> <p>My car specification:</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">CarSpecification</span> : Specifications.<span style="color: #2b91af">CompositeSpecification</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: #2b91af">Func</span><<span style="color: #2b91af">Car</span>, <span style="color: blue">bool</span>> IsSatisfiedFunction { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> CarSpecification(<span style="color: #2b91af">Func</span><<span style="color: #2b91af">Car</span>, <span style="color: blue">bool</span>> isSatisfiedFunction)</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">this</span>.IsSatisfiedFunction = isSatisfiedFunction;</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">bool</span> IsSatisfiedBy<T>(T candidate)</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: blue">if</span> (!(candidate <span style="color: blue">is</span> <span style="color: #2b91af">Car</span>))</p> <p style="margin: 0px">        {</p> <p style="margin: 0px">            <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #2b91af">ArgumentException</span>(<span style="color: #a31515">"must pass Car entity"</span>, <span style="color: #a31515">"candidate"</span>);</p> <p style="margin: 0px">        }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: blue">if</span> (<span style="color: blue">this</span>.IsSatisfiedFunction != <span style="color: blue">null</span>)</p> <p style="margin: 0px">        {</p> <p style="margin: 0px">            <span style="color: blue">return</span> <span style="color: blue">this</span>.IsSatisfiedFunction(candidate <span style="color: blue">as</span> <span style="color: #2b91af">Car</span>);            </p> <p style="margin: 0px">        }</p> <p style="margin: 0px">        <span style="color: blue">return</span> <span style="color: blue">false</span>;</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> </div> <p>The whole code: </p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">partial</span> <span style="color: blue">class</span> <span style="color: #2b91af">MainWindow</span> : <span style="color: #2b91af">Window</span></p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">private</span> <span style="color: #2b91af">IList</span><<span style="color: #2b91af">Car</span>> cars;</p> <p style="margin: 0px">    <span style="color: blue">private</span> <span style="color: #2b91af">CarSpecification</span> price = <span style="color: blue">new</span> <span style="color: #2b91af">CarSpecification</span>(c => c.Price <= 40000);</p> <p style="margin: 0px">    <span style="color: blue">private</span> <span style="color: #2b91af">CarSpecification</span> seats = <span style="color: blue">new</span> <span style="color: #2b91af">CarSpecification</span>(c => c.Seats >= 7);</p> <p style="margin: 0px">    <span style="color: blue">private</span> <span style="color: #2b91af">CarSpecification</span> slow = <span style="color: blue">new</span> <span style="color: #2b91af">CarSpecification</span>(c => c.HorsePower < 140);</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">public</span> MainWindow()</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        InitializeComponent();</p> <p style="margin: 0px"> </p> <p style="margin: 0px">        <span style="color: blue">this</span>.cars = ApplyRules(<span style="color: #2b91af">Cars</span>.Get());</p> <p style="margin: 0px">        <span style="color: blue">this</span>.DataContext = <span style="color: blue">this</span>.cars;</p> <p style="margin: 0px">    }</p> <p style="margin: 0px"> </p> <p style="margin: 0px">    <span style="color: blue">private</span> <span style="color: #2b91af">IList</span><<span style="color: #2b91af">Car</span>> ApplyRules(<span style="color: #2b91af">IList</span><<span style="color: #2b91af">Car</span>> cars)</p> <p style="margin: 0px">    {</p> <p style="margin: 0px">        <span style="color: #2b91af">ISpecification</span> myCarSpecification = price.And(seats).And(slow.Not());</p> <p style="margin: 0px">        <span style="color: blue">return</span> cars.Where(c => myCarSpecification.IsSatisfiedBy<<span style="color: #2b91af">Car</span>>(c)).ToList();</p> <p style="margin: 0px">    }</p> <p style="margin: 0px">}</p> </div> <p>Definitively this simple example could be written in other ways. More importantly you evaluate your new car ….</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzsPEmXhUTfVAOR8j1_wdyrtOVGle6Q8KptumlWR77l-Lgv4MjyYuUwj1ZtnzqxVx0XKhwMt2fXZgqxnHEqe5rNKix-bN1SvS6UhmpucEfDraCzQLMRZLxmNubUQvxey8-S-NqBK1Sm60O/s1600-h/image%5B8%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivdq1LJ7tOE3gI6hRy_waOfcS7efuZn7v2-nGJwA1b8x7SdTdIv8Rh05clJ7sO33Wi6bqRnoObMNVxWp0drxguPx7uT8QdHS56oZ5TtT4SvCZuGCz5IgY2IkhCDtr07QsMP7CfT_A7Da6c/?imgmax=800" width="868" height="192" /></a></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com0tag:blogger.com,1999:blog-8040115472186352073.post-80555907808258691932010-03-16T11:16:00.001+01:002010-03-16T11:16:00.133+01:00Linq in a Generic Data Access Layer with EF4<p><strong></strong></p> <p><strong>Introduction</strong></p> <p>Decoupling a data access layer (DAL) from business or service logic has become mainstream for some time now – not only due to testing (mocking) reasons but also because replacing your ageing data access technology or your database (manufacturer) may be a topic.</p> <p><strong>The Interface</strong></p> <p>I’ve created a simple repository pattern (CRUD) kind of interface over the last year or two. The methods of the interface are generic</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">int</span> Add<T>(T entity);</p> <p style="margin: 0px"><span style="color: blue">int</span> Delete<T>(T entity);</p> <p style="margin: 0px"><span style="color: blue">int</span> Update<T>(T entity);</p> <p style="margin: 0px"><span style="color: #2b91af">IList</span><T> GetAll<T>();</p> <p style="margin: 0px">// and more</p> </div> <p>The implementation was done with NHibernate 2.1 and recently with Entity Framework 4.0 (EF4). </p> <p><strong>The Domain Model</strong></p> <p>I had several domain models and object-relational mapping (ORM) definitions. Here’s a simple model to show things:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiADiHSyHGCinmP_BQJGqq3IRr4q7YaKKqyT6EIl4ZBcD7aAgtlYadpVe6i-zFXcPphpFhjBDIzRWMC-yTVpWJOMQOORy-2v2W5RDPYy4T1hafULsx5F9E_N9iJbSVeo1do-P6p9ZCZI3gy/s1600-h/image13.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_8SuFzywowiM/S59aVmwyC-I/AAAAAAAAA-U/mXHruYpfzQw/image_thumb7.png?imgmax=800" width="415" height="555" /></a> </p> <p>A blog or facebook like system that stores Entry objects allows for people to add Comments or just say they like it (Liker).</p> <p><strong>Using Linq</strong> </p> <p>Linq is a powerful language feature that can be used to submit queries from the layers on top of the DAL. It is data access and database independent because it works on the domain model – so no coupling to a particular technology.</p> <p>For this reason I provided a Linq entry point to the interface. Shown here is the EF4 implementation:</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">public</span> <span style="color: #2b91af">IQueryable</span><T> GetLinq<T>()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: #2b91af">ObjectContext</span> context = GetObjectContext();</p> <p style="margin: 0px">    <span style="color: blue">return</span> context.CreateObjectSet<T>() <span style="color: blue">as</span> <span style="color: #2b91af">IQueryable</span><T>;</p> <p style="margin: 0px">} </p> </div> <p>Or even easier with NHibernate and the NHibernate Linq provider:</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">public</span> IQueryable<T> GetLinq<T>()</p> <p style="margin: 0px">{</p> <p style="margin: 0px">    <span style="color: blue">return</span> <span style="color: blue">this</span>.Session.Linq<T>();</p> <p style="margin: 0px">}</p> </div> <p>Now you can program statements like</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px">l = databaseContext.GetLinq<<span style="color: #2b91af">Entry</span>>().Where(entry => entry.Title.Length > <span style="color: #a52a2a">5</span>).ToList();</p> </div> <p>emitting SQLExpress 2008 T-SQL:</p> <p><a href="http://lh5.ggpht.com/_8SuFzywowiM/S59aWIW5PTI/AAAAAAAAA-Y/Qg1KTPWIV2s/s1600-h/image9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtzeoojxIaXCyzKQXAT8dL8xF81r8cs9u3cmo1U_ulvMc0uWS1ERsSf10MgqvABDuLFu9ZEwI0LVnacIf3bNfJfa6Nx73VOZjTaGD1FzxL0E3LNuQLNxLskaYSlcK8KKbwZb3qXHMdBbfc/?imgmax=800" width="319" height="143" /></a> </p> <p>Or more complex</p> <div style="font-family: courier new; background: white; color: black; font-size: 12pt"> <p style="margin: 0px"><span style="color: blue">var</span> result = <span style="color: blue">from</span> x <span style="color: blue">in</span> <span style="color: blue">this</span>.databaseContext.GetLinq<<span style="color: #2b91af">Entry</span>>()</p> <p style="margin: 0px">             <span style="color: blue">join</span> y <span style="color: blue">in</span> <span style="color: blue">this</span>.databaseContext.GetLinq<<span style="color: #2b91af">Liker</span>>()</p> <p style="margin: 0px">             <span style="color: blue">on</span> x.Id <span style="color: blue">equals</span> y.Entry_FK</p> <p style="margin: 0px">             <span style="color: blue">select</span> <span style="color: blue">new</span> { x.Title, y.Posted };</p> </div> <p>producing</p> <p><a href="http://lh6.ggpht.com/_8SuFzywowiM/S59aXFwakeI/AAAAAAAAA-g/vJsPuMccx6s/s1600-h/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_8SuFzywowiM/S59aX_vom3I/AAAAAAAAA-k/xYTXnngbT48/image_thumb2.png?imgmax=800" width="639" height="104" /></a></p> <p>Clean and optimized! The above seems to work due to lazy evaluation and loading. </p> <p>Note that you could use GetAll<T>().Where() kind of code, but this would return all (10000+) records and only filter on the result set – so a performance killer.</p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1tag:blogger.com,1999:blog-8040115472186352073.post-42889273181063925262010-01-15T16:36:00.001+01:002010-01-15T16:36:18.555+01:00Create your own Web Casts with Microsoft Expression Encoder Screen Capture<p>Have you ever explained a certain topic to a peer or a live audience and wanted to</p> <ul> <li>record your computer screen</li> <li>record the audio</li> <li>save this to a file</li> </ul> <p>for later reuse or another audience?</p> <p>Then the <a href="http://www.microsoft.com/Expression/products/Encoder_Overview.aspx">Microsoft Expression Encoder (3) Screen Capture</a> is an application to look at. Screen Capture is included in Expression Studio 3, Expression Web 3 or the Expression Professional Subscription.</p> <p>Start the application, enable the microphone (and web cam; no tried yet myself) and press the red dot button.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiF_uPZPsr720d-HgSFsjdLioijFM2MVghfCUyxo94_cSs0Tp8n9wj8qBVcj0X3XuhlYqWTU_L3CnHThtR6y6mn1e7RZzqKVHMLr4qulU2OOoA2MSumeb6QvdU2nM9ppJfBbppXxtTpQIR/s1600-h/image%5B3%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_8SuFzywowiM/S1CLY-XOgnI/AAAAAAAAA3M/cvJwkdAnIeg/image_thumb%5B1%5D.png?imgmax=800" width="435" height="91" /></a></p> <p>Select the screen area to capture</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghow-_9vTxBEf1lrJSCZeASkOmFDM4lri0TKsizetjraIvPzXu54nvmGLgQHz_8g1HOFoXaV_DK8cH5vu1rUYCINSIcr_mQGMfi3C8EvfqNq9PfKC2qM9JlIcTjWoRz8sJVtJbs0CE9kiD/s1600-h/image%5B22%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis7IYhHwEd97Hur8bQU8tc82vvkOqrmCHEZtHJyt-UM-qZQ21lxcBuzkpdodD-P1sld8Y6sWRZPadhDjrbILQ_hw55oKbuJ2g8krGqM4fnySrQRp3o3IHfMJykNeOaIieuKZZkD6TP4RRY/?imgmax=800" width="591" height="480" /></a></p> <p>Press the red button again to confirm your selection</p> <p><a href="http://lh5.ggpht.com/_8SuFzywowiM/S1CLaRrb6SI/AAAAAAAAA3Y/haocICwtgZU/s1600-h/image%5B13%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQpMJt_008qDJFWEzA_49TMeNNb5k9lwl2S33jC8XeCqqBgKqHvXIjmOJdIHUtxHrccQqH1o_zAY22Y-zEXrtI7Yow_yyl2V8Bq3TjDJGAnMFR2ENK2GWE9suBLs76oKeBNfqDo21Y1NTT/?imgmax=800" width="443" height="101" /></a></p> <p>Pausing recording is done with Ctrl+Shift+F11, stopping with Ctrl+Shift+F12.</p> <p>An .xesc file is now create. To encode this to a more common format (like mp4 or wmv) Microsoft Expression Encoder 3 can be used: </p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFPW7nmn7Y0oDsD5zSiV3Rwk-RpTypimXTHfOEkt9gZi5qSJX4RDoZkgBtUwjo6hJkvp74GhQGoVWtzOHstG6Z6AbFXLA2IGRcNPOtfzENROR1waIe9sbbAEtZz4SSsOnEh7sTpvyAmoiI/s1600-h/image%5B24%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFtlun7lN-Q_6U228EMKPzzMwrCxF9x2eoVaq7EZRpC9o-mQdpX53Z7nn_MWqANnvv9iz7lHD9OUiFPOkQwZDrSLO2J4LVz8PbhPs1NTn_HMz36MQRezRMsf0rQMLTHjH55iiXvVXZgKm1/?imgmax=800" width="726" height="496" /></a></p> Markus Lederhttp://www.blogger.com/profile/18420051096418489608noreply@blogger.com1