Johnny Code2020-08-05T12:27:29+00:00http://johnnycode.comJohn Bubriskibubriski@gmail.comFreeing up space in local SQL Server Databases2018-02-27T13:00:00+00:00http://johnnycode.com/2018/02/27/freeing-up-space-in-local-sql-server-databases<p>The sizes of my local databases for <a href="https://stackoverflow.com">Stack Overflow</a> were huge, so I did some digging to reduce their size. Here is a basic list of easy things to do to free up space in your SQL Server databases.</p>
<hr />
<p><strong><em>I would not recommend doing ANY of these on prod!!!</em></strong>
<strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong>***</p>
<ol>
<li><strong>Shrink the DB</strong>. There is often unused space within the allocated DB files (*.mdf).</li>
<li><strong>Shrink the Log File</strong>. Same idea as above but with the log file (*.ldf).</li>
<li><strong>Rebuild the indexes and <em>then</em> shrink the DB</strong>. If you have large tables the indexes are probably fragmented. In SQL Server you can go to <code class="language-plaintext highlighter-rouge">Table > Indexes > Rebuild All</code>, or <strong>check out the script below to rebuild all indexes in a DB</strong>. <strong>FYI, this will actually INCREASE the size of your DB file until you shrink it again!</strong></li>
</ol>
<p>Those 3 above were enough for my local setup. Shrinking initially didn’t do much for me (because I had already done it in the past), but <strong>rebuilding the indexes on a <em>single table</em> cleared up 15 Gb from my biggest DB</strong>!</p>
<p>Here is the article where I found the info about rebuilding indexes… there are some more suggestions in there as well: <a href="http://aboutsqlserver.com/2014/12/02/size-does-matter-10-ways-to-reduce-the-database-size-and-improve-performance-in-sql-server/">Size does matter: 10 ways to reduce the database size and improve performance in SQL Server</a></p>
<p>Here is a nicely formatted version of a script from <a href="https://gallery.technet.microsoft.com/scriptcenter/Script-for-rebuilding-all-8d079754">Mohammad Nizamuddin on TechNet</a>. their script to rebuild all the indexex in the current database. Yes, it can take a while so run it when you step away from the computer. Make sure you remember to shrink the DB again after you run it!</p>
<hr />
<p><strong><em>SECOND WARNING!!! DON’T RUN THIS ON PROD!!!!!</em></strong>
<strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong>***</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DECLARE @TableName varchar(255)
DECLARE TableCursor CURSOR FOR
SELECT table_name
FROM information_schema.tables
WHERE table_type = 'base table'
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
DBCC DBREINDEX(@TableName, ' ', 90)
FETCH NEXT FROM TableCursor INTO @TableName
END
CLOSE TableCursor
DEALLOCATE TableCursor
</code></pre></div></div>
<p>I wonder if this would also improve the performance of the index. Maybe it’s something that can be run on prod with your DBA’s approval, during an off-peak time.</p>
Procedural Generation 101 (for games)2016-11-08T13:00:00+00:00http://johnnycode.com/2016/11/08/procedural-generation-101-for-games<div style="padding: 10px; color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc;">
<a href="https://github.com/jbubriski/unity-proc-gen">Download the sample project: Unity Proc Gen Sample Project on GitHub</a>
</div>
<blockquote>
<p>“Awwww man I need some of that Procedural Generation in my game”</p>
<p>- anonymous totally not made up indie game developer</p>
</blockquote>
<p>But what is it? Well it’s when your game is all random and stuff right? Sort of. I like to think of it as randomness with a bit of intelligence. It isn’t a silver bullet, but it can help add variety and re-playability to your game.</p>
<p>But before we get into it, let’s take a look at some games that do Procedural Generation.</p>
<h2 id="games-that-use-procedural-generation">Games that use Procedural Generation</h2>
<ul>
<li>Minecraft, Terraria - Terrain is dynamically created for each game.</li>
<li>Diablo I, II, III, Spelunky - Dungeons/map is generated.</li>
<li>The Division - Set pieces (rooms) are dynamically linked together each time a new mission is run.</li>
<li>No Man’s Sky - Terrain, creatures and plants are generated the same way for everyone who plays the game.</li>
<li>Borderlands 1, 2 - Weapon models and stats are generated.</li>
<li>Crossy Road, Land Sliders, Shooty Skies - Mobile games that randomly generate levels.</li>
<li>Final Frontier (a highly anticipated unreleased game from an up and coming indie game developer) - Enemy waves are generated at increasingly difficulty with great variety.</li>
<li>And many others!</li>
</ul>
<p>Think about those for a minute. Many different types of games use Procedural Generation, and they use it for different aspects of gameplay. Even if 2 games use it for the same aspect they may still use it in different ways. Terraria and The Division and both generate the map but Terraria generates the terrain while The Division composes its level out of set piece rooms. Think about some of the other similiarities between these games. Think about if any of your favorite games use Procedural Generation. Finally, think about games that don’t use Procedural Generation.</p>
<h2 id="applications-of-procedural-generation">Applications of Procedural Generation</h2>
<p>Given the list of games we just mentioned we can see that there are many different applications of randomness:</p>
<ul>
<li>Terrain/level creation</li>
<li>Enemies/spawning</li>
<li>Loot/weapons/gear</li>
<li>Models/textures/animations</li>
<li>Sound/music - I’m not well versed in games with Procedurally Generated sound, but I’ve “heard” it’s a thing. (GET IT!?)</li>
<li>Story/quests/dialog</li>
</ul>
<h2 id="procedural-generation-methods">Procedural Generation Methods</h2>
<p>So how is this randomness achieved? And what is so intelligent about it? Let’s start simple and imagine we’re making a Dungeon Crawler. For the sake of this article, let’s apply Procedural Generation to the map, enemies, and loot.</p>
<h3 id="method-1-regular-ol-randomness">Method 1: Regular Ol’ Randomness</h3>
<p>While not intelligent, you can use pure randomness.</p>
<ul>
<li>How big is each level of our dungeon? Randomly create a grid of tiles 10-100 high/wide.</li>
<li>What is the layout of the dungeon? Each tile is randomly selected from a list: Empty, Decoration, Trap, Enemy.</li>
<li>What enemies are going to show up? Randomly select 1-10 enemies.</li>
<li>What loot drops? Pick a random item image, select 5 random abilities for it.</li>
</ul>
<p>Sounds like we have ourselves an awesome game, right? Every play-through will probably be drastically different! Wait, DRASTICALLY different? Well, yeah that could be an issue… We could get 10 bosses to spawn right next to us and drop nothing but worthless loot. Or maybe we get 1 weak goblin to spawn and he drops Excalibur and Aegis! Or maybe the map is 100x100 and is ALL TRAPS. Or maybe… you get the idea.</p>
<p>While this type of gameplay can be entertaining, it’s too chaotic and the user will quickly become frustrated that the game either goes really well, really badly, or anywhere in between.</p>
<p>A better approach is what I call…</p>
<h3 id="method-2-guided-randomness">Method 2: Guided Randomness</h3>
<p>As we just saw, complete randomness can be great… or disastrous. Instead of drowning our game in randomness we’ll selectively apply randomness, with limits (or ranges). Good games slowly ramp up difficulty and avoid huge discrepancies in difficulty. Let’s take our last example and upgrade it:</p>
<ul>
<li>How big is each level of our Dungeon? The level grid starts at 10x10 and gets increasingly bigger as the player progresses.</li>
<li>What is the layout of the dungeon? Each level is allowed a certain number of traps and decorations. Those numbers slowly increase with the level size so the whole level doesn’t become traps and decorations.</li>
<li>What enemies are going to show up? Start with only weak enemies and slowly introduce the more difficult ones. Optionally replace a harder enemy with many smaller ones, for more variety.</li>
<li>What loot drops? Find a way to categorize the abilities that can appear on an item and select 1 from each category. Maybe certain abilities have a higher chance to appear together and maybe some can’t appear together at all. Fire and Ice damage on a single weapon might seem silly for example, cuz realism.</li>
<li>Quests - “Fetch ______ ______’s from ______ for ______”.</li>
</ul>
<p>So now that we’ve created a more fluid play-through, how can we share it? Wait, you can share randomness?</p>
<h3 id="improvement-1-using-a-seed">Improvement 1: Using a Seed</h3>
<p>Imagine you just had an amazing play through of a game, and your friend wants to play it too so you can finally settle who is better at video games. If we want to share our play through, we need the game’s randomness to be deterministic. That means the game should produce the same results everytime, given a start value, or <strong>seed</strong>. Random Number Generators (RNG’s) are able to take a value that it uses as a starting point.</p>
<p>If you create a new RNG instance and pass it the same seed every time you will get the same exact sequence of values generated. As long as everything is generated in the same order, the exact same experience can be replayed!</p>
<p>But that doesn’t mean that <em>everything</em> should be using a seed. For example, cosmetic things like particle effects can still be fully randomized simply because it doesn’t matter, and the sequence in which they’re created would be different for every play through. We also want to make sure that we use a separate RNG instance for each type of thing that we’re generating. For example, the layout engine should use it’s own RNG to make sure that we don’t accidentally generate a random value somewhere and throw the whole thing off.</p>
<p>Keep in mind that while the game can be generated the same way, each player may play the game differently. If you have a game with multiple paths through a given map, a player could take a different route and therefore encounter things in a different order.</p>
<p>Ok, so now our game has pretty interesting playthroughs, and we can even share them! How do we take things to the next level?</p>
<h3 id="improvement-2-set-pieces">Improvement 2: Set Pieces</h3>
<p>Randomness with constraints can only get you so far. Eventually you may want to incorporate <strong><em>Set Pieces</em></strong>. Set Pieces are pieces of content that are <strong>pre</strong>-generated, either by the game developer or by the game.</p>
<p>Let’s continue with our dungeon crawler example. If you tried creating the game I’ve been describing so far, you’ll find that there are still some rough edges. At times, things just don’t end up looking or feeling right. Maybe the Traps were all created in a cluster that is easily avoidable, or maybe the RNG gods decided to roll really bad stats on every weapon that drops.</p>
<ul>
<li>Dungeon Layout - Create “blocks” that consist of several tiles preconfigured with decorations, traps, and enemies. Imagine 4 Skeleton Guards faithfully guarding a booby-trapped sacred altar with a Golden Chalice on top. Sounds cool, right? Don’t use that one though… that’s mine. (The Division, Diablo, and Spelunky all do something like this. See the links at the bottom for an <strong><em>amazing</em></strong> video on Spelunky’s Level Generation)</li>
<li>Loot - Create Named Weapons that have unique stats like “The Party Pooper” which is the only weapon in the game that makes a sad trombone noise and spews out confetti every time you kill an enemy. (The Division, Diablo, Borderlands, and many others have named items)</li>
<li>Quests - Hand-craft a number of quests and sprinkle them throughout the game amidst the fetch quests. A cool idea might be to disguise a set-quest as a fetch quest, surprising the player with a boss or some awesome loot.</li>
</ul>
<p>OK now our game is FREAKIN’ SWEET. SHIP IT! What? Not yet? What else could we possibly need?</p>
<h3 id="noise-functions">Noise Functions</h3>
<p>Randomize the volume? No! Not that type of noise. Noise as in static, like on a incorrectly setup TV, or when your old car radio can’t find a station. Noise can do some of the heavy lifting for you when it comes to randomization. Let’s take a look at a Noise Function commonly used in games for terrain generation called <a href="https://en.wikipedia.org/wiki/Perlin_noise">Perlin Noise</a>.</p>
<p>(<em>Apparently there is a successor to Perlin Noise called <a href="https://en.wikipedia.org/wiki/Simplex_noise">Simplex Noise</a>. However, it is patented so there is also <a href="https://en.wikipedia.org/wiki/OpenSimplex_noise">OpenSimplex noise</a></em>)</p>
<p>Perlin Noise generates a grid of values ranging from 0 to 1. What’s cool is if we map the grid of values to a grid of pixels, we would get an image that looks like clouds! Each pixel in the cloud image is a different shade of black, or if you look at it another way, each pixel can be a value between 0 and 1. 0 being completely white, 1 being completely black, and anything in between representing shades of gray. Since we have values from 0 to 1, we could multiply those values by a fixed number and get any upper limit! Multiply everything by 10 and we get 0 to 10. Multiply everything by 25 and we get 0 to 25. Multiply everything by 10,000 and we get 0 to 10,000. You get the idea.</p>
<p>Now that we can scale the image data to fit our needs we can apply it to different things. A prime example of this would be a height map for terrain. Using a scale of 0 - 100, we could use 25 as “sea level”. Any number below 25 would be considered water, 25-35 would be beach, 30-60 would be forests, 60-90 would be hills, and 90-100 would be mountains. Another example would be to calculate the probability of a trap appearing, or clusters herds of enemies/animals.</p>
<h2 id="a-simple-example---final-frontier">A Simple Example - Final Frontier</h2>
<p>Now that we’ve covered the basics, let’s take a slightly more detailed look at a real world example.</p>
<p>Final Frontier is a simple space shooter. Each game consists of increasingly difficult waves of enemies. Once all enemies in a wave are cleared players are given 10 seconds to purchase upgrades and prepare themselves for the next wave.</p>
<p>The Procedural Generation comes in the form of the enemy makeup of each wave. Each successive wave has a larger point value assigned to it. That point value is used to spawn a varying number of enemies each round. Enemies are spawned until the points are exhausted. For example, these could be the point values for the enemies:</p>
<ul>
<li>1 - Scout - Crappy trash mob.</li>
<li>3 - Cloaking Scout - Hard to see at times which allows it to sneak up on the player.</li>
<li>10 - Light Gunship - Slow moving, but has a turret and missiles.</li>
<li>20 - Heavy Gunship - Even slower moving, but has multiple turrets and missile launchers.</li>
<li>50 - Mothership - A mobile base. Super slow, gigantic, armed to the teeth, and launches fighters.</li>
</ul>
<p>And these could be the point values available to each wave:</p>
<ul>
<li>Wave 1 - 5</li>
<li>Wave 2 - 10</li>
<li>Wave 3 - 15</li>
<li>Wave 4 - 20</li>
<li>Wave 5 - 30</li>
<li>Wave 6 - 40</li>
<li>Wave 7 - 50</li>
<li>Wave 8 - 75</li>
<li>Wave 9 - 100</li>
<li>Wave 10 - 150</li>
</ul>
<p>When we put those together we can see the different possibilities for each wave:</p>
<ul>
<li>Wave 1
<ul>
<li>5 Scouts</li>
<li>2 Scouts, 1 Cloaking Scout</li>
</ul>
</li>
<li>Wave 3
<ul>
<li>15 Scouts</li>
<li>3 Cloaking Scouts</li>
<li>5 Scouts, 2 Cloaking Scouts</li>
<li>10 Scouts, 1 Cloaking Scout</li>
</ul>
</li>
<li>Wave 5
<ul>
<li>30 Scouts</li>
<li>15 Scouts, 5 Cloaking Scouts</li>
<li>1 Light Gunship, 20 Scouts</li>
<li>1 Light Gunship, 5 Scouts, 5 Cloaking Scouts</li>
<li>1 Light Gunship, 1 Heavy Gunship</li>
<li>etc.</li>
</ul>
</li>
</ul>
<p>As the game progresses, each wave can have more variety in it, but the difficulty shouldn’t vary <em>too</em> much.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If this all sounds pretty cool, you should check out <a href="http://www.procjam.com/">PROCJAM</a>, the Procedural Generation Game Jam! There are a lot of great resources there, even if you don’t plan on entering the Jam.</p>
<p>Just in case it wasn’t obvious from the title, Procdeural Generation has other applications than just games! I’ve heard</p>
<p>And if you’re in the Boston area on Novermber 19th, I’ll be speaking at the <a href="http://www.bostoncodecamp.com">Boston Code Camp</a> about Procedural Generation and showing examples in Unity.</p>
<h2 id="resources-and-other-cool-links">Resources and Other Cool Links</h2>
<p><del>Dogs on the internet</del> People have done a lot of cool stuff with procedural generation. Check out these awesome examples:</p>
<ul>
<li><a href="https://github.com/jbubriski/unity-proc-gen">Unity Proc Gen Sample Project on GitHub</a></li>
<li><a href="http://www.procjam.com/">PROCJAM - Procedural Generation Game Jam</a></li>
<li><a href="https://www.youtube.com/watch?v=3wcpLwvBTYo">PROCJAM 2016 Talks</a></li>
<li><a href="https://www.youtube.com/watch?v=Uqk5Zf0tw3o">How (and Why) Spelunky Makes its Own Levels | Game Maker’s Toolkit</a></li>
<li><a href="http://mewo2.com/notes/terrain/">Generating Fantasy Maps</a></li>
<li><a href="http://www.redblobgames.com/maps/terrain-from-noise/">Making maps with noise functions</a></li>
<li><a href="https://docs.unity3d.com/ScriptReference/Mathf.PerlinNoise.html">PerlinNoise function in Unity</a></li>
<li><a href="https://docs.unity3d.com/Manual/RandomNumbers.html">Unity Manual - Adding Random Gameplay Elements</a></li>
<li><a href="http://abundant-music.com/">Procedurally Generate Your Own Music</a></li>
<li><a href="http://darwintunes.org/welcome">Darwin Tunes - Procedurally Generated Music</a></li>
</ul>
Intel RealSense Camera and Hackathon Review2015-10-02T13:00:00+00:00http://johnnycode.com/2015/10/02/intel-realsense-camera-and-hackathon-review<p>So I somehow got invited to an Intel RealSense™ Hacker Lab.</p>
<p><em>Disclaimer: The event was free, food/drink was provided, I got to keep the camera, and I had a chance to win some prizes (but didn’t). I also wasn’t asked to do this review.</em></p>
<p>TLDR: The Intel RealSense camera is basically an embeddable version of the Kinect and I got to build something with one and take it home. Despite some bad logistics, the event was pretty good and it was fun to work with a Kinect-like device.</p>
<h2 id="schedule">Schedule</h2>
<p>The event consisted of slide presentations, questions, and playing with demos in the first half of the morning, then on to code demo in the second half. After lunch we were free to create our own projects until around 5:30. Then we demoed the projects and they judged them and gave out prizes (I Didn’t win anything).</p>
<h2 id="camera-features">Camera Features</h2>
<p>Now about the Intel RealSense camera. We used (and were given to take hom) an external F200 camera made by Creative. The F200 is the same camera used internally on a few laptops on the market right now. There is a rear-facing R200 version coming out soon that is meant for longer ranges.</p>
<ul>
<li>Has a 1080p RGB camera</li>
<li>Works from something like 8 inches to 4 feet from the camera. <a href="https://software.intel.com/en-us/articles/intel-realsense-data-ranges">More details on Intel RealSense Data Ranges</a>, including their rear-facing R200 camera.</li>
<li>Tracks something like 21 points on each hand, and something like 76~ points on the face.</li>
<li>Can also do some form of 3D scanning and random object tracking (I think they have a specific app coming that does this).</li>
<li>Has hand gesture support and facial emotion tracking.</li>
<li>Does <strong>NOT</strong> swivel/move like the Kinect.</li>
<li>Microphone (dual I think)</li>
</ul>
<h2 id="camera-featuresusage-impressions">Camera Features/Usage Impressions</h2>
<p>I’m not going to hold back… from using the demos, I found the hand tracking to be pretty janky. If you have open hands with palms facing the camera it works perfectly. As soon as you start moving your fingers around it frequently loses track of them because, naturally, the IR sensor can’t see fingers behind fingers (or hands behind hands). The API also has built in support for various gestures, but they work with a varying degree success. Most of the project demos that day that involved hand tracking were not super successful. One project used swipe gestures which were recently added to the API but they basically didn’t work at all during the presentation (Apparently it was more reliable when it was being tested).</p>
<p>The facial tracking, however, was actually pretty impressive since your head (generally) doesn’t contort it’s features around! One demo mapped all 76~ tracking points to the video feed and operated exactly as you would expect! Unfortunately, facial emotion tracking is basically unusable at this point with the SDK. However, I can imagine that they would be able to develop better algorithms to change this as long as the data they’re receiving currently would allow that to happen. I guess there is nothing stopping you from taking the raw data points and developing/using your own algorithms as well.</p>
<p>Finally, the camera/API itself had some issues. Multiple people had problems with it randomly not working (myself included), and I think someone’s unit died completely during the event. Unity also crashed pretty often, again, randomly. Some times my app would even try to connect to the built in webcam on the laptop! Hopefully these are all just software issues that can be eventually solved.</p>
<h2 id="projects">Projects</h2>
<p>I built a game called Emergency Landing. Your plane is on fire and your goal is to steer it safely to a landing strip by tilting your head. Tilting your head to the side banks it left and right, while leaning forward and backward causes the plane to subtly start to dive or level out. You start the game and choose easy or hard. You are then set on a rough course towards one of 2 landing strips, based on difficulty. In hard mode the landing strip is farther so the plane is going faster/higher in order to get within range. All you need to do is make contact with the landing strip and you win. Touch any other ground/tree/bounding box and you lose. I was very please with what I was able to make despite the issues mentioned earlier.</p>
<p>The runner up made a game where you were a robot shooting lasers at enemies. Your robot had a rolly thing on the bottom whose movementswere controlled by moving the left hand up/down. The right hand controlled the steering/aiming. It was a pretty well done demo, however the controls looked very unintuitive/difficult to use. Again, IMO the hand tracking is not great.</p>
<p>The winner had made a music app where opening your mouth in different ways played different tones. Moving your hands varied the pitch. It was pretty inventive, but it didn’t sound very good, and it was one of the most ridiculous/scary things I’ve ever seen.</p>
<p>The rest of the demos ranged from simply spinning 3D models with gestures to Starfox clones. One guy had used a separate “360 degree camera” and made it so that you could look around one of the pictures he had taken with that other camera.</p>
<p>Another guy had integrated the system with a JavaScript project that makes different types of music, but this one actually sounded good. It was precanned melodies and things but you would switch instruments/tempo using gestures. I would have voted for that one.</p>
<h2 id="logistics">Logistics!?!?</h2>
<p>This is basically going to be me complaining for a few paragraphs…</p>
<p>First off, it took me 2.5 hours to get there (not their fault) and they told me to park at 1-2 hour street parking or 2 hour lot parking… for a 12 hour event (their fault). Since it was the beginning of the Genesis flood, I was SOAKED after going out to move my car (to a real lot), and stayed that way all day. The room was also pretty crowded.</p>
<p>Also, there were a ton of issues with the setup of the laptops they had us use. They didn’t realize that the new VS requires sign in and some people didn’t have MS accounts. A Unity account was also required, but I can’t remember if they had mentioned that before (I don’t think they did). Some people’s laptops were also missing the materials so a thumb drive had to be passed around, which apparently still had issues because they were still using a web installer.</p>
<p>(To be clear, I have both a Unity and MS account, so I was fine)</p>
<h2 id="conclusion">Conclusion</h2>
<p>TBH, the market penetration isn’t there for these devices so it wouldn’t be practical to build apps/games solely dependent on the hand/face tracking. However, you may be able to guarantee the presence of the device in certain industries (medical, gov?), or you could offer an enhanced/alternate modes for when the camera is present. It sounds like these cameras will eventually end up in most PC laptops, but it is probably going to be a while for you to <em>expect</em> people to have one (just like what happened with the original web cam).</p>
<p>Developing for this type of device shouldn’t be forced. To paraphrase the Intel guy, you should use interfaces to do what they’re designed to do. Don’t create a virtual keyboard when you know that this will be attached to a laptop/desktop that already has a mouse/keyboard. So unfortunately, having these other great specialized input mechanisms almost limits the applications of the hand/face tracking. But that’s a good thing too.</p>
<p>I think games will be where this might initially take off, as well as private applications with integrated hardware. I’m hoping that someday we all have enhanced versions of these camera so we can practice Karate, sign language, dancing, and more.</p>
.NET Is Not a Black Box, Open It Up2014-10-09T13:00:00+00:00http://johnnycode.com/2014/10/09/dot-net-is-not-a-black-box-open-it-up<p>Recently I’ve been working with a site that has had a ton of problems. The latest issue was that we needed to configure the Active Directory integration which involved setting up an .exe that handled importing users. Unfortunately, with the cloud hosting of the CMS, the .exe didn’t work.</p>
<h2 id="complain">Complain</h2>
<p>I contacted support and they basically said I was shit outta luck! They basically told me I needed to upgrade to the latest version in order to use that feature with their cloud hosting.</p>
<h2 id="now-what">Now What?</h2>
<p>Better give up and tell the customer… right?</p>
<p>Nope. Screw the CMS vendor, let’s fix it ourselves.</p>
<p>So what does the AD import utility actually do?</p>
<ol>
<li>Take SQL Server Credentials</li>
<li>Take AD Credentials</li>
<li>Map fields</li>
<li>Import the data from AD into SQL Server</li>
</ol>
<p>Sounds simple enough, now what’s the problem? Here is a screenshot of the actual error:</p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/kentico-ad-import-utility-error.png" alt="Save the patched assembly" /></p>
<p>After speaking with support and googling around I figured out that <code class="language-plaintext highlighter-rouge">sp_databases</code> is a system stored procedure in SQL Server that lists out the databases on the server. Since the CMS is using a certain type of cloud hosting, we don’t have access to that stored procedure. But that shouldn’t really matter. We already have all the connection information handy. I’m guessing that the utility is doing an extra call to <code class="language-plaintext highlighter-rouge">sp_databases</code>.</p>
<h2 id="identify-the-issue">Identify The Issue</h2>
<p>Now that we’ve formed a hypothesis about why the error is occurring, how do we actually fix it?</p>
<p>Luckily for us, .NET and things created with .NET are not black boxes. Let’s crack open the .exe and try and find the specific problem with the code.</p>
<p>For examining the assembly (.dll or .exe) we have a myriad of options:</p>
<ul>
<li><a href="http://ilspy.net/">ILSpy</a> - My goto favorite since it’s open source.</li>
<li><a href="http://www.telerik.com/products/decompiler.aspx">Telerik JustDecompile</a> - A good free option.</li>
<li><a href="http://www.red-gate.com/products/dotnet-development/reflector/">Red Gate .NET Reflector</a> - Paid product, but supposedly the best.</li>
</ul>
<p>I think I originally started with ILSpy to identify the issue. However, identifying the issue is only so valuable. Now I needed to fix it.</p>
<h2 id="fix-the-issue">Fix The Issue</h2>
<p>ILSpy will allow you to save the decompiled C# code to disk, but then we would have to manually recompile it. Another option would be to use the <a href="http://msdn.microsoft.com/en-us/library/f7dy01k1(v=vs.110).aspx">IL Dissembler</a> (Ildasm.exe) to decompile the assembly into it’s IL, but that would require a little bit of work too. It’s 2014, let’s take the easy way out.</p>
<p>With a bit more googling I found <a href="http://reflexil.net/">Reflexil</a>, “The .NET Assembly Editor”. From the homepage:</p>
<blockquote>
<p>Reflexil is an assembly editor and runs as a plug-in for Red Gate’s Reflector and Telerik’s JustDecompile. Reflexil is using Mono.Cecil, written by Jb Evain and is able to manipulate IL code and save the modified assemblies to disk. Reflexil also supports C#/VB.NET code injection.</p>
</blockquote>
<p>PERFECT.</p>
<p>So I grabbed <a href="http://www.telerik.com/products/decompiler.aspx">JustDecompile</a>, opened up the plugin manager, and installed the Reflexil plugin which is labeled as “Assembly Editor” in the plugin list.</p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/telerik-justdecompile-plugins-manager.png" alt="The plugin manager in Telerik JustDecompile" /></p>
<p>Armed with the Reflexil plugin let’s take a look at what I found:</p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/found-the-code.png" alt="We found the code" /></p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/found-the-il.png" alt="We found the IL" /></p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/edit-existing-instruction.png" alt="Edit the existing instruction" /></p>
<p><img src="/assets/images/2014-10-09-dot-net-is-not-a-black-box-open-it-up/save-assembly-as.png" alt="Save the patched assembly" /></p>
<p>OK that’s a lot of information, let’s dissect the steps needed to follow along:</p>
<ol>
<li>Open the Reflexil plugin from the plugin menu.</li>
<li>Like in any other IL explorer/decompiler, find the code in question.</li>
<li>Click the method name which causes Reflexil to load the IL just for that method.</li>
<li>Look for identifiers in the IL. In this case we can see that there is the string <code class="language-plaintext highlighter-rouge">"Step2_ErrorConnectingDB"</code> in the C# code which appears directly in the IL.</li>
<li>After finding the general are of the code, find the actual code in question. In this case we can see that we’re setting the <code class="language-plaintext highlighter-rouge">connectionResult</code> to <code class="language-plaintext highlighter-rouge">false</code> in C#. In the IL we can see that the variable is being worked with on instruction 081.</li>
<li>Analyze the details. IL does one thing at a time. Instruction 081 is setting up the variable to be worked with. Instruction 082 is setting it to false (0) with <a href="http://en.wikipedia.org/wiki/List_of_CIL_instructions"><code class="language-plaintext highlighter-rouge">ldarg.0</code></a>.</li>
<li>Make the change (shown in the third image). Right-click on the instruction and select “Edit…”. Change it to <a href="http://en.wikipedia.org/wiki/List_of_CIL_instructions"><code class="language-plaintext highlighter-rouge">ldarg.1</code></a> (true, or the value 1).</li>
<li>Save out the updated assembly. In the tree view, right-click on the .exe and select “Save as…” and save the patched assembly.</li>
<li>Take the rest of the day off.</li>
</ol>
<p>And there you have it! I prevented having to tell the customer that they would need to upgrade their CMS, all in about 2 hours. The result was that the error message flickers in the step for a split second before the wizard just proceeds to the next step.</p>
<h2 id="conclusion">Conclusion</h2>
<p>While this sort of thing is usually a last resort, it is definitely something you can do, even without deep knowledge of IL and how .NET works. I know next to nothing about actual IL code, I just googled the instructions to find out what they did.</p>
<p>So the next time you encounter a .NET .exe or DLL you don’t have the source for, don’t be afraid to take a peak inside and maybe even change something!</p>
How to get the Current Controller Name, Action, or ID in ASP.NET MVC2014-10-03T13:00:00+00:00http://johnnycode.com/2014/10/03/how-to-get-the-current-controller-name-action-or-id-asp-net-mvc<p>«««««««««««««««
Updated!!! A commenter asked for the area name, so I’ve included that in the code as well.<br />
«««««««««««««««</p>
<p>Luckily I’ve been back in ASP.NET MVC lately! On a new project I needed to check the current controller and actions for highlighting the current item in the menu. SO I dug up some of my custom code that seems to still apply to the latest ASP.NET MVC.</p>
<h2 id="usage">Usage</h2>
<p>From your view you can simply use the extension methods off the <code class="language-plaintext highlighter-rouge">Html</code> object:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Html.Controller();
@Html.Action();
@Html.Id();
@Html.Area();
</code></pre></div></div>
<h2 id="show-me-the-code">Show me the Code!</h2>
<p>Here it is:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static class HtmlRequestHelper
{
public static string Id(this HtmlHelper htmlHelper)
{
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
if (routeValues.ContainsKey("id"))
return (string)routeValues["id"];
else if (HttpContext.Current.Request.QueryString.AllKeys.Contains("id"))
return HttpContext.Current.Request.QueryString["id"];
return string.Empty;
}
public static string Controller(this HtmlHelper htmlHelper)
{
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
if (routeValues.ContainsKey("controller"))
return (string)routeValues["controller"];
return string.Empty;
}
public static string Action(this HtmlHelper htmlHelper)
{
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
if (routeValues.ContainsKey("action"))
return (string)routeValues["action"];
return string.Empty;
}
public static string Area(this HtmlHelper htmlHelper)
{
var dataTokens = HttpContext.Current.Request.RequestContext.RouteData.DataTokens;
if (dataTokens.ContainsKey("area"))
return (string)dataTokens["area"];
return string.Empty;
}
}
</code></pre></div></div>
<p>Just add this class into your project. You may need to reference the namespace in the view folder web.config. Let me know if I need to add that part in.</p>
<p>Thanks!</p>
How to fix Disqus on your CloudFlare Backed Site2014-08-01T13:00:00+00:00http://johnnycode.com/2014/08/01/how-to-fix-disqus-on-your-cloudflare-backed-site<p>I use CloudFlare on JohnnyCode.com (You’re on it right now!). It provides some really <a href="https://www.cloudflare.com/overview" title="An Overview of CloudFlare">cool features related to performance and security</a> that I wont get into right now. What I will mention is that CloudFlare’s features are very “tweakable”, letting you only use what you want.</p>
<h2 id="ad-blockers">Ad Blockers</h2>
<p>First, disable any ad blockers you might have, just to make sure they’re not interfering with things.I use Adblock Plus and this was definitely blocking certain requests. In Chrome, the extension is in the top-right corener of the browser. Click it, and choose to enable ads for your domain.</p>
<h2 id="tweak-cloudflares-settings">Tweak CloudFlare’s Settings</h2>
<p>Something about CloudFlare’s optimizations seemed to be interfering with the <a href="https://disqus.com/">Disqus</a> comment engine that I use on my site. I ignored it for a while but I finally got around to investigating it, and here is how I fixed it.</p>
<ul>
<li>Go to CloudFlare and login (duh).</li>
<li>Go to Settings > Performance settings for the domain in question.</li>
<li>Disable the Rocket Loader™ (Web optimization)/ BETA</li>
</ul>
<p>Image:</p>
<p><img src="/assets/images/2014-08-01-how-to-fix-disqus-on-your-cloudflare-backed-site/cloudflare-performance-settings.png" alt="CloudFlare Performance Settings Page" /></p>
<p>That’s it.</p>
<p>Something with their Rocket Loader JS optimizations kills Disqus. FYI, I did try adding cloudflare.com and ajax.cloudflare.com as trusted domains in Disqus prior to this, but it didn’t seem to fully fix the problem (You may want to do that anyway, thinking toward the future).</p>
Exclude Kentico Linked Documents from Smart Search Results2014-08-01T12:00:00+00:00http://johnnycode.com/2014/08/01/exclude-kentico-linked-documents-from-smart-search-results<p>It’s pretty easy. Simply go into the Smart Search Results Web Part and set the <code class="language-plaintext highlighter-rouge">Search condition</code> to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-NodeLinkedNodeID:[0 TO 999999999]
</code></pre></div></div>
<p>Image:</p>
<p><img src="/assets/images/2014-08-01-exclude-kentico-linked-documents-from-smart-search-results/smart-search-results-web-part-settings-dialog.png" alt="Kentico Smart Search Results Web Part Settings Dialog" /></p>
<p>Another quick tip is to exclude disabled products from your search results if you’re using E-commerce:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-NodeLinkedNodeID:[0 TO 999999999] AND SKUEnabled:true
</code></pre></div></div>
<p>That’s it!</p>
<h2 id="explanation">Explanation</h2>
<p>If you’re wondering what that funky syntax is, it’s <a href="http://lucene.apache.org/core/2_9_4/queryparsersyntax.html">Lucene Query Parser Syntax</a> (technically <a href="http://lucenenet.apache.org/">Lucene.net</a>, but I think the same syntax applies). It basically says:</p>
<ul>
<li>”-“ - Exclude…</li>
<li>“NodeLinkedNodeID” - Documents (Nodes) where the NodeLinkedNodeID is…</li>
<li>”:[0 TO 999999999]” - Between 0 and 999999999.</li>
</ul>
<p>So if the NodeLinkedNodeID field has a number in it, it’s a Linked Document and we want to exclude it.</p>
<h2 id="credit">Credit</h2>
<p>I originally found this <a href="http://devnet.kentico.com/forums/f55/fp15/t32334/exclude-linked-documents-from-search">solution on the Kentico DevNet</a>, posted by Juraj Ondrus, but I figured it would be good to have a stand alone post along with a deeper explanation of the solution.</p>
Finding The Mobile App Development Option That's Right For You2014-06-04T12:00:00+00:00http://johnnycode.com/2014/06/04/finding-the-mobile-app-development-option-thats-right-for-you<p>When it comes to mobile development, where do you start? There are a myriad of options these days, and I’ll try and give a basic overview of the big players. I’ll let you decide which one is right for you.</p>
<p><em>Disclaimer: I’ve only shipped 1 mobile app, and have worked on some other. However, I’ve been trying to keep my eye on things and this is the state of mobile development as I see it.</em></p>
<h2 id="native-or-not">Native or Not?</h2>
<p>What are the general pros and cons of native vs non-native development?</p>
<p>IMO, native development generally means that you have complete control over an app’s performance, can consume the latest API’s, and can almost automatically utilize each platforms UI design. If you are OK with targeting a single platform (probably iOS), then investing all your efforts in the best possible experience for that one platform can pay off. I have also heard that no matter how you develop apps, learning the specific API’s for the specific platforms is beneficial.</p>
<p>The downside of native development is that you need to develop your app from scratch for each platform. If you’re targeting iOS, Android and Windows Phone, that’s 3 different codebases you need to develop and maintain (and try and be an expert in). As the developer building the mobile app(s), you will need to learn 3 different languages and API’s to varying degrees.</p>
<p>If we look at things from a cross platform perspective, we might need to sacrifice some cost, performance, features, and/or flexibility in order to share most, if not all code. Xamarin seems to be a great solution if you can spend the money. The other web-based options seem to be great alternatives if you’re looking to keep costs low or leverage web technologies you may already be familiar with. The web-based options also provide an extremely low barrier to entry.</p>
<p>Now let’s take a more detailed look at some of the specific options…</p>
<h2 id="native-android-google-play-amazon-app-store-etc">Native Android (<a href="https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCAQFjAA&url=https%3A%2F%2Fplay.google.com%2Fapps%2Fpublish%2F&ei=nB-PU8GXNYzgsATKy4D4AQ&usg=AFQjCNEvG-AI0sojdmEeraO9D_b4Xtsn6g&sig2=8qpONJjRVtg6CwALqtlsLA" title="Google Play Developer Console enables developers to easily publish and distribute their applications directly to users of Android-compatible phones">Google Play</a>, <a href="https://developer.amazon.com/public">Amazon App Store</a>, etc.)</h2>
<p>You develop your Android apps with Java and push them out to Google Play or other Android App Stores. A developer account with Google Play is free, easy to setup, and you can publish an app within hours.</p>
<ul>
<li>Cost - Free</li>
<li>Language - Java</li>
<li>IDE - Eclipse, Eclipse derivative, or other 3rd party options.</li>
</ul>
<h2 id="native-ios">Native iOS</h2>
<p>You develop your iOS apps with XCode and push them out to the iOS App Store. A Apple Developer Account costs $100 a year and I think it requires an <a href="http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/Apply-for-an-Employer-Identification-Number-(EIN)-Online">EIN number</a>. There is typically a 2 week minimum wait time for your app to be approved. Your app can also be rejected, requiring that you go through the 2 week approval process again.</p>
<ul>
<li>Cost - $100 / year for an Apple Developer Account</li>
<li>Language - Objective-C</li>
<li>IDE - XCode</li>
</ul>
<h2 id="cross-platform---xamarin">Cross Platform - <a href="http://xamarin.com/" title="Create native iOS, Android, Mac and Windows apps in C#">Xamarin</a></h2>
<p>You build the bulk (~80%) of your app’s logic with C# and build the UI’s specific to each platform separately. The Indie Xamarin plan costs $400 per platform per developer per year. Higher tiers are availble for additional features like Visual Studio support, a quite of cross-platform business controls, and access to the Mobile Test Cloud.</p>
<p>Example: It would cost $4000 a year for a team of 5 to build apps for iOS and Android.</p>
<ul>
<li>Cost - Minimum $400 / platform / dev / year (Additional tiers offer more features at a higher price)</li>
<li>Language - C#</li>
<li>IDE - Xamarin Studio or Visual Studio with a higher package, plus others for creaing UI’s.</li>
</ul>
<h2 id="cross-platform---phonegap">Cross Platform - PhoneGap</h2>
<p>Provides a wrapper and access to native API’s for “web pages”. You build your app with HTML/CSS/JS like you would a website and use PhoneGap to build that into an app for iOS or Android. PhoneGap hides the fact that the app is running a “website” and can look native depending on the styling that you use (CSS). The <a href="https://build.phonegap.com/">PhoneGap Build</a> service from Adobe will handle the actual build process for the various platform dependent things like the Android .APK’s and iOS XCode Projects. You simply upload a zip of your code and wait for their service to do it’s magic.</p>
<p><em>I have worked with PhoneGap and PhoneGap Build to develop a simple party game. It seemed to work great, and let us build the whole game in 1 weekend. Unforunately due to copyright issues we never shipped the game.</em></p>
<ul>
<li>Cost - Free (for now)</li>
<li>Language - HTML/CSS/JavaScript</li>
<li>IDE - Whatever you want</li>
<li>Conjecture: Potentially has performance issues. Not sure if there are any limitations when using Native API’s. Support for Native API’s may be lacking or may not be implemented right away. Not sure if they will charge for the service in the future.</li>
</ul>
<h2 id="cross-platform---cocoonjs">Cross Platform - CocoonJS</h2>
<p>Is similar to PhoneGap in that your app is built with JS, but has traditionally targetted Canvas-based apps. This is exclusively an online service, since their system is proprietary. The real benefit of using CocoonJS is that it translates Canvas draw calls to GPU calls. This means that games written in JS can nearly match the performance of native games.</p>
<p><em>I actually have used this service to ship a game with <a href="http://fragcastle.com/">Frag Castle</a> called RK Runner for <a href="https://itunes.apple.com/tc/app/rk-runner/id632390010?mt=8">iOS</a> and <a href="https://play.google.com/store/apps/details?id=com.fragcastle.rkrunner">Android</a>. Try it out and see for yourself how well it performs.</em></p>
<ul>
<li>Cost - Free (for now)</li>
<li>Language - HTML/CSS/JavaScript or JavaScript via Canvas</li>
<li>IDE - Whatever you want</li>
<li>Makes it easy to port JS games to mobile.</li>
<li>Conjectur: Not sure if they will charge for the service in the future.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>This is not an exhaustive list of mobile app development options. I know there are other services out there like the <a href="http://app-framework-software.intel.com/" title="The JavaScript library for mobile HTML5 app development.">Intel App Framework</a> and Telerik’s <a href="http://www.telerik.com/appbuilder" title="Telerik App Builder">App Builder</a> and <a href="http://www.telerik.com/platform" title="Telerik Platform">Platform</a>. So take all this with a grain of salt and do your own research.</p>
<p>Given what I know about the above platforms, here is my breakdown of how to choose:</p>
<ul>
<li>Native - To target a single platform or learn the specifics about it’s API’s and features.</li>
<li>Xamarin - For businesses that want to efficiently develop native apps for iOS and Android.</li>
<li>PhoneGap - For “regular” apps that can be built with the web stack for low cost.</li>
<li>CocoonJS - For games that can be built with HTML5/JS or ported from HTML5/JS.</li>
</ul>
<p>Hope this was helpful, feel free to let me know about any other options out there.</p>
Improved Unity Diffs in GitHub2014-05-20T12:00:00+00:00http://johnnycode.com/2014/05/20/improved-unity-diffs-in-github<p>At <a href="http://fragcastle.com" title="Frag Castle Games">Frag Castle Games</a> we use a private <a href="http://github.com" title="GitHub">GitHub</a> repo to store our source code for <a href="http://rockkickass.com" title="Rock Kickass - a 2D platormer">Rock Kickass</a>. We use Branches and Pull Requests to build new features and incorporate them back into master.</p>
<h2 id="the-problem">The Problem</h2>
<p>Our system has worked great in the past, but since we’ve switched to <a href="http://unity3d.com/" title="Unity Game Engine">Unity</a> things have been tougher:</p>
<p><img src="/assets/images/2014-05-20-improved-unity-diffs-in-github/sample-diff.png" alt="Sample Diff of a Feature Pull Request" /></p>
<p>See what I mean? In case you missed it:</p>
<ul>
<li>61 changed files</li>
<li>28,707 additions</li>
<li>846 deletions</li>
</ul>
<p>You’re probably thinking “<em>WOW, that is a metric #</em>&$#$#-ton of code*”. Not exactly…</p>
<p>The reason for the gigantic stats is that Unity creates a meta file for each file that you import. This is fine, because Unity needs this meta data to let you configure how you work with imported files (quality settings, slicing, etc). But as you can see it <strong>hoses</strong> the diffs.</p>
<p>I don’t think you can <strong>not</strong> check in those files. It would cause massive problems in the way that Unity keeps track of things. Surprisingly, there is no way to filter the view of those files within GitHub!</p>
<p>So what’s a Unity dev to do?</p>
<h2 id="the-answer">The Answer</h2>
<p>Use a <strong><em>bookmarklet</em></strong> to run some JS on the diff page and hide all the irrelevant files!</p>
<p>Here is a link to the gist with the JS files for hiding the irrelevant Unity files:</p>
<p><a href="https://gist.github.com/jbubriski/eba4bbeecccd5e4fc0ec" title="Bookmarklet JS for hiding Unity files in GitHub diffs">https://gist.github.com/jbubriski/eba4bbeecccd5e4fc0ec</a></p>
<p>And here is the embedded gist:</p>
<script src="https://gist.github.com/jbubriski/eba4bbeecccd5e4fc0ec.js"> </script>
<h2 id="usage">Usage</h2>
<p>A bookmarklet is a browser bookmark, but instead of it pointing to a URL, it points to some JavaScript that runs when you envoke the bookmark. I have the usage details in the gist as well, but here is a simple test you can do with bookmarklets.</p>
<ol>
<li>Make a new bookmark in your browser.</li>
<li>Set the title to whatever you want… something like “<code class="language-plaintext highlighter-rouge">bookmarklet test</code>”</li>
<li>set the URL to “<code class="language-plaintext highlighter-rouge">javascript: alert('It works');</code>”</li>
</ol>
<p>Now that we know how bookmarklets work, you can take the 2 JS snippets from the gist and turn them into bookmarklets! When you’re viewing a diff on GitHub, simply run your bookmarklet and voilà! Usable diffs!</p>
<h2 id="explanation">Explanation</h2>
<p>So what do the scripts do exactly?</p>
<p>The main script simply uses JS to scan the page and find individual diff sections of certain file types and hide those sections. It uses jQuery for easy DOM searching a manipulation. Currently it hides files with the following extensions:</p>
<ul>
<li>.unity</li>
<li>.meta</li>
<li>.anim</li>
<li>.controller</li>
<li>.prefab</li>
<li>.asset</li>
</ul>
<p><strong>If you think of any more types to include, <a href="https://twitter.com/JohnBubriski" title="My Twitter account">drop me a line on Twitter</a>!</strong></p>
<p>The secondary script finds all the diff sections and shows them, restoring the original view.</p>
<p><em>Note: Alternatively, I could make a link on a page that let’s you simply drag that link to your bookmark bar, but I’m guessing the exact code will be tweaked over the next few weeks. Eventually, ideally, I will make links for easy setup.</em></p>
Using the jQuery Validate Plugin with HTML5 Data Attribute Rules2014-03-27T12:00:00+00:00http://johnnycode.com/2014/03/27/using-jquery-validate-plugin-html5-data-attribute-rules<p><a href="http://jqueryvalidation.org/" title="Form validation with jQuery">The jQuery Validation Plugin</a> is a great plugin that “just works”. It’s so great that even <a href="http://www.asp.net/mvc/tutorials/mvc-5/introduction/adding-validation">ASP.NET MVC uses the plugin for client side validation</a>! They have a nice JavaScript API for wiring up validation rules and messages, along with the <a href="http://jqueryvalidation.org/documentation/" title="jQuery Validation Plugin Documentation">documentation</a> for it. However, they have an almost completely undocumented feature that makes use of HTML5 data attributes!</p>
<p>I think that I originally knew this feature existed because ASP.NET MVC uses jQuery Validate for “unobtrusive validation”, meaning they don’t inline JavaScript in your markup, but instead use data attributes.Apparently you can use any rule as a data attribute after version <a href="https://github.com/jzaefferer/jquery-validation/issues/868">1.11.0</a>.</p>
<h2 id="basic-example">Basic Example</h2>
<p>If you have no idea what I’m talking about here is a super simple example of the jQuery Validation Plugin on JS Fiddle:</p>
<iframe width="100%" height="300" src="http://jsfiddle.net/jbubriski/SLXhR/embedded/html,js,resources,result" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p><a href="http://jsfiddle.net/jbubriski/SLXhR/">and a link to the JS Fiddle</a>.</p>
<p>And here is the same code here, just in case:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><!DOCTYPE html>
<html>
<form id="validate-me-plz">
<div>
Required: <input type="text" name="firstName" data-rule-required="true" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.0.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script type="text/javascript">
$('#validate-me-plz').validate();
</script>
</html>
</code></pre></div></div>
<p>You can see that on the input element we have an attribute called <code class="language-plaintext highlighter-rouge">data-rule-required</code> that is set to <code class="language-plaintext highlighter-rouge">true</code>. Just calling <code class="language-plaintext highlighter-rouge">.validate()</code> on the form element will check for these data attributes and run the validations. As mentioned earlier, there is also JavaScript API for applying rules.</p>
<h2 id="rule-format">Rule Format</h2>
<p>To add rules to your input elements follow this format:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>data-rule-[rule name separate by dashes]="true"
</code></pre></div></div>
<p>Here are some examples:</p>
<ul>
<li>Required - <code class="language-plaintext highlighter-rouge">data-rule-required="true"</code></li>
<li>Email - <code class="language-plaintext highlighter-rouge">data-rule-email="true"</code></li>
<li>Minimum Length = <code class="language-plaintext highlighter-rouge">data-rule-minlength="6"</code></li>
</ul>
<h2 id="message-format">Message Format</h2>
<p>By default the jQuery Validation Plugin will add it’s owne messages, but you can customize them to be whatever you want using another data attribute. To specify messages for each rule with data attributes follow this format:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>data-msg-[rule name separate by dashes]="The message you want."
</code></pre></div></div>
<p>Here are some examples:</p>
<ul>
<li>Required - <code class="language-plaintext highlighter-rouge">data-msg-required="Madam/sir, this field is required."</code></li>
<li>Email - <code class="language-plaintext highlighter-rouge">data-msg-email="Let us spam you, enter a valid email address."</code></li>
</ul>
<h2 id="full-example">Full example:</h2>
<p>Here is a more complete example on JS Fiddle that shows different validators and messages being used:</p>
<iframe width="100%" height="300" src="http://jsfiddle.net/YQgEq/1/embedded/html,js,resources,result" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p><a href="http://jsfiddle.net/jbubriski/YQgEq/2/">and a link to the JS Fiddle</a>.</p>
<p>And here is the same code here, just in case:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><!DOCTYPE html>
<html>
<form id="validate-me-plz">
<div>
Required: <input type="text" name="required" data-rule-required="true" />
</div>
<div>
Required w/custom message: <input type="text" name="required-sassy" data-rule-required="true" data-msg-required="Please enter SOMETHING." />
</div>
<div>
Email: <input type="text" name="email" data-rule-email="true"/>
</div>
<div>
Email w/custom message: <input type="text" name="anotherEmail" data-rule-email="true" data-msg-email="Please enter a valid email address you dummy." />
</div>
<div>
<input type="submit" value="Validate!" />
</div>
</form>
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script type="text/javascript">
$('#validate-me-plz').validate();
</script>
</html>
</code></pre></div></div>
<h2 id="how-it-works">How it works</h2>
<p>If you’re interested in how it works, take a <a href="https://github.com/jzaefferer/jquery-validation/blob/master/src/core.js#L928" title="Look at the code that reads the data validation attributes.">look at core.js around line 928</a>. They simply use the jQuery <code class="language-plaintext highlighter-rouge">data()</code> method to check each element for all of the loaded validators. They automatically covert the validator name in the data attribute name:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>value = $element.data("rule" + method[ 0 ].toUpperCase() + method.substring( 1 ).toLowerCase());
</code></pre></div></div>
<p>But where are the dashes? I didn’t realize it, but data attributes can (should?) be referenced via jQuery <em>without</em> their dashes. Instead of the dashes you <a href="http://en.wikipedia.org/wiki/CamelCase" title="iUseCamelCaseForLocalVariableNames">Camel Case</a> the data attribute name, without the “data-“ prefix. The above code results in something like this for the required rule:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>value = $element.data("ruleRequired");
</code></pre></div></div>
<p>which maps to the <code class="language-plaintext highlighter-rouge">data-rule-required</code> attribute.</p>
<h2 id="rule-list">Rule List:</h2>
<p>If you want to know exactly what the validators are available and what they do <a href="https://github.com/jzaefferer/jquery-validation/blob/master/src/core.js#L1037">look at the code for the validators in core</a> or <a href="https://github.com/jzaefferer/jquery-validation/tree/master/src/additional">browse the additional validators</a>.</p>
<p>Here is a list of them that I compiled by looking at the source on GitHub. I marked them with what part of the framework they’re from, and whether or not I tested them:</p>
<p>(Tested, core)</p>
<ul>
<li>data-rule-required=”true”</li>
<li>data-rule-email=”true”</li>
</ul>
<p>(Untested, core, but should work)</p>
<ul>
<li>data-rule-url=”true”</li>
<li>data-rule-date=”true”</li>
<li>data-rule-dateISO=”true”</li>
<li>data-rule-number=”true”</li>
<li>data-rule-digits=”true”</li>
<li>data-rule-creditcard=”true”</li>
<li>data-rule-minlength=”6”</li>
<li>data-rule-maxlength=”24”</li>
<li>data-rule-rangelength=”5,10”</li>
<li>data-rule-min=”5”</li>
<li>data-rule-max=”10”</li>
<li>data-rule-range=”5,10”</li>
<li>data-rule-equalto=”#password”</li>
<li>data-rule-remote=”custom-validatation-endpoint.aspx”</li>
</ul>
<p>(Untested, additional, but should work)</p>
<ul>
<li>data-rule-accept=””</li>
<li>data-rule-bankaccountNL=”true”</li>
<li>data-rule-bankorgiroaccountNL=”true”</li>
<li>data-rule-bic=””</li>
<li>data-rule-cifES=””</li>
<li>data-rule-creditcardtypes=””</li>
<li>data-rule-currency=””</li>
<li>data-rule-dateITA=””</li>
<li>data-rule-dateNL=””</li>
<li>data-rule-extension=””</li>
<li>data-rule-giroaccountNL=””</li>
<li>data-rule-iban=””</li>
<li>data-rule-integer=”true”</li>
<li>data-rule-ipv4=”true”</li>
<li>data-rule-ipv6=”true”</li>
<li>data-rule-mobileNL=””</li>
<li>data-rule-mobileUK=””</li>
<li>data-rule-lettersonly=”true”</li>
<li>data-rule-nieES=””</li>
<li>data-rule-nifES=””</li>
<li>data-rule-nowhitespace=”true”</li>
<li>data-rule-pattern=””</li>
<li>data-rule-phoneNL=”true”</li>
<li>data-rule-phoneUK=”true”</li>
<li>data-rule-phoneUS=”true”</li>
<li>data-rule-phonesUK=”true”</li>
<li>data-rule-postalcodeNL=”true”</li>
<li>data-rule-postcodeUK=”true”</li>
<li>data-rule-require_from_group=””</li>
<li>data-rule-skip_or_fill_minimum=””</li>
<li>data-rule-strippedminlength=””</li>
<li>data-rule-time=””</li>
<li>data-rule-time12h=””</li>
<li>data-rule-url2=””</li>
<li>data-rule-vinUS=””</li>
<li>data-rule-zipcodeUS=”true”</li>
<li>data-rule-ziprange=””</li>
</ul>
<p>Thanks! Hope you found this helpful!</p>
Getting a Document or TreeNode from a URL in Kentico2014-02-20T12:00:00+00:00http://johnnycode.com/2014/02/20/getting-a-document-or-treenode-from-a-url<p>I was creating a web service method that was called via AJAX from an existing page. I needed to get the Document from which the service was being called but I didn’t want to dump the DocumentID/NodeID to the page. This is how my request was made:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$.post('/Path/To/Service.aspx'
, {
documenturl: document.location.href
});
</code></pre></div></div>
<p>Within the service I had the document URL of the calling page, but I needed more information about that Document. Using the <code class="language-plaintext highlighter-rouge">PageInfoProvider</code> I was able to translate the URL into a <code class="language-plaintext highlighter-rouge">PageInfo</code> object:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var pageInfo = PageInfoProvider.GetPageInfoForUrl(url, "en-US", (string)null, true, true, SiteInfoProvider.CurrentSiteName);
</code></pre></div></div>
<p>From there you can get the full Document/TreeNode given the ID’s on the <code class="language-plaintext highlighter-rouge">PageInfo</code> object:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pageInfo.DocumentID
pageInfo.NodeID
</code></pre></div></div>
<p>I was able to find this information by reflecting <code class="language-plaintext highlighter-rouge">CMS.URLRewritingEngine.dll</code> and examining the <code class="language-plaintext highlighter-rouge">URLRewriter</code> class and the <code class="language-plaintext highlighter-rouge">RewriteUrl</code> method.</p>
How To Become A Programmer And Get A Job2014-01-16T12:00:00+00:00http://johnnycode.com/2014/01/16/how-to-become-a-programmer-and-get-a-job<p>I recently came across a candidate for a developer position who sounded very promising, but unfortunately had graduated some years ago, had no experience and was working in a different field. I offered to give this person some advice and fortunately they were open to hearing my thoughts and opinions.</p>
<p>Instead of writing a one-off email, I thought it would make more sense to write a general version in a public place that I can point everyone at. I’ve come across several people who have mentioned they want to start/change careers.</p>
<h2 id="why-would-i-want-to-be-a-programmer">Why would I want to be a programmer???</h2>
<p>So many reasons…</p>
<ul>
<li>Good/Great/Amazing pay</li>
<li>You could make websites!</li>
<li>You could make mobile apps!</li>
<li>You could make desktop apps!</li>
<li>With the right job a programmer can work from home, or even work for themselves</li>
<li>You will probably naturally learn more things about computers</li>
<li>Your friends will think you are some sort of internet wizard, when you explain why their favorite website is broken</li>
<li>YOU WILL ALWAYS HAVE A JOB</li>
</ul>
<h2 id="is-programming-right-for-me">Is programming right for me???</h2>
<p>Maybe not, but is your current job right for you? At least as a programmer you will probably get good pay, regular working hours, job security, flexibility and more.</p>
<h2 id="but-i-cant-right-now-because">But I can’t right now because…</h2>
<p>There is nothing stopping you. Literally. Nothing. If you have access to some sort of computer, you can make it happen. No excuses. Programming is probably the most accessible field with a plethora of learning options out there. For example, programmers often feel the need to write how-to blog posts…</p>
<h2 id="how-do-i-proceed">How do I proceed?</h2>
<p>Read and write code.</p>
<p>Period.</p>
<p>There is no better way to learn, and probably, to get a job in the field. The best way to get better at something is to do it! So when you go home tonight, start making a simple HTML/CSS website. Next week add some jQuery or JavaScript. The week after that start doing some server-side programming with a database.</p>
<p>Having written some code at home, you may even have an advantage over other candidates when you interview. A very smart man named Linus Torvalds once said <em>“Talk is cheap. Show me the code.”</em>. And if you show them the code and it’s not half bad, they will have no choice but to hire you. If someone presented me with these 2 candidates:</p>
<ul>
<li>Did 2-4 years of college</li>
<li>Did 2-4 years of coding in their free time and created websites/apps that they could demo</li>
</ul>
<p>I would take the second candidate hands down. Even though <em>I</em> went to college, probably <em>because I went to college</em>, I would rather take someone who has “real-world” experience, then someone who was able to pass courses.</p>
<h2 id="but-where-do-i-start-i-dont-know-anything">But where do I start, I don’t know anything?</h2>
<h3 id="online-learning">Online learning</h3>
<p>No, I’m not talking about an online degree. These days there is a lot to learn, but there are so many resources available. I haven’t used all of these sites personally, but I’ve heard good things about them:</p>
<ul>
<li><a href="http://www.codecademy.com/" title="Code Academy - Learn to code interactively, for free.">Code Academy</a> (FREE)</li>
<li><a href="https://www.khanacademy.org/" title="Khan Academy - Start learning now. Completely free, forever.">Khan Academy</a> (FREE)</li>
<li><a href="https://www.coursera.org/" title="Take the world's best courses, online, for free.">Coursera</a> (FREE)</li>
<li><a href="https://www.codeschool.com/" title="Code School - Learn by Doing. No setup. No hassle. Just learning.">Code School</a> ($, but some free, I did some courses and they seem good)</li>
<li><a href="http://teamtreehouse.com/" title="Treehouse - Learn how to build websites & apps, write code or start a business.">Treehouse</a> ($, heard from a non-programmer friend that it is good)</li>
<li><a href="https://www.udemy.com/" title="Start Learning from the World's Top Instructors">Udemy</a> ($, but some free, heard from a co-worker that it’s good)</li>
</ul>
<h3 id="books">Books</h3>
<p>There is always books! Personally I like books, and pretty much anything you get from O’Reilly or APress will be good. The great thing about books is that a good book will start with the basics and build you up. They don’t usually leave out important things and have been tech review (and reviewed by the great users of Amazon.com!) Here are 3 O’Reilly books I looked up on Amazon that have good reviews:</p>
<ul>
<li><a href="http://www.amazon.com/HTML-XHTML-Definitive-Chuck-Musciano-ebook/dp/B00BQN40IS/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389887335&sr=1-1&keywords=o%27reilly+html">HTML & XHTML: The Definitive Guide</a></li>
<li><a href="http://www.amazon.com/CSS-Definitive-Guide-Eric-Meyer-ebook/dp/B00457X7L8/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389887367&sr=1-1&keywords=o%27reilly+css">CSS: The Definitive Guide</a></li>
<li><a href="http://www.amazon.com/JavaScript-Definitive-Guide-Guides-ebook/dp/B004XQX4K0/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389887352&sr=1-1&keywords=o%27reilly+javascript">JavaScript: The Definitive Guide</a></li>
</ul>
<h3 id="friends">Friends</h3>
<p>I’ve written an article before on <a href="http://johnnycode.com/2012/07/20/establish-your-own-developer-kaizen-guild/" title="Establish Your Own Developer Kaizen Guild">building a team of people you can lean on if you need help</a> and also mentioned that <a href="http://www.hanselman.com/blog/WhoIsOnYourLifesBoardOfDirectors.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ScottHanselman+%28Scott+Hanselman+-+ComputerZen.com%29">Scott Hanselman says you need a “Life’s Board of Directors”</a>. When you’re starting out, a developer friend can be worth their weight in gold if you get stuck, need advice on which technologies to learn, or just want someone to shoot the (developer) shit with.</p>
<h3 id="go-to-code-camps-and-meetups">Go to code camps and meetups</h3>
<p>If you live anywhere near a city, chances are there is some sort of free code camp happening regularly, along with <a href="http://www.meetup.com/" title="Meetups are neighbors getting together to learn something, do something, share something…">meetup</a> groups that happen weekly! For example, the <a href="http://www.bostoncodecamp.com/">Boston Code Camp</a> (I live an hour from Boston and go when I can).</p>
<p>Nothing in your area? Start one.</p>
<h3 id="follow-websites-blogs-and-people-on-twitter">Follow websites, blogs and people on Twitter</h3>
<p>A great way to learn about what is out there is to find other vocal programmers and see what they’re talking about.</p>
<ul>
<li>Go to the <a href="http://www.reddit.com/r/programming/">Programming Sub-Reddit</a> and <a href="https://news.ycombinator.com/">Hacker News</a> (Just be wary of the comments)</li>
<li>Use <a href="http://feedly.com/">feedly</a> to follow their blogs.</li>
<li>Find a few key people on Twitter to get a pulse on what’s new/hot/interesting.</li>
</ul>
<h2 id="for-women">For women</h2>
<p>Some very awesome female developers named Sara Chipps and Vanessa Hurst that co-founded an organization called <a href="http://www.girldevelopit.com/" title="Don't be shy. Develop it.">Girl Develop It</a>, whose mission is as follows:</p>
<p><em>“Girl Develop It is an international organization, that exists to provide affordable and accessible programs to women who want to learn software development through mentorship and hands-on instruction.”</em></p>
<p>While they do charge for their classes (Maybe they have free ones too?), having hands-on workshops with support in a comfortable learning environment is probably invaluable. I think that I have heard of some other organizations catered towards women like <a href="http://www.blackgirlscode.com/">Black Girls Code</a>.</p>
<h2 id="so-what-do-you-john-bubriski-think-i-should-do">So what do YOU, John Bubriski, think I should do?</h2>
<h3 id="learn-html-css-and-javascript-to-make-websites">Learn HTML, CSS and JavaScript to make websites</h3>
<p>All websites run on these techs, and you need to a solid understanding to be most effective. Even if you want to go into mobile app development, knowing these techs can help you. You’ll need a website to support your app, right?</p>
<h3 id="learn-git-for-source-control">Learn Git for source control</h3>
<p>Any programming job will probably require that you use some source control. There are still a lot of companies on older SCCS’ (Source Code Control Systems), but Git is trending up and is here to stay if you ask me. If you can learn Git, you can learn another SCCS system if needed.</p>
<h3 id="learn-a-server-side-language">Learn a server-side language</h3>
<p>It is tricky to recommend a single language. So check out a few and pick whatever feels right:</p>
<ul>
<li>Python</li>
<li>Ruby</li>
<li>C#</li>
<li>PHP</li>
</ul>
<h3 id="learn-about-databases-and-sql">Learn about databases and SQL.</h3>
<p>Every interesting app or website is driven by a database. Databases store information. SQL let’s you store and retrieve information from the database.</p>
<p>If you picked this language above:</p>
<ul>
<li>PHP - Ususally coupled with MySQL. Most cheap hosting accounts come with both pre-installed and the PHPMyAdmin tool.</li>
<li>C# - Usually coupled with SQL Server.</li>
<li>Python/Ruby - Ask around, I don’t know!</li>
</ul>
<h3 id="dont-stop-learning">Don’t stop learning</h3>
<p>The more you know the more efficient you can be.</p>
<h3 id="if-something-feels-harder-than-it-should-be-it-probably-is">If something feels harder than it should be, it probably is</h3>
<p>I’ve seen people waste tons of time doing something the hard way. If they just took a few minutes to Google for a better solution, they would probably find one and save a ton of time.</p>
<h2 id="closing-thoughts">Closing thoughts</h2>
<p>I would love to hear feedback about what people think about this article since it is a little different from my typical how-to post.</p>
Programmatically Add a Tab to the Kentico UI2014-01-13T12:00:00+00:00http://johnnycode.com/2014/01/13/programmatically-add-a-tab-to-the-kentico-ui<p><em>First post in 2014! Woohoo!</em></p>
<p>Adding tabs to Kentico’s CMS Desk and Site Manager is pretty easy. The Modules UI let’s you do just that. However, there are 2 important limitations here:</p>
<ol>
<li>Not all areas of the CMS Desk/CMS Site Manager support adding tabs through the Modules UI.</li>
<li>Building a custom module that can be exported/imported is not as easy when using the Modules UI.</li>
</ol>
<p>There must be another way!</p>
<p>Enter Kentico event handlers…</p>
<h2 id="background">Background</h2>
<p>Before I get into the details of solving a specific problem, let me a give a quick overview of Kentico Modules and Event Handlers.</p>
<p>Kentico contains global events that fire for almost any situation. You can register custom event handlers to take action when a given event takes place. For a complete reference of available events, refer to the <a href="http://devnet.kentico.com/docs/7_0/devguide/index.html?event_handlers_overview.htm" title="Handling Global Events">Global Events documentation</a>.</p>
<p>The definition of a <a href="http://devnet.kentico.com/docs/7_0/devguide/index.html?custom_modules.htm" title="Developing custom modules">Kentico Module</a> is pretty loose, but here are a few important facts. If you create a custom module in the CMS Site Manager, it will allow you to easily export (and subsequently import) the related code. Exporting a module will include code from:</p>
<ul>
<li>~/App_Code/CMSModules/[Module Code Name]</li>
<li>~/CMSModules/[Module Code Name]</li>
</ul>
<p>Now that we know <strong>what to code</strong> and <strong>where to put it</strong>, we can actually <strong>get this done</strong>!</p>
<h2 id="the-problem">The Problem</h2>
<p>Let’s say that we want to be able to add a tab to the BizForm interface. If you look at the BizForm module in the CMS Site Manager, you can see that they don’t define the tabs within the UI. They’re actually hard-coded in an .aspx file! What’s a dev to do???</p>
<h2 id="the-solution">The Solution</h2>
<p>But wait! It turns out that most (if not all) of the admin pages in Kentico inherit from the CMSPage class, and there are global events associated with that class! So we should be able to handle an event that will allow us to inject a tab into the UI!</p>
<p><em>Note: Refer to the <a href="http://devnet.kentico.com/docs/7_0/devguide/index.html?event_handlers_overview.htm" title="Handling Global Events">documentation on handling custom events</a> if you have any issues getting the event handlers registered. I do include complete sample code below, but refer to the documentation for a complete explanation of what it all means.</em></p>
<p>First, we’ll create a class that will register/handle the events:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/App_Code/CMSModules/MyCustomModule/MyCustomModuleLoader.cs
</code></pre></div></div>
<p>Add the custom event handler for when a page of type <code class="language-plaintext highlighter-rouge">CMSPage</code> loads:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public override void Init()
{
CMSPage.OnAfterPageLoad += CMSPage_OnAfterPageLoad;
}
</code></pre></div></div>
<p>And then add the tab if our criteria is met:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected void CMSPage_OnAfterPageLoad(object sender, EventArgs e)
{
var cmsPage = (CMSPage)sender;
var formId = HttpContext.Current.Request.QueryString["FormID"];
var cmsBizFormPage = cmsPage as CMSBizFormPage;
if (cmsBizFormPage != null)
{
if (cmsBizFormPage.PersistentEditedObject is BizFormInfo)
{
cmsPage.SetTab(int.MaxValue - 1, "My Custom Tab", cmsPage.ResolveUrl("~/CMSModules/MyCustomModule/Tools/MyCustomTab.aspx?formid=" + formId), "SetHelpTopic('helpTopic', 'general_tab');");
}
}
}
</code></pre></div></div>
<p>In the above code we check if the page is a more specifically a <code class="language-plaintext highlighter-rouge">CMSBizFormPage</code>, and that the <code class="language-plaintext highlighter-rouge">PersistentEditedObject</code> is in fact a <code class="language-plaintext highlighter-rouge">BizFormInfo</code> object. You can use whatever criteria you want, or even do it globally (although that probably isn’t a good idea)!</p>
<p>And here is the complete code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System;
using System.Web;
using CMS.FormEngine;
using CMS.SettingsProvider;
using CMS.UIControls;
[CustomPageEvents]
public partial class CMSModuleLoader
{
/// <summary>
/// Attribute class that ensures the loading of custom handlers
/// </summary>
private class CustomPageEventsAttribute : CMSLoaderAttribute
{
/// <summary>
/// Called automatically when the application starts
/// </summary>
public override void Init()
{
// Assigns custom handlers to the appropriate events
CMSPage.OnAfterPageLoad += CMSPage_OnAfterPageLoad;
}
protected void CMSPage_OnAfterPageLoad(object sender, EventArgs e)
{
var cmsPage = (CMSPage)sender;
var formId = HttpContext.Current.Request.QueryString["FormID"];
var cmsBizFormPage = cmsPage as CMSBizFormPage;
if (cmsBizFormPage != null)
{
if (cmsBizFormPage.PersistentEditedObject is BizFormInfo)
{
cmsPage.SetTab(int.MaxValue - 1, "My Custom Tab", cmsPage.ResolveUrl("~/CMSModules/MyCustomModule/Tools/MyCustomTab.aspx?formid=" + formId), "SetHelpTopic('helpTopic', 'general_tab');");
}
}
}
}
}
</code></pre></div></div>
<h2 id="exporting-the-custom-module">Exporting the Custom Module</h2>
<p>If you want to be able to export and import this piece of functionality as a real live bone-fide custom module, all you need to do is “create” a custom module in the CMS Site Manager. Go to CMS Site Manager > Development > Modules and create a new module there. Just make sure that the code name of the module matches the folder names you might have in <code class="language-plaintext highlighter-rouge">~/App_Code/CMSModules/</code> and <code class="language-plaintext highlighter-rouge">~/CMSModules/</code>. Then you can export your custom module from the dropdown menu next to it in the grid:</p>
<p><img src="/assets/images/2014-01-13-programmatically-add-a-tab-to-the-kentico-ui/exporting-a-custom-module.png" alt="Exporting a Custom Module" /></p>
<p>That’s it!</p>
Using Macros Inside Dropdown List Fields in Kentico CMS2013-11-13T12:00:00+00:00http://johnnycode.com/2013/11/13/using-macros-inside-dropdown-list-fields-in-kentico-cms<p>Macros make Kentico a really flexible and powerful CMS. They are supported almost everywhere in the CMS. <em>Almost</em>…</p>
<h2 id="the-problem">The Problem</h2>
<p>I was trying to create a dropdown list field that would be dependent on another field in the same document. There are the <a href="/2013/10/12/using-dependent-fields-in-kentico/" title="Using Dependent Fields in Kentico CMS">dependent field properties for enabling or hiding the field</a>, but I needed to affect the data that was loaded. I had my dropdown set to use a SQL command to retrieve its values, but the data source property wasn’t rendering my macro. Googling around, I found some articles suggesting that they might work, but only inside the User form:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/15783025/cascading-dropdown-list-for-custom-field-in-kentico-cms">http://stackoverflow.com/questions/15783025/cascading-dropdown-list-for-custom-field-in-kentico-cms</a></li>
<li><a href="http://stackoverflow.com/questions/18470411/kentico-custom-field-items-based-on-selected-user">http://stackoverflow.com/questions/18470411/kentico-custom-field-items-based-on-selected-user</a></li>
</ul>
<p>I also found some user voice requests that indicate that support for this feature is coming in v8, but v8 isn’t out yet and I need this now! So what’s a dev to do?</p>
<h2 id="the-solution">The Solution</h2>
<p>Why not just <strong><em>add</em></strong> macro support!? We’ll need to customize Kentico’s code, but it should be easy to do and easy to spot/handle during an hotfix/upgrade conflict.</p>
<p>In <code class="language-plaintext highlighter-rouge">CMSFormControls/Basic/DropDownListControl.ascx.cs</code>, add the following using directive to the top of the code file:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using CMS.CMSHelper;
</code></pre></div></div>
<p>After the <code class="language-plaintext highlighter-rouge">Page_Load</code> method, around line 296, add a <code class="language-plaintext highlighter-rouge">OnPreRender</code> event handler to force the list to load the values when a field may have changed:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (IsPostBack && DependsOnAnotherField)
{
dropDownList.Items.Clear();
LoadAndSelectList();
}
}
</code></pre></div></div>
<p>And around line 336, add the following code to the LoadAndSelectList() method to add macro handling support to the data source property for the SQL query:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Add macro parameters for the current value of each field
var replacements = new object[Form.FieldEditingControls.Count, 2];
var i = 0;
foreach (EditingFormControl field in Form.FieldEditingControls.Values)
{
replacements[i, 0] = field.FieldInfo.Name;
replacements[i, 1] = field.Value;
i++;
}
CMSContext.CurrentResolver.SourceParameters = replacements;
query = CMSContext.CurrentResolver.ResolveMacros(query);
</code></pre></div></div>
<p>The resulting method should look something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/// <summary>
/// Loads and selects control.
/// </summary>
private void LoadAndSelectList()
{
if (dropDownList.Items.Count == 0)
{
string options = ValidationHelper.GetString(GetValue("options"), null);
string query = ValidationHelper.GetString(GetValue("query"), null);
// Add macro parameters for the current value of each field
var replacements = new object[Form.FieldEditingControls.Count, 2];
var i = 0;
foreach (EditingFormControl field in Form.FieldEditingControls.Values)
{
replacements[i, 0] = field.FieldInfo.Name;
replacements[i, 1] = field.Value;
i++;
}
CMSContext.CurrentResolver.SourceParameters = replacements;
query = CMSContext.CurrentResolver.ResolveMacros(query);
try
{
FormHelper.LoadItemsIntoList(options, query, dropDownList.Items, FieldInfo);
}
catch (Exception ex)
{
DisplayException(ex);
}
FormHelper.SelectSingleValue(selectedValue, dropDownList);
}
}
</code></pre></div></div>
<h2 id="an-example">An Example</h2>
<p>The code that we added simply adds all the fields’ current values as macros, given the field name. Now we can reference other fields in the data source property with a SQL query like this one:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SELECT ChildId, ChildName
FROM customtable_Children
WHERE ParentID = {% ParentId #%}
UNION ALL
SELECT 0, ''
ORDER BY ChildName
</code></pre></div></div>
<p>In the above example there would be a dropdown setup to list parents. After the parent is selected, the children of that parent would load in the second dropdown. You should also set the dependent field settings to postback on change of the parents, and possibly show/hide the child dropdown as needed.</p>
<p>And that’s it! Let me know if this helped or if you find a better way!</p>
The Differences Between HTML Form Content Types (enctype)2013-10-30T12:00:00+00:00http://johnnycode.com/2013/10/30/the-differences-between-html-form-content-types-enctype<p>You’ve probably seen it before. The <code class="language-plaintext highlighter-rouge">enctype</code> attribute of an HTML Form element. But what does it mean?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><form method="post" enctype="application/x-www-form-urlencoded">
...
</form>
</code></pre></div></div>
<p>At least form me, I almost never need to worry about what the content type is for a form. I use ASP.NET most of the time so this is automatically handled for me. But what if you’re not using a framework that handles this for you, or you’re rolling your own, or you need to post data to another system? Let’s see how changing the content type affects the POST.</p>
<p>You can change the content type to one of the following, per the <a href="http://www.w3.org/TR/html5/forms.html#attr-fs-enctype" title="Forms in HTML5 Documents">W3C HTML5 Form spec</a>:</p>
<ul>
<li>application/x-www-form-urlencoded</li>
<li>multipart/form-data</li>
<li>text/plain</li>
</ul>
<h2 id="how-do-we-test">How do we test?</h2>
<h3 id="browser-dev-tools">Browser Dev Tools</h3>
<p>First off, how do we see the differences? You can use the <a href="https://developers.google.com/chrome-developer-tools/" title="Chrome DevTools">Chrome DevTools</a>, or <a href="https://getfirebug.com/" title="Firebug. Web Development Evolved.">Firebug</a> in Firefox, or probably the IE dev tools. WIth those tools there should be a way to view the requests that your browser makes. Here is an example of the “Net” tab in Firefox:</p>
<p><img src="/assets/posts/2013-10-30-form-content-type-differences-enctype/firebug-net-tab.png" alt="A screenshot of the Firebug Net Tab." /></p>
<p>With the net tab open, you can click on any request and view the details about the request. You can see things like the Headers that were sent, the response, cookies that we passed, etc. Now that we know where to look, we can see what the differences are in the form content types.</p>
<p><em>Pro tip: Enable the persist button to track requests across multiple page loads. The list will get really long, but it will allow you to more easily compare multiple requests.</em></p>
<p><em>Pro Pro tip: I’ve never done this, but I believe that some of the dev tools will export the data listed in the Net tabs to a generic format. That data can be reloaded at a later time, or maybe used in some other way (diff tool?). Again, I’ve never used it but it may be helpful for extreme cases.</em></p>
<h3 id="proxies">Proxies</h3>
<p>While I didn’t really use them in creating this post, there are 2 powerful debugging proxies:</p>
<ul>
<li><a href="http://fiddler2.com/" title="The free web debugging proxy for any browser, system or platform">Fiddler</a></li>
<li><a href="http://www.charlesproxy.com/" title="Charles is an HTTP proxy / HTTP monitor / Reverse Proxy that enables a developer to view all of the HTTP and SSL / HTTPS traffic between their machine and the Internet.">Charles</a></li>
</ul>
<p>Proxies hook into your system at a lower level to potentially capture <em>any</em> HTTP traffic on your system. This can be really helpful in seeing requests across multiple browsers and other apps all in one place.</p>
<h3 id="test-form">Test Form</h3>
<p>Here is a little <a href="/assets/posts/2013-10-30-form-content-type-differences-enctype/form-content-type-tester.html" title="HTML Form Content Type Tester (enctype)">HTML form content type test page</a> I’ve created that is setup with the different content types. It should be pretty self explanatory.</p>
<h2 id="test-results">Test Results</h2>
<p>Universally, when the content type is set for a form, that content type is passed as a header in the request:</p>
<p><img src="/assets/posts/2013-10-30-form-content-type-differences-enctype/firebug-request-details-content-type.png" alt="A request's details showing the content type" /></p>
<p>Also, if you look at the Post Tab you will see how the data is encoded for the request:</p>
<p><img src="/assets/posts/2013-10-30-form-content-type-differences-enctype/firebug-net-tab-post-data.png" alt="A request's details showing the post data" /></p>
<p>Here is the full post data for each content type:</p>
<p><strong>application/x-www-form-urlencoded (default):</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>test_field_1=Test&amp;test_field_2=%21%40%23%24%25%5E%26*%28%29_%2B-%3D
</code></pre></div></div>
<p><strong>text/plain:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>test_field_1=Test
test_field_2=!@#$%^&*()_+-=
</code></pre></div></div>
<p><strong>multipart/form-data:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>test_field_1=Test&amp;test_field_2=%21%40%23%24%25%5E%26*%28%29_%2B-%3D
-----------------------------21204402826745
Content-Disposition: form-data; name=&quot;test_field_1&quot;
Test
-----------------------------21204402826745
Content-Disposition: form-data; name=&quot;test_field_2&quot;
!@#$%^&amp;*()_+-=
-----------------------------21204402826745--
</code></pre></div></div>
<p>As you can see above, the content type setting can have a drastic difference in how the data is contained in the request, and subsequently, how the server/framework/app on the other end needs to interpret it.</p>
<h2 id="so-when-is-this-actually-important">So when is this actually important?</h2>
<p><strong>TL;DR: PayPal and possibly other 3rd party services may expect a specific content type of an HTML Form POST.</strong></p>
<p>As I mentioned earlier, this rarely comes up for me. However, this week I’m working on a PayPal integration and this was <em>very</em> important. In fact, if the content type was wrong on the form that posted payment information to PayPal a generic error would be thrown. This took me a while to track down since a regular HTML form worked fine, but when an ASP.NET form was pointed at the PayPal endpoint it break. This led to a <strong>lot</strong> of double-checking of code and values and testing with different parameters.</p>
<p>Eventually it came down to the fact that the form data was identical, but the posts were still giving different results. That’s when I remembered that ASP.NET typically works by having “one form to rule them all” on the page, and JavaScript is used to handle form posts (not AJAX, but JS code is triggered on submit). At that point I started looking at the details of the Net tab in Firefox, and that’s when I noticed the differences in Content Type! In my case the ASP.NET form was using the <code class="language-plaintext highlighter-rouge">multipart/form-data</code> content type, which PayPal was not cool with.</p>
Using Dependent Fields in Kentico CMS2013-10-12T12:00:00+00:00http://johnnycode.com/2013/10/12/using-dependent-fields-in-kentico<p>Kentico has a pretty decent macro engine under the hood, and you can use it almost anywhere inside the CMS. A perfect place that macros shine is when you’re working with forms, and you want them to be more dynamic. Clients often ask us to show/hide or enable/disable fields based on the values in other fields. We can accomplish these feats by enabling dependent field options for each form field.</p>
<p>For any form editor, with a field selected, scroll to the bottom of the field’s properties (Make sure you’re in advanced mode). You should see these properties:</p>
<ul>
<li>Visible condition</li>
<li>Enabled condition</li>
<li>Has depending fields</li>
<li>Depends on another field</li>
</ul>
<p><img src="/assets/images/2013-10-12-using-dependent-fields-in-kentico/dependent-field-settings.png" alt="Dependent field settings" /></p>
<p>Enabling “Has depending fields” on a field will cause a postback on the form, which allows other fields to potentially make changes to themselves at that time. For those dependent fields you would enable “Depends on another field”. Additionally, you would set the visible or enabled condition. Also, custom form controls could take other actions as well such as reloading a different set of data.</p>
<h2 id="a-practical-example">A Practical Example</h2>
<p>A prime example where dependent fields can be used is with Country and State values. If you want to capture a user’s country and state you can use the built in Country Selector, however it stores data in a odd way. You either get the string names of the country and state, the country ID, or the state ID. Ideally, I would want the country and state ID’s both as integers but I’m not sure why that’s not an option.</p>
<p>Let’s say that you have a Contact Us form built with a BizForm, and you want your customers to provide their country and state. To do this ourselves, we’ll make 2 drop down fields, and “link” them up using dependent field options.</p>
<p>First, create the Country drop down and set the following properties:</p>
<ul>
<li>Column Name: <strong>Country</strong></li>
<li>Attribute Type: <strong>Integer</strong></li>
<li>Field Caption: <strong>Country</strong></li>
<li>Data Source: <strong>SQL Query</strong></li>
<li>Has depending fields: <strong>Checked</strong></li>
</ul>
<p>And set the SQL query to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SELECT CountryID, CountryDisplayName
FROM CMS_Country
</code></pre></div></div>
<p>Then create the State drop down and set the following properties</p>
<ul>
<li>Column Name: <strong>State</strong></li>
<li>Attribute Type: <strong>Integer</strong></li>
<li>Field Caption: <strong>State</strong></li>
<li>Data Source: <strong>SQL Query</strong></li>
<li>Depends on another field: <strong>Checked</strong></li>
<li>Visible condition: <strong>Country.Value == 271</strong></li>
</ul>
<p>And set the SQL query to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SELECT StateID, StateDisplayName
FROM CMS_State
</code></pre></div></div>
<p>Now, when the form initially loads, the state drop down will be hidden. When the user selects a country, you should see the page flicker as it posts back. If the user selects the country with ID 271, USA, the state drop down will appear.</p>
<p>So why do we have to do <code class="language-plaintext highlighter-rouge">Country.Value</code>, and not just <code class="language-plaintext highlighter-rouge">Country</code>? A colleague of mine, Ben, pointed this out to me. <code class="language-plaintext highlighter-rouge">Country</code> is actually a reference to the field, and not directly to the value. There are other properties on that field you can reference such as that fields visible or enabled status.</p>
<h2 id="the-macro-editors">The Macro Editors</h2>
<p>To better develop macros for those conditional fields, you can bring up the macro editors to help you out. If you click the pencil next to the visible or enabled condition fields, it will pop up the editors. There are 3 tabs:</p>
<ul>
<li>Rule Designer</li>
<li>Designer</li>
<li>Code</li>
</ul>
<h3 id="the-rule-designer">The Rule Designer</h3>
<p>The rule designer tries to provide you with common scenarios that you might need and presents them as text with placeholders. I didn’t know about this until recently, and it seems like a pretty cool feature that caters to non-developers.</p>
<p><img src="/assets/images/2013-10-12-using-dependent-fields-in-kentico/macro-editor-rule-designer.png" alt="Dependent field settings" /></p>
<h3 id="designer">Designer</h3>
<p>The designer is a little more developer oriented, but still tries to hold your hand a bit. It allows you to select left hand value along with an operator (which may require a right hand value). Then you can add additional rules and re-order as you see fit.</p>
<p><img src="/assets/images/2013-10-12-using-dependent-fields-in-kentico/macro-editor-designer.png" alt="Dependent field settings" /></p>
<h3 id="code">Code</h3>
<p>The code editor is just the plain-jane editor with some intellisense support. If you’re a seasoned Kentico Macro user and you know what you’re doing, this is probably the way to go.</p>
<p><img src="/assets/images/2013-10-12-using-dependent-fields-in-kentico/macro-editor-code.png" alt="Dependent field settings" /></p>
<p>There you have it! Hope this helps someone!</p>
Using C# And SqlBulkCopy To Import CSV Data Into SQL Server2013-08-19T12:00:00+00:00http://johnnycode.com/2013/08/19/using-c-sharp-sqlbulkcopy-to-import-csv-data-sql-server<p>I’ve written a lot of imports in my day, but they’re always painful. Recently though, I think I’ve found a pretty good solution for programmatically getting data straight into SQL Server, <strong><em>fast</em></strong>. This isn’t that helpful if you need to use an API, but it’s great if you can do direct inserts.</p>
<p>Here are the tools I use to import the data:</p>
<ul>
<li>C#</li>
<li>The <code class="language-plaintext highlighter-rouge">Microsoft.VisualBasic.FileIO.TextFieldParser</code> class (yes, you can use it from C#)</li>
<li>The <code class="language-plaintext highlighter-rouge">System.Data.SqlClient.SqlBulkCopy</code> class</li>
</ul>
<p>Here are some unscientific benchmarks I did importing data into a Kentico CMS install, but this should work with any SQL Server DB:</p>
<p>Importing 4.6 million rows of IP lookup data (with 6 columns)…</p>
<ul>
<li><strong>21 hours</strong> - Kentico CMS API</li>
<li><strong>1 hour</strong> - SQL Inserts into live table</li>
<li><strong>3 minutes</strong> - SqlBulkCopy into temp table, then INSERT INTO live table</li>
<li><strong>2 minutes</strong> - SqlBulkCopy into live table, using ColumnMappings to skip PK</li>
</ul>
<p>Pretty big difference! First, I tried to use the API to get the data in, because that’s the recommended way. Well, it turns out it wasn’t feasible given the amount of data, and the data is simply going into a Custom Table so the API isn’t super important.</p>
<p>Then I tried doing straight SQL insert statements. This was <em>much</em> better, but still took <em>way</em> too long.</p>
<p>Finally I came across SQL Bulk Copy. I first tried to use the command line version, but then discovered the .NET class! I had some trouble getting the config file right for the command line version, but the .NET class also makes more sense in the context of a Kentico website. It couldn’t be easier to use, and I was loading the data into a temp table, then using the <code class="language-plaintext highlighter-rouge">INSERT INTO</code> syntax to put the data into the live table. <em>Then</em> I realized that I could simply setup the column mappings and skip the temp table altogether!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using Microsoft.VisualBasic.FileIO;
public class CsvBulkCopyDataIntoSqlServer
{
protected const string _truncateLiveTableCommandText = @"TRUNCATE TABLE YourTableName";
protected const int _batchSize = 100000;
public void LoadCsvDataIntoSqlServer()
{
// This should be the full path
var fileName = @"C:\Path\To\File.csv";
var createdCount = 0;
using (var textFieldParser = new TextFieldParser(fileName))
{
textFieldParser.TextFieldType = FieldType.Delimited;
textFieldParser.Delimiters = new[] { "," };
textFieldParser.HasFieldsEnclosedInQuotes = true;
var connectionString = ConfigurationManager.ConnectionStrings["CMSConnectionString"].ConnectionString;
var dataTable = new DataTable("YourTableName");
// Add the columns in the temp table
dataTable.Columns.Add("FirstName");
dataTable.Columns.Add("LastName");
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
// Truncate the live table
using (var sqlCommand = new SqlCommand(_truncateLiveTableCommandText, sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
// Create the bulk copy object
var sqlBulkCopy = new SqlBulkCopy(sqlConnection)
{
DestinationTableName = "YourTableName"
};
// Setup the column mappings, anything ommitted is skipped
sqlBulkCopy.ColumnMappings.Add("FirstName", "FirstName");
sqlBulkCopy.ColumnMappings.Add("LastName", "LastName");
// Loop through the CSV and load each set of 100,000 records into a DataTable
// Then send it to the LiveTable
while (!textFieldParser.EndOfData)
{
dataTable.Rows.Add(textFieldParser.ReadFields());
createdCount++;
if (createdCount % _batchSize == 0)
{
InsertDataTable(sqlBulkCopy, sqlConnection, dataTable);
break;
}
}
// Don't forget to send the last batch under 100,000
InsertDataTable(sqlBulkCopy, sqlConnection, dataTable);
sqlConnection.Close();
}
}
}
protected void InsertDataTable(SqlBulkCopy sqlBulkCopy, SqlConnection sqlConnection, DataTable dataTable)
{
sqlBulkCopy.WriteToServer(dataTable);
dataTable.Rows.Clear();
}
}
</code></pre></div></div>
<p>It’s that easy! You may need to adjust the <code class="language-plaintext highlighter-rouge">_batchSize</code> if you’re importing data with more columns, otherwise loading 100,000 records into RAM might crush your machine.</p>
Using Custom Settings from a Macro in Kentico CMS2013-08-13T12:00:00+00:00http://johnnycode.com/2013/08/13/using-custom-settings-from-a-macro-in-kentico-cms<p>Custom settings have been around since 6.0. Before that, I had actually developed a <a href="http://johnnycode.com/2010/07/08/introducing-the-custom-settings-module-for-kentico-cms/" title="Introducing the Custom Settings Module for Kentico CMS">Custom Settings Module</a> leveraging Kentico’s API’s, but it wasn’t well tested, and let’s face it, it wasn’t built in. While it’s not a monumental technical feat and doesn’t get much attention, having Custom Settings built in really improves on the already flexible framework. Previously, potentially configurable values were hard coded or stored in the web.config. Try telling a customer that they need to open the web.config to make a simple change! Not ideal.</p>
<p>Now we can simply define custom settings in Kentico that work exactly like the built in settings. They can be utilized from web parts, modules, events, macros, or almost any other area of the application.</p>
<p><em>One area that I know does <strong>not</strong> support <strong>any</strong> type of macro are some of the form field settings, like the data source text area for a drop down list type.</em></p>
<h2 id="creating-a-custom-setting">Creating a Custom Setting</h2>
<p>To create your Custom Settings, go to <code class="language-plaintext highlighter-rouge">Site Manager > Development > Custom Settings</code> and add a new category. I named mine “Form Field Defaults’, name yours whatever you want.</p>
<p><em>Note that the category name doesn’t matter when referencing the macro. It’s just for organization.</em></p>
<p>Create a new settings group. I named mine “General”.</p>
<p>Now you’re ready to add your actual setting. Add a new settings key. I named mine “Use Default” with a code name of “UseDefault”. I set it to be a bool, with everything else as default.</p>
<p>Now you should see something like this:</p>
<p><img src="/assets/images/2013-08-13-using-custom-settings-from-a-macro-in-kentico-cms/creating-the-custom-setting.png" alt="Creating the custom setting" /></p>
<p>Now under <code class="language-plaintext highlighter-rouge">Site Manager > Settings</code> you can set the value of your Custom Setting globally and for each site.</p>
<h2 id="using-the-custom-setting">Using the Custom Setting</h2>
<p>After setting appropriate values, you can access the Custom Setting through a macro like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{%Settings.CustomSettings.General.UseDefault#%}
</code></pre></div></div>
<p>As mentioned above, the setting category isn’t actually used. Not sure why it works this way, and why the macro intellisense doesn’t really give you what you need, but whatever, this is what works.</p>
<p>Now that you can access your custom setting, you can use it in things like conditionals. So if you have a Biz Form or Document Type that is shared across sites, you could, for example, set default values per site:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{%if(Settings.CustomSettings.General.UseDefault == "True") { "Default 1" } else { "Default 2" }#%}
</code></pre></div></div>
<p>That’s it!</p>
Fixing Assembly Binding Redirect Issues2013-07-19T12:00:00+00:00http://johnnycode.com/2013/07/19/fixing-assembly-binding-redirect-errors<p>This post is really a compilation of things I’ve found online, mostly from <a href="http://stackoverflow.com">Stack Overflow</a>.</p>
<h2 id="what-does-a-healthy-assembly-binding-redirect-look-like">What does a healthy assembly binding redirect look like?</h2>
<p>First, let’s take a look at a good configuration, with the complete web.config structure (omitting other sections):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="CMS.ExtendedControls" publicKeyToken="834b12a258f213f9" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.4940.41825" newVersion="7.0.4940.41825" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
</code></pre></div></div>
<p>Notice that I am specifying the assembly name, publicKeyToken, and culture. Also, the oldVersion attribute on the redirect itself covers ALL versions, <strong><em>including the one we’re redirecting to</em></strong>. I don’t know if that is a requirement, but it certainly works.</p>
<h2 id="do-a-sanity-check">Do a sanity check</h2>
<p>Grab a coworker and make sure that everything is correct. Check the assembly name, the public key token, the version numbers, hell, check that you’re running the right project! TRIPLE CHECK EVERYTHING. Think back… how many times have you had issues where the cause was a 1 character mistake? It never hurts to check again.</p>
<h2 id="check-the-specificversion-property-on-your-references">Check the SpecificVersion property on your references</h2>
<p>I’m not 100% on this one, but I think I remember seeing somewhere that you need to set your references to NOT require a specific version.</p>
<p><img src="/assets/images/2013-07-19-fixing-assembly-binding-redirect-errors/setting-specific-version-property-to-false.png" alt="Setting the specific version property to false" /></p>
<h2 id="check-the-namespace-on-the-assemblybinding-element">Check the Namespace on the assemblyBinding element</h2>
<p>As mentioned in <a href="http://stackoverflow.com/questions/3490327/assembly-binding-redirect-does-not-work" title="Assembly binding redirect does not work">this question</a>, it sounds like people have manually typed in the namespace on the <code class="language-plaintext highlighter-rouge">assemblyBinding</code> element and have incorrectly used an <code class="language-plaintext highlighter-rouge">=</code> instead of a <code class="language-plaintext highlighter-rouge">-</code>.</p>
<p>Incorrect:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><runtime>
<assemblyBinding xmlns="urn:schemas=microsoft-com:asm.v1">
...
</code></pre></div></div>
<p>Correct (dash, not equals):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
...
</code></pre></div></div>
<h2 id="check-the-namespace-on-the-configuration-element">Check the Namespace on the configuration Element</h2>
<p>In one case, none of the above methods worked for me. Apparently, the namespace on the configuration element can affect how the redirects work. The asker in <a href="http://stackoverflow.com/questions/1543132/why-is-assembly-binding-redirect-not-working-in-my-web-site" title="Why is assembly binding redirect not working in my web site?">this question</a> mentioned removing the namspace attribute (although it didn’t fix his situation). This is what the first 3 lines of my web.config looked:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<configSections>
</code></pre></div></div>
<p>After removing the namespace from the configuration element, all was well:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><?xml version="1.0"?>
<configuration>
<configSections>
</code></pre></div></div>
<h2 id="if-all-else-fails">If all else fails</h2>
<p>It looks like there is a <a href="http://blogs.msdn.com/b/ianhu/archive/2006/07/12/663834.aspx" title="Fuslogvw.exe and diagnosing .NET assembly binding issues">utility to help debug assembly binding redirects</a>. I have never had to resort to this, so I can’t say how well it works. Here’s hoping you don’t have to use it either.</p>
Using the Kentico API to generate a code name for your object2013-07-18T12:00:00+00:00http://johnnycode.com/2013/07/18/using-the-kentico-api-to-generate-code-names<p>There may come a time when you find yourself creating new object in Kentico via the API. You may need to generate a code name. I’ve dug through some of the internal processes and assemblies and found the following methods:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CMS.GlobalHelper.ValidationHelper.GetIdentifier(object name)
CMS.GlobalHelper.ValidationHelper.GetCodeName(object name)
</code></pre></div></div>
<p>Let’s talk briefly about these.</p>
<h2 id="getidentifier">GetIdentifier</h2>
<p>This one is pretty straightforward if you use a reflection tool to examine the assembly and view the code. The first overload of the method actually calls into the second overload, which does a simple Regex removal of all non-alphanumeric characters, along with underscores. The 2nd overload allows you to specify the character used to replace offending characters with. It has the following signature:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string GetLanguage(object lang, string replacement)
</code></pre></div></div>
<h2 id="getcodename">GetCodeName</h2>
<p>This method is significantly more complicated than the last. It features 8 overloads that each feature fewer default values and more parameters than the last. The most complicated overload has the following signature:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string GetCodeName(object name, string replacement, int maxLength, bool useUnicode, bool removeDiacritics, string allowedCharacters, bool useCamelCase)
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>Just remember that these methods do not prevent code name collisions from happening. If you’re worried about that, I think there is a <code class="language-plaintext highlighter-rouge">EnsureUniqueCodeName()</code> method on the <code class="language-plaintext highlighter-rouge">BaseInfo</code> abstract class that I <em>think</em> will take care of that.</p>
Using Strongly Typed Custom Document Type Classes in Kentico CMS2013-07-15T12:00:00+00:00http://johnnycode.com/2013/07/15/using-strongly-typed-custom-document-type-classes<p>Kentico is a great platform for building web apps, but some times the API code doesn’t feel like it’s as good as it could be:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>TreeNode document = treeProvider.Select(...);
var integerValue = ValidationHelper.GetInteger(document.GetValue("Age"), 0);
</code></pre></div></div>
<p>Sure, that works reliably, but using ValidationHelper everywhere along with the string names of the fields isn’t conducive to good programming habits. Why don’t we fix that using a strongly typed class for our custom Document Type. Just grab the boilerplate code from <code class="language-plaintext highlighter-rouge">C:\Program Files (x86)\KenticoCMS\7.0\CodeSamples\App_Code Samples\Samples\Classes</code>, and create property’s for each of the Document Type fields.</p>
<p>Let’s say I had a Person Document Type with:</p>
<ul>
<li>First Name</li>
<li>Last Name</li>
<li>Age</li>
</ul>
<p>The end result of the custom Document Type class looks like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System;
using CMS.DocumentEngine;
/// <summary>
/// Document type registration
/// </summary>
[DocumentType(PersonDocument.CLASS_NAME, typeof(PersonDocument))]
public partial class CMSModuleLoader
{
}
/// <summary>
/// Person document type class, deriving from TreeNode
/// </summary>
public partial class PersonDocument : TreeNode
{
/// <summary>
/// Class name of the item
/// </summary>
public const string CLASS_NAME = "Custom.Person";
public string FirstName
{
get
{
return GetStringValue("FirstName", "");
}
set
{
SetValue("FirstName", value);
}
}
public string LastName
{
get
{
return GetStringValue("LastName", "");
}
set
{
SetValue("LastName", value);
}
}
public int Age
{
get
{
return GetIntegerValue("Age", 0);
}
set
{
SetValue("Age", value);
}
}
public PersonDocument()
: base(CLASS_NAME)
{
}
}
</code></pre></div></div>
<p>And the following is an example of using the Kentico API to retrieve a list of Person documents from the content tree. We select only “Person” documents, and are able to use our custom class to deal with the data in a strongly-typed fashion:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var treeProvider = new TreeProvider();
var documents = treeProvider.SelectNodes(CMSContext.CurrentSiteName, "/%", "en-us", false, "custom.Person");
if (!DataHelper.DataSourceIsEmpty(documents))
{
// Loop through all documents
foreach (PersonDocument person in documents.Items)
{
// Alternatively, if you're dealing with a DataSet you can new up a person from the DataRow
// var person = TreeNode.New<PersonDocument>(documentRow, "custom.Person", treeProvider);
Response.Write(string.Format("{0} {1}", person.FirstName, person.LastName));
}
}
</code></pre></div></div>
<p>The only caveat here is that your custom Document Type needs to match the class you created, otherwise things will break. But that is definitely a risk that is easily mitigated with permissions and educated developers. And if things do need to change, which inevitably they will, Visual Studio and/or ReSharper will help you refactor things with minimal effort.</p>
<h2 id="but-wait-theres-more">But wait, there’s more!</h2>
<p>If you didn’t get nosy already, check out the other files in the samples folder in Kentico’s install directory: <code class="language-plaintext highlighter-rouge">C:\Program Files (x86)\KenticoCMS\7.0\CodeSamples\App_Code Samples\Samples\Classes</code>. Notice how they have samples for Custom Table Items and Bizform Items! They essentially follow the same pattern, but with their respective provider classes. Strongly typed code for everyone!</p>
Create a SQL Server Login and User with limited permissions2013-07-12T12:00:00+00:00http://johnnycode.com/2013/07/12/create-a-sql-server-login-user-with-limited-permissions<p>People always say you shouldn’t use the sa account for your web app, and you shouldn’t! Below is a script to make a login and user for your database with basic CRUD permissions. If your web app is compromised, damage to the database will be limited to just that database, and not to all the databases running in your SQL Server instance. While still bad, the attacker would only be able to mess with your data, and wouldn’t be able to drop/create tables or other nasty things.</p>
<p>Assuming you have a database name “webapp1”, and want a user “philipjfry” with the password “deltabrainwave”:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CREATE LOGIN phillipjfry
WITH PASSWORD = 'deltabrainwave';
USE [webapp1];
GO
CREATE USER phillipjfry FOR LOGIN phillipjfry
WITH DEFAULT_SCHEMA = dbo;
GRANT INSERT TO webapp1;
GRANT SELECT TO webapp1;
GRANT UPDATE TO webapp1;
GRANT DELETE TO webapp1;
GO
</code></pre></div></div>
Encrypting sections of an ASP.NET web.config2013-06-26T12:00:00+00:00http://johnnycode.com/2013/06/26/encrypting-sections-of-an-asp-net-web-config<p>This article is mostly for my own purposes, but maybe it will help someone complete the encryption process without getting a headache. <a href="http://msdn.microsoft.com/en-us/library/zhhddkxy.aspx" title="Walkthrough: Encrypting Configuration Information Using Protected Configuration">The original steps are located here on the MSDN</a>, but this is an abbreviated version with an important note.</p>
<h3 id="granting-read-access-to-an-rsa-encryption-key">Granting Read Access to an RSA Encryption Key</h3>
<p>Go to the appropriate framework directory for the ASP.NET files:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
</code></pre></div></div>
<p>From here we can grant read access to an RSA encryption key by running this command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.\aspnet_regiis.exe -pa "NetFrameworkConfigurationKey" "IIS APPPOOL\MySite"
</code></pre></div></div>
<p>“IIS APPPOOL\MySite” is the identity that my App Pool runs under. If you don’t know what yours is, create an <code class="language-plaintext highlighter-rouge">.aspx</code> file in your website with the following content:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><%@ Page Language="C#" %>
<%
Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
%>
</code></pre></div></div>
<h3 id="encrypting-sections-of-the-webconfig-file">Encrypting Sections of the Web.config File</h3>
<p>At this point, we are ready to run the command that will actually encrypt the web.config. <strong>MAKE SURE THAT YOU HAVE A BACKUP OF ALL THE DATA STORED IN THE SECTION YOU ARE ABOUT THE ENCRYPT</strong>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.\aspnet_regiis.exe -pe "connectionStrings" -app "/MySite"
</code></pre></div></div>
<p>If all went well, you should see</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Microsoft (R) ASP.NET RegIIS version 4.0.30319.17929
Administration utility to install and uninstall ASP.NET on the local machine.
Copyright (C) Microsoft Corporation. All rights reserved.
Encrypting configuration section...
Succeeded!
</code></pre></div></div>
<p>but…</p>
<h3 id="it-didnt-work">It Didn’t Work!!!</h3>
<p>If you setup your system like me, you may have encountered output containing a stupid error message like this one:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Microsoft (R) ASP.NET RegIIS version 4.0.30319.17929
Administration utility to install and uninstall ASP.NET on the local machine.
Copyright (C) Microsoft Corporation. All rights reserved.
Encrypting configuration section...
A configuration file cannot be created for the requested Configuration object.
Failed!
</code></pre></div></div>
<p><a href="http://forums.asp.net/t/1753876.aspx/1" title="encrypting a webconfig file error">b471code3 from the ASP.NET forums</a> hit the nail on the head with the answer:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"I'm assuming you already checked this out but what I'd pay special attention to is the -site option. If the app's web.config you are trying to encrypt is not under the DefaultWebSite or you have deleted and recreated the DefaultWebSite, the -site option will need to be specified.
For example, when IIS is installed, a Web site named "Default Web Site" is created as site 1. In pages served from that site, the INSTANCE_META_PATH server variable returns "/LM/W3SVC/1". If you do not specify a -site option, site 1 is used."
</code></pre></div></div>
<p>But how do we get the site’s <code class="language-plaintext highlighter-rouge">INSTANCE_META_PATH</code>? <a href="http://weblogs.asp.net/owscott/archive/2010/03/09/viewing-all-server-variables-for-a-site.aspx" title="Viewing all Server Variables for a Site">Scott Forsynth tells you how to get the INSTANCE_META_PATH on his blog</a>. Just make another <code class="language-plaintext highlighter-rouge">.aspx</code> file in your site with the following content:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><%@ Page Language="C#" %>
<%
foreach (string var in Request.ServerVariables)
{
Response.Write(var + " " + Request[var] + "<br>");
}
%>
</code></pre></div></div>
<p>That will dump all the server variables to the page, in which you will find something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>INSTANCE_META_PATH /LM/W3SVC/3
</code></pre></div></div>
<p>The number on the end is the site ID (It also looks like the <code class="language-plaintext highlighter-rouge">INSTANCE_ID</code> variable has just the site ID, but I’m not 100% sure if that is reliable). Take that and incorporate it into the encryption command. This is what the correct command looks like:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.\aspnet_regiis.exe -pe "connectionStrings" -app "/" -site "3"
</code></pre></div></div>
<p>Note that I replace the application name with just a forward slash. If you do run an application inside your IIS site, you will need to include that. Personally, I don’t normally do that, mainly to avoid issues with <a href="http://stackoverflow.com/questions/782252/avoid-web-config-inheritance-in-child-web-application-using-inheritinchildapplic" title="Avoid web.config inheritance in child web application using inheritInChildApplications">configuration inheritance</a>.</p>
<p>And then you will have a super secret web.config section!</p>
Programmatically Logging In a User in Kentico2013-06-11T12:00:00+00:00http://johnnycode.com/2013/06/11/programmatically-logging-in-a-user-in-kentico<p>You’re using <a href="http://www.kentico.com" title="Kentico CMS">Kentico CMS</a> and you need to log someone in. Maybe you’re doing a custom registration form, or an OAuth integration. Whatever the case, it’s super easy. You simply call the <code class="language-plaintext highlighter-rouge">AuthenticateUser</code> static method on the <code class="language-plaintext highlighter-rouge">CMSContext</code> class. Here is the method signature:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static void AuthenticateUser(string userName, bool createPresistentCookie);
</code></pre></div></div>
<p>And this is how you would call it:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CMSContext.AuthenticateUser("my username", true);
</code></pre></div></div>
<p>Piece of cake!</p>
Joining Multiple Document Types in Kentico2013-06-01T12:00:00+00:00http://johnnycode.com/2013/06/01/joining-multiple-document-types-in-kentico<p>A common thing our clients request is that they want the latest news-like documents to show on the homepage. More specifically News, Press Releases, Events, Webinars, etc. This is easy, until you try and combine them all into a single list.</p>
<h2 id="the-problem">The problem</h2>
<p>Let’s say you want to use a Repeater to try and show these documents. That might seem like a good way to go. You can set the repeater to select multiple document types, but what about the transformation? How would you display a custom date field?</p>
<p>Maybe you want a simple Kentico Transformation like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><li><a href="<%# GetDocumentUrl() %>"><%# Eval("Date") %> <%# Eval("DocumentName") %></a></li>
</code></pre></div></div>
<p><em>Note: transformations live on individual Document Types, but nothing is stopping you from using them with other documents types. As long as the field names match between the transformation and the data, it will work.</em></p>
<p>But if you’re selecting News <em>and</em> Press Release documents, the above transformation wont work. Why? Because Kentico will run a SQL query that joins those documents together, but only the CMS_Tree and CMS_Document tables, <em>not the custom document table portion</em>. So that means you will have the core information about the document, <strong>but you wont have access to any of the custom fields</strong>.</p>
<h1 id="the-solution">The Solution</h1>
<p>To rectify this, you need to use a custom SQL query to bring all the data together in the right format. Specifically, we want to union all the views together, while aliasing the columns so that the union actually works.</p>
<p>Here is the query I whipped up to join News and Press Release documents.</p>
<p><strong><em>Disclaimer: I’m not a DB, I just play one in real life. I’m not sure of the performance impact of doing these unions is. Let me know if there is a better way!</em></strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SELECT ##TOPN## NodeId, NodeGuid, NodeAlias, NodeAliasPath, DocumentId, DocumentName, Type, Date
FROM
(SELECT NodeId, NodeGuid, NodeAlias, NodeAliasPath, DocumentId, DocumentName, 'News' AS Type, NewsReleaseDate AS Date
FROM View_CONTENT_News_Joined
UNION ALL
SELECT NodeId, NodeGuid, NodeAlias, NodeAliasPath, DocumentId, DocumentName, 'Press Release' AS Type, PressReleaseDate AS Date
FROM View_CONTENT_PressRelease_Joined
) Results
WHERE ##WHERE##
ORDER BY ##ORDERBY##
</code></pre></div></div>
<p>It looks a little complicated so let’s break it down:</p>
<ol>
<li>The 2 inner selects are selecting the rows from the appropriate views for the respective document types. The views are automatically created and updated by Kentico any time a document type’s fields are updated. The view joins together the CMS_Tree, CMS_Document, and custom document type tables.</li>
<li>When selecting from each view, we also alias the columns to match up for the <code class="language-plaintext highlighter-rouge">UNION</code> between them.</li>
<li>The outer select is simply selecting the rows from the result of the <code class="language-plaintext highlighter-rouge">UNION</code>.</li>
<li>The ‘##’ are helper macros for content that gets substituted (These just get removed if they’re not used).</li>
</ol>
<p>Once you’ve stolen the above code, make sure you test it with your own data, probably in SQL Server Management Studio (just manually replace the macro helpers when testing). Once everything works for your data, we want to store it in one of your document types. Go to the <code class="language-plaintext highlighter-rouge">Site Manager > Document Types > News > Queries</code> and create the query there, setting the name and using the default settings.</p>
<p><img src="/assets/images/2013-06-01-joining-multiple-document-types-in-kentico/Creating-the-custom-query-in-the-document-type.png" alt="Creating the custom query in the document type" /></p>
<p>Now that Kentico knows about our query, add a Repeater with custom query to the page template in the CMS Desk.</p>
<p><img src="/assets/images/2013-06-01-joining-multiple-document-types-in-kentico/Adding-the-repeater-with-custom-query-web-part.png" alt="Adding the Repeater with custom query Web Part" /></p>
<p>and set the properties like so:</p>
<ul>
<li><strong>Query Name</strong> - CMS.News.latest_updates</li>
<li><strong>ORDER BY Expression</strong> - Results.Date DESC</li>
<li><strong>SELECT TOP N</strong> - 3</li>
<li><strong>Transformation name</strong> - CMS.News.homepage</li>
</ul>
<p><strong><em>Note: Make sure you sub in your own values above, and set the rest of the properties as needed.</em></strong></p>
<p>And there you have it! Don’t forget to check with your DBA to see how he feels about that query…</p>
<p><em>SQL derived from <a href="http://stackoverflow.com/questions/213851/sql-query-using-order-by-in-union" title="SQL Query - Using Order By in UNION">Stackoverflow</a></em></p>
Troubleshooting Common IIS Issues2013-05-28T12:00:00+00:00http://johnnycode.com/2013/05/28/troubleshooting-common-iis-issues<p><strong>Disclaimer: I am not a Sys Admin. I have no idea what I’m doing. Use common sense before executing any of these solutions. If something breaks, don’t call me.</strong></p>
<p>The ones at the beginning of the list should be relatively easy and safe to check. As you go down the list, the steps may start to affect the availability of the site and/or server. Side effects are noted for each step.</p>
<h2 id="siteapplication-level">Site/Application level</h2>
<p>Changes in this section will probably only affect the site you’re working with.</p>
<h3 id="check-that-youre-looking-at-the-right-site">Check that you’re looking at the right site</h3>
<p>Make sure you’re not trying to fix the wrong site. Check the server IP and the site bindings. If you’re still not sure, drop a temp file into the site root and try and fetch it from your browser.</p>
<h3 id="check-the-path-to-the-website">Check the path to the website</h3>
<p>Self-explanatory.</p>
<h3 id="check-that-the-right-application-pool-is-being-used">Check that the right Application Pool is being used</h3>
<p>Self-explanatory.</p>
<h3 id="check-if-a-site-is-nested-within-another-site">Check if a site is nested within another site</h3>
<p>If you are nesting sites, the default functionality is that the web.config will be inherited. A change in the parent site’s configuration can affect the child site. You can disable inheritance per section, but it will might be easier to move the child to it’s own site.</p>
<h3 id="check-the-application-pool-framework-version">Check the Application Pool framework version</h3>
<p>Check to see if it is set to right framework version. Usually you can look at the version numbers in the web.config to see what framework version it should be using. Note that .NET framework versions 2.0, 3.0, and 3.5 are all covered under the 2.0 version (3.0 and 3.5 are like add-ons).</p>
<p><em>Note: Changing the app pool framework version will restart your site.</em></p>
<p><em>Caveat: App pools can be used by many sites. Check before you change something that could break other sites.</em></p>
<h3 id="check-the-application-pool-32-bit-mode-support-flag">Check the Application Pool 32-bit mode support flag</h3>
<p>If you get a YSOD (Yellow Screen of Death) about a DLL not loading, or being in the incorrect format, you may need to flip this flag. If set to false, the site will run in 64-bit mode. If set to true, the site will run in 32-bit mode. <strong>Note that “enabling 32-bit mode” will force the site to run in 32-bit mode and it will no longer load 64-bit DLL’s.</strong> So if you’re trying to add libraries to a website, you may need to go and download another version.</p>
<p><em>Commonly seen when using MySQL or SQLite.</em></p>
<p><em>Note: Changing the app pool mode will restart your site.</em></p>
<p><em>Caveat: App pools can be used by many sites. Check before you change something that could break other sites.</em></p>
<h3 id="check-the-webconfig-for-iis-modules">Check the web.config for IIS Modules</h3>
<p>If you are just loading up a site from another server or source control, you could be missing some IIS Modules required to run the site.</p>
<p>For example, we commonly use the <a href="http://www.iis.net/downloads/microsoft/url-rewrite" title="IIS URL Rewrite 2.0">IIS URL Rewrite Module</a> for IIS 7+. It provides an easy way to handle rewriting and redirecting. However, if it isn’t installed on the server trying to run the site, you get some generic web.config error.</p>
<p>Another issue we encountered was that the IIS URL Rewrite Module was installed, but we were missing one of the extensibility modules. I think the error message was more clear because it complained that the provider or assembly was missing.</p>
<p><em>I highly recommend the IIS URL Rewrite Module and you can install it directly from the <a href="http://go.microsoft.com/?linkid=9722531zsadasdas" title="Install the IIS URL Rewrite Module from WebPI">Web Platform Installer</a>. Extensibility samples are available for <a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=rewriteextensibility&DownloadId=9257" title="Download the IIS URL Rewrite Module extensibility samples">download</a> too.</em></p>
<p><em>A coworker, Mirek, just ran into this issue and reminded me of it today.</em></p>
<h3 id="recycle-the-application-pool">Recycle the Application Pool</h3>
<p>Sometimes an application can just get into a bad state. Recycling it <em>basically</em> restarts the site.</p>
<p><em>Caveat: CMS/Application users may end up getting logged out and may lose work.</em></p>
<p><em>Caveat: App pools can be used by many sites. Check before you change something that could break other sites.</em></p>
<h3 id="stop-and-start-application-pool">Stop and start Application Pool</h3>
<p>Recycling the app pool may work, but stopping it and starting it actually does a little bit more.</p>
<p><em><strong>Caveat: When stopping the application pool, the site will go completely offline. Starting it again can take up to a few minutes, depending on the size of the site and what state it was in.</strong> If you try and start it right away IIS will popup some random error. Just keep trying until it works.</em></p>
<p><em>Caveat: App pools can be used by many sites. Check before you change something that could break other sites.</em></p>
<h2 id="iis-level">IIS level</h2>
<p>Changes in this section will affect all sites running under IIS.</p>
<h3 id="restart-iis">Restart IIS</h3>
<p>Try to avoid this at all costs. Consult with other devs/IT before resorting to this.</p>
<h3 id="re-register-aspnet-with-iis">Re-register ASP.NET with IIS</h3>
<p>Sometimes a framework version install can get messed up. You can run the install script from the framework version folder. The scripts can be found in <code class="language-plaintext highlighter-rouge">C:\Windows\Microsoft.NET\{mode}\{version}</code>.</p>
<p><em>Caveat: Make sure you run the command against the right Framework mode and version.</em></p>
<p><em>Caveat: Make sure you run the command with the right command line options to ensure that you don’t modify the framework versions on all the sites on the server.</em></p>
<h2 id="server-level">Server level</h2>
<p>Changes in this section will affect all services running on the server.</p>
<h3 id="restart-the-server">Restart the server</h3>
<p>Rarely, IIS may get into a bad state that can only be solved with a reboot. I’ve only ever seen this once. Typically this wont happen if you’re running IIS with a standard configuration / network configuration.</p>
<p><strong><em>Note: Try to avoid this at all costs. Consult with other devs/IT before resorting to this. There may be other important services running on the machine.</em></strong></p>
Weighting Results in a Kentico Custom Search Index2013-05-21T12:00:00+00:00http://johnnycode.com/2013/05/21/weighting-results-in-a-kentico-custom-search-index<p>Kentico’s search uses <a href="http://lucenenet.apache.org/" title="Lucene.net Search Engine Library">Lucene.net</a> under the hood to provide a fast and powerful search experience.</p>
<p>However, as much as Kentico does to make the options flexible, it’s impossible to anticipate all the different scenarios. Sometimes you need to create a custom search index. Kentico provides basic instructions on how to <a href="http://devnet.kentico.com/docs/7_0/devguide/index.html?smart_search_defining_custom_index_content.htm" title="Defining custom index content with Kentico Smart Search">define custom index content</a> in their <a href="http://devnet.kentico.com/docs/7_0/devguide/index.html" title="Kentico CMS 7.0 Developer Guide">Developer Guide</a>, and they have an additional <a href="http://devnet.kentico.com/Videos/System-Management/Smart-Search-in-Kentico-CMS-6.aspx" title="Smart Search Customization in Kentico CMS 6">webinar and sample project</a> that goes more in-depth.</p>
<h2 id="use-case-and-solution">Use Case And Solution</h2>
<p>A common problem you may have though, is that the search indexer wont understand the context of the content you’re indexing. It doesn’t understand how it should weight certain results. For example, if you’re indexing products and product documentation, you probably want the product pages to rank higher than the documentation pages.</p>
<p>To accomplish custom weighting of your search index results, we can simply specify a “boost” value on a document being indexed, so that it receives more or less weight when it matches the search terms.</p>
<p>If we want a document to rank higher, we set a boost value over 1. To rank lower, set a boost value under 1.</p>
<p>In one custom implementation we did for a client we created a custom search index for media items, based on their related content. ex. for Product A, there is a related PDF, simply linked via a custom document field. The PDF document didn’t contain much content, so we actually referenced the fields on the related Products to get relevant search data.</p>
<p>However, PDF’s were each used by many products, and therefore, they ranked higher than the products themselves! To overcome this, we “downgraded” their search weight by setting a low boost value.</p>
<h2 id="show-me-the-code">Show Me The Code!</h2>
<p>It was really quite simple once I figured out that the boost value is what needs to be adjusted. Within your index loop, just before adding a search document to the index, set the boost value:</p>
<p>// Inside the loop…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Create new document for current text file
var searchDocument = SearchHelper.CreateDocument(SearchHelper.CUSTOM_SEARCH_INDEX, Guid.NewGuid().ToString(), SearchHelper.INVARIANT_FIELD_VALUE, createdDate, SearchHelper.INVARIANT_FIELD_VALUE);
// Add search data
// ...
// Decrease the relvancy of this document so we don't overtake products.
searchDocument.SetBoost(0.1f);
// Add document to the index
indexWriter.AddDocument(searchDocument);
</code></pre></div></div>
<p>You could easily hook up an algorithm to adjust the boost value yourself, but in our case a static value for this index worked fine. And that’s all there is to it!</p>
Using Custom Classes with Kentico Macros2013-05-09T12:00:00+00:00http://johnnycode.com/2013/05/09/using-custom-classes-with-kentico-macros<p>Kentico Macros provide flexibility when it comes to building your site. Macros work with the current context to provide data from the current site, user, document, querystring, etc.</p>
<p>The problem is when you want to use a custom type. If you look at the MacroExpression classes code using your favorite decompiler (like <a href="http://ilspy.net/" title="ILSpy a .NET Decompiler">ILSpy</a> you find this method:</p>
<p>(In CMS.GlobalHelper.MacroExpression)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected object EvaluateInternal(MacroResolver resolver, MacroEvalParameters evalParams, ref bool match)
</code></pre></div></div>
<p>calls into:</p>
<p>(In CMS.GlobalHelper.MacroExpression)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public virtual bool GetObjectValue(object obj, string columnName, ref object result)
</code></pre></div></div>
<p>which attempts to render properties and other data from the following types</p>
<ul>
<li>DataRow</li>
<li>DataRowView</li>
<li>IHierarchicalObject</li>
<li>IDataContainer</li>
<li>ISimpleDataContainer</li>
<li>INameIndexable</li>
</ul>
<p>So, unfortunately, that means this code doesn’t work out of the box:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> MyDataObject.DataPoint
</code></pre></div></div>
<p>While it’s not the ideal situation, you can inherit from one of those class, or implement one of the interfaces to leverage macros with your custom class.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class MyDataClass : ISimpleDataContainer
{
public string DataPoint { get; set; }
public object GetValue(string columnName)
{
return DataPoint;
}
public bool SetValue(string columnName, object value)
{
DataPoint = value.ToString();
return true;
}
public object this[string columnName]
{
get { return DataPoint; }
set
{
DataPoint = value.ToString();
}
}
}
</code></pre></div></div>
<p><em>(Note that my “implementation” of the interface is very basic. If we add more properties we want to support, we would have to add conditionals, a switch, or ideally, some reflection based resolving of the property names)</em></p>
<p>Now you can use your data class like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var myDataObject = new MyDataClass { DataPoint = "test data" };
var macroResolver = CMSContext.CurrentResolver;
macroResolver.SetNamedSourceData("MyDataObject", myDataObject);
var result = macroResolver.ResolveMacros("This should be the number of units: MyDataObject.DataPoint ");
</code></pre></div></div>
Using Service Stack to create a CSV file with ASP.NET Webforms2013-05-01T13:00:00+00:00http://johnnycode.com/2013/05/01/using-service-stack-to-create-a-csv-file-with-asp-net-webforms<p>Recently I needed to export some data from a CMS (Content Management System). The customer requested that the data be in CSV format. There are a lot of different ways to do this, but this one might be one of the easiest!</p>
<p>CSV isn’t a terribly complicated format, but people do screw it up often enough. We could write some simple code to output our data in CSV format, but why not stand on the shoulders of giants? We’ll leverage <a href="http://www.servicestack.net/">Service Stack</a> to do all the heavy lifting for us.</p>
<p>Here is a snippet from my code. This is a sample click event handler in ASP.NET Webforms:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected void uxExportProducts_Click(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=product-export.csv");
CsvSerializer.SerializeToStream(GetProducts(), Response.OutputStream);
Response.End();
}
</code></pre></div></div>
<p>To setup, we need to clear any other headers that may have been set, set the content type, and “force” a file download with the “Content-Disposition” header. Make sure you update your code to set the appropriate filename. After that we just need to serialize out the data, and then <code class="language-plaintext highlighter-rouge">End()</code> the response so the rest of the page doesn’t automatically render.</p>
<p>So what does the <code class="language-plaintext highlighter-rouge">GetProducts()</code> method do? Here is the method signature for the Serialization method:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string SerializeToCsv<T>(IEnumerable<T> records);
</code></pre></div></div>
<p>I simply had my data layer return a <code class="language-plaintext highlighter-rouge">List<ProductData></code> (or it could be a <code class="language-plaintext highlighter-rouge">IEnumerable<T></code>):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public List<ProductData> GetProducts()
{
// Code to get the data from the DB or web service or whatever...
}
</code></pre></div></div>
<p>…and ProductData is just a POCO:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class ProductData
{
public string ProductName { get; set; }
public string Photo { get; set; }
public string Description { get; set; }
public string Category { get; set; }
}
</code></pre></div></div>
<p>Hope that helps someone!</p>
Drupal 7 Panels Page Template Suggestion2013-01-29T12:00:00+00:00http://johnnycode.com/2013/01/29/drupal-7-panels-page-template-suggestion<p>The Drupal Panels Module is one of the best modules out there and provides flexible templating directly within the CMS. I recently worked on a site where I needed a default <em>page.tpl.php</em> for most of my pages, but a different <em>page.tpl.php</em> for my panel pages. Mainly, my regular pages need some padding around the main content area, while my panel page layouts dealt with that individually.</p>
<p>Madmatter23 provides some <a href="http://grasmash.com/article/add-drupal-template-suggestion-panels-page-paneltplphp">Drupal 6 code on his blog</a>. It allows you to have a <strong><em>page–panel.tpl.php</em></strong> that will be used for your panel pages. I took that code and updated it for Drupal 7:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/**
* Implementation of hook_preprocess_page().
*/
function theheap_preprocess_page(&$variables) {
// if this is a panel page, add template suggestions
if($panel_page = page_manager_get_current_page()) {
// add a generic suggestion for all panel pages
$variables['theme_hook_suggestions'][] = 'page__panel';
// add the panel page machine name to the template suggestions
$variables['theme_hook_suggestions'][] = 'page__' . $panel_page['name'];
//add a body class for good measure
$body_classes[] = 'page-panel';
}
}
</code></pre></div></div>
<p>Madmatter23 also provides <a href="http://grasmash.com/article/add-drupal-template-suggestion-panels-page-paneltplphp">an additional (Drupal 6) snippet</a> that will also add template suggestions for the specific layout of the panel page. I didn’t have a need for that, but if you need that functionality it should be very easy to port the few extra lines into my sample above.</p>
<p>That’s it!</p>
Establish Your Own Developer Kaizen Guild2012-07-20T12:00:00+00:00http://johnnycode.com/2012/07/20/establish-your-own-developer-kaizen-guild<p>Much like <a href="http://www.hanselman.com/blog/WhoIsOnYourLifesBoardOfDirectors.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ScottHanselman+%28Scott+Hanselman+-+ComputerZen.com%29">Scott Hanselman says you need a “Life’s Board of Directors”</a>, every <em>developer</em> needs to be a part of their own <strong>Developer Kaizen Guild (DKG)</strong>.</p>
<h2 id="what-is-a-developer-kaizen-guild-dkg">What is a Developer Kaizen Guild (DKG)?</h2>
<p>Kaizen is Japanese for “improvement” but is used in the context of <em>continuous improvement</em>. Read <a href="http://en.wikipedia.org/wiki/Kaizen">the Kaizen Wikipedia article</a> if you want to know more about the philosophy and practices. A guild “is an association of craftsmen in a particular trade” <a href="http://en.wikipedia.org/wiki/Guild">according to Wikipedia</a>. To build on those definitions, a Developer Kaizen Guild is:</p>
<blockquote>
<p>An tight-knit group of developers focused on continuous improvement of themselves and their trade.</p>
</blockquote>
<p>The full phrase “Developer Kaizen Guild” was coined by a good friend and great developer <a href="http://codeimpossible.com">Jared Barboza</a>.</p>
<h2 id="what-are-the-benefits-of-a-dkg">What are the benefits of a DKG?</h2>
<p>The main benefit of a DKG is the ability to “bounce ideas” off of others. Having trouble debugging a bizarre issue? Ask the DKG. Need architecture advice? Ask the DKG. Frustrating boss or co-workers? Vent to the DKG.</p>
<p>Members of the DKG can offer direct support in the form of advice or wisdom. Chances are that someone else in the DKG has experienced a situation similar to yours, or maybe even the <strong><em>exact</em></strong> situation you’re in. The act of explaining your current issues to someone else can often bring self-enlightenment. How many times have you asked a question only to realize the answer just as the words leave your mouth</p>
<p>The DKG can also provide indirect support. There is only so much time in the day we can spend learning. Then there are the days where we get bogged down with work and can’t even open our RSS feed, let alone monitor the Spolsky’s and Atwood’s on Twitter. It’s times like these where the DKG shines. Even if you didn’t have time to hear the latest buzz, someone else did. The DKG can aggregate notifications about the latest development trends, libraries and practices.</p>
<h2 id="who-should-be-in-your-dkg">Who should be in your DKG?</h2>
<p>Take an inventory of your developer friends/co-workers/past-co-workers and identify the ones that are similar to you. Similar in a sense that they work like you. They are <strong><em>passionate</em></strong> about their job. They want to <strong><em>learn</em></strong>. They want to <strong><em>improve</em></strong>. Language and experience are less important. Generally, programming languages and frameworks are similar enough that experienced developers from different backgrounds can have productive discussions about specific code or patterns. The more diverse your backgrounds, the greater the overall value of The Guild. Below I use our DKG as an example of the diversity you should strive for.</p>
<h2 id="who-needs-a-dkg">Who needs a DKG?</h2>
<p>As I said, every good developer should be a part of a DKG. In particular, people who would <strong>greatly</strong> benefit from a DKG are people lacking support in their daily work. People who:</p>
<ul>
<li>Work from home.</li>
<li>Are isolated in a small or 1-person development team.</li>
<li>Work with developers who aren’t interested in Kaizen.</li>
</ul>
<p>This is the make up of our very own DKG. We have co-workers, remote co-workers, past co-workers, and associates. Associates are people who know other members of the DKG, but whom you may not know personally. Based on personality similarities, you may very well make some new friends through these associations.</p>
<h2 id="how-do-you-communicate-with-your-dkg">How do you communicate with your DKG?</h2>
<p>Everyone’s DKG is going to work differently. Our DKG uses Skype group chat, but there are a multitude of options:</p>
<ul>
<li><a href="http://skype.com">Skype</a> group chat</li>
<li>An <a href="http://www.irc.org/">IRC</a> channel (or <a href="http://jabbr.net">Jabbr</a> room for a low friction version)</li>
<li>Local <a href="http://meetup.com">meetups</a> or playdates</li>
<li>Phone Calls</li>
</ul>
<p>The nice thing about Skype is that it works on multiple OS’, it records messages you miss, supports audio/video conversations, and is free!</p>
<h2 id="so-how-does-a-dkg-work-in-practice">So how does a DKG work in practice?</h2>
<p>Here is a real-world example from earlier this week:</p>
<p>An internal application my company created is using a link tag to dynamically load CSS. We change the href in JavaScript which forces the browser to load the new stylesheet. This is working great, but I notice a double-load of the same stylesheet in the Network tab in Chrome. The dynamic link tag is starting with a default value but then some JavaScript immediately updates the href on page load to the same value. Wanting to prevent that additional request, I remove the default/hard-coded href attribute.</p>
<p>This particular app was written in MVC 1 or 2 and upgraded to 3, but the views are still using the Web Forms View Engine. Through my simple change, the markup goes from this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><link href="someRandomStylesheet" rel="stylesheet" type="text/css" href="style.css" id="dynamicCss" />
</code></pre></div></div>
<p>to this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><link rel="stylesheet" type="text/css" href="style.css" id="dynamicCss" />
</code></pre></div></div>
<p>I test my change locally and everything looks good. I push the change and move on…</p>
<p>…suddenly, I get 5 more bug reports relating to the app. The UI for the app has exploded. But how?</p>
<p>I look at the staging site and see the whacky styles. What the heck happened? Was it my fault, or someone else’s? I check the history. Nope, I’m the only who touched the code recently. I’m testing in the same browser on the same page. I use the Chrome inspector to look at the styles being applied to a misbehaving element when I find that a bunch of class styles are missing…</p>
<p>Viewing the source shows that something has gone terribly wrong.</p>
<p>I expected to see this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><link rel="stylesheet" type="text/css" href="style.css" id="dynamicCss" />
</code></pre></div></div>
<p>but instead I saw this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><link rel="stylesheet" type="text/css" href="style.css" id="_ctl0_dynamicCss" />
</code></pre></div></div>
<p>WTF?</p>
<p>This is MVC right? Yep. MVC 3? Yep. Just a regular web forms master view? Yep. Then what the heck is happening? I immediately call a meeting of the Developer Kaizen Guild, a coalition of top-notch developers working in various web development roles. Each member brings their own specialties to the table:</p>
<ul>
<li>Jared - .Net, Ruby, JavaScript, Testing</li>
<li>Gregg - jQuery, HTML, CSS, Customer Relations</li>
<li>Chris J - .NET, HTML, CSS, TCP/IP</li>
<li>Mark - Cold Fusion, jQuery, HTML, CSS, SQL, Customer Relations</li>
<li>Dave - Architecture, C#, Coding Concepts, Debugging</li>
<li>Keith - C#, VB.NET, JS, HTML, SQL, Customer Relations</li>
<li>Joe - Everything under the sun</li>
<li>Chris B - Ruby, PHP</li>
</ul>
<p>Back to the problem at hand…</p>
<p>Jared, the one most familiar with the seedy underbelly of ASP.NET begins analyzing the issue. He starts offerings workarounds, considers the possibility of a web forms view engine bug, then has an epiphany:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"oh f***
does your <head> have runat="server" or something?"
</code></pre></div></div>
<p>BINGO. Problem solved. Total time to solution via the DKG: 10 minutes.</p>
<p>How long would it have taken for me to have the same realization? It’s hard to say for sure but at the time I didn’t even know where to begin looking, despite my extensive experience with ASP.NET.</p>
<h2 id="take-it-up-a-notch">Take it up a notch</h2>
<p>Now that you formed a DKG (You did, right?), why not take it up a notch? Take a look at your DKG roster. You now have a tight-knit network of like-minded people of varying abilities and skills, all with the goal of continuously improving their skills. <strong>That is a bad-ass combination right there</strong>. Why not apply this awesome force of cohesive technical abilities? Here are some ideas to get you started:</p>
<ul>
<li>Start a podcast</li>
<li>Start an open source project</li>
<li>Start a company</li>
</ul>
<h2 id="side-note">Side note</h2>
<p>If you don’t like the term Developer Kaizen Guild, try “Skilled Hackers Invested in Evolving and Leading Development”, or S.H.I.E.L.D.</p>
Getting JSON from ASP.NET: The Beautiful, the Good, the Bad and the Ugly2012-07-16T12:00:00+00:00http://johnnycode.com/2012/07/16/getting-json-from-asp-net-beautiful-good-bad-ugly<p><strong>UPDATED</strong>
Since <a href="http://www.hanselman.com/blog/VisualStudio2012AndNETFramework45IsRELEASEDHeres5MinuteVideosToGetYouUpToSpeedQuick.aspx">ASP.NET 4 has been officially released</a>, I added an example of Web API controller code.</p>
<p>Since I started my new job I’ve been working on some old ASP.NET Web Forms code. We use a lot of AJAX but we don’t use many different approaches to get the data. For fun, I created <a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/">a GitHub project to demonstrate the various ways to get JSON data from the different flavors of ASP.NET</a>. Below is a little explanation of the code.</p>
<h2 id="the-bad-using-an-aspnet-web-forms-page-aspx">The Bad: Using an ASP.NET Web Forms page (.aspx)</h2>
<p><a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/blob/master/src/GetJsonFromAspNet/GetJsonFromAspNet/PeoplePage.aspx.cs">The ASP.NET Web Forms Page code-behind on GitHub</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public partial class PeoplePage : Page
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var peopleRepository = new PeopleRepository();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(JsonConvert.SerializeObject(peopleRepository.GetPeople()));
}
[WebMethod]
public static object GetViaWebMethod()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return people;
}
}
</code></pre></div></div>
<p>The first example using <code class="language-plaintext highlighter-rouge">Response.Write()</code> is terrible. Just terrible. Don’t <em>ever</em> do this, <strong>ever</strong>. There is simply no justification to use an ASP.NET Page to simply return raw data. If you need to do this, use a handler or a web service (examples linked/discussed below).</p>
<p>The second example using a a static method with a WebMethod attribute isn’t recommended, but I can understand if people want to keep their JSON endpoint in the same place where the data is handled for the view (Page) that renders the related HTML.A better approach would be</p>
<p><strong>Thoughts: Try hard to stay away from these 2 approaches!</strong></p>
<h2 id="the-ugly-using-an-aspnet-http-handler-ashx">The Ugly: Using an ASP.NET HTTP Handler (.ashx)</h2>
<p><a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/blob/master/src/GetJsonFromAspNet/GetJsonFromAspNet/PeopleHandler.ashx.cs">The ASP.NET HTTP Handler code on GitHub</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class PeopleHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(people));
}
}
</code></pre></div></div>
<p>This is a straightforward example that may not be a best practice, but is fairly lightweight. ASP.NET handler’s are pretty “raw” and don’t have the same overhead that Pages do. So this approach should be a little faster than the above methods, while separating your JSON service from your presentation code (If you want that).</p>
<p><strong>Thoughts: This isn’t a bad approach, but it’s not the best either.</strong></p>
<h2 id="the-good-using-an-aspnet-web-service-asmx">The Good: Using an ASP.NET Web Service (.asmx)</h2>
<p><a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/blob/master/src/GetJsonFromAspNet/GetJsonFromAspNet/PeopleService.asmx.cs">The ASP.NET Web Service code on GitHub</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class PeopleService : WebService
{
[WebMethod]
public object GetPeople()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return people;
}
[WebMethod]
public object GetPeopleDictionary()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeopleDictionary();
return people;
}
}
</code></pre></div></div>
<p>This is probably the most widespread one (hopefully). This is the best way to do a web service in an ASP.NET Web Forms site.</p>
<p><strong>Thoughts: If you’re stuck with a Web Forms site and can’t enhance it with MVC controllers, this is your best approach.</strong></p>
<h2 id="the-beautiful-using-an-aspnet-mvc-controller">The Beautiful: Using an ASP.NET MVC controller</h2>
<p><a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/blob/master/src/GetJsonFromAspNet/GetJsonFromAspNet/Controllers/HomeController.cs">The HomeController code on GitHub</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult GetPeopleViaJson()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return Json(people);
}
public ActionResult GetPeopleViaJsonDotNet()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return Content(JsonConvert.SerializeObject(people), "application/json");
}
public ActionResult GetPeopleViaJsonDotNetActionResult()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return new JsonNetResult { Data = people };
}
}
</code></pre></div></div>
<p>The first example highlights the simplicity behind ASP.NET MVC and the way you “return” data to the client. It uses the built in Json method to return a JsonResult. Short and sweet.</p>
<p>The second example is a bit “better” in that it uses the Json.NET library to serialize the data manually. This should be a lot faster than the built-in serializer.</p>
<p>The last approach is my favorite. It uses a custom ActionResult type to automatically handle the serialization via Json.NET instead of the built-in serializer. Short and sweet and fast.</p>
<p><strong>Thoughts: This is my recommended approach for getting JSON data out of ASP.NET.</strong></p>
<h2 id="using-an-aspnet-mvc-web-api-controller">Using an ASP.NET MVC Web API Controller</h2>
<p>The newest of the bunch. ASP.NET Web API offers “restful” web services. As far as serving up JSON, it looks very similar to an ASP.NET Web Service (.asmx). The return type of the Web API controller method is our data type, and the serialization is handled by Web API. The configuration of Web API flexible, but lives outside the individual controller (not shown here).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class JsonController : ApiController
{
public IEnumerable<Person> People()
{
var peopleRepository = new PeopleRepository();
var people = peopleRepository.GetPeople();
return people;
}
}
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>The takeaway? Use an MVC Controller or ASP.NET Web API controller when you can. If you’re stuck in Web Forms land, try and use a ASMX web service to keep things separated.</p>
<p>If you were unfamiliar with JSON and .NET, I hope this post and <a href="https://github.com/jbubriski/GetJsonFromAspNetExamples/">my GitHub project</a> help you gain some insight on how to pull JSON from your own ASP.NET web applications. If you’re an ASP.NET AJAX veteran, and you know of other methods that I forgot to mention, feel free to send me a pull request and let me know!</p>
How to Migrate from WordPress to Jekyll Running on Github2012-07-10T12:00:00+00:00http://johnnycode.com/2012/07/10/how-to-migrate-from-wordpress-to-jekyll-running-on-github<p>This one’s for you <a href="http://datachomp.com/">Rob</a>!</p>
<p><img src="/assets/images/2012-07-10-how-to-migrate-from-wordpress-to-jekyll-on-github/per-robs-tweet.png" alt="" /></p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Setup">Setup</a></li>
<li><a href="#Conversion">Conversion</a></li>
<li><a href="#Configuration">Configuration</a></li>
<li><a href="#Deployment">Deployment</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<h2 id="introduction"><a id="Introduction">Introduction</a></h2>
<h3 id="why-are-you-migrating">Why are you migrating?</h3>
<p>Wordpress was working great for me and I didn’t have any major issues with it, so why did I switch? Here are some reasons you might want to power your blog with Jekyll:</p>
<ol>
<li>Security - I’ll never have to worry about vulnerabilities in WordPress or PHP again.</li>
<li>Performance - Static files are <em>fast</em>.</li>
<li>Portability - If I ever need to migrate to another host, I can install Jekyll on the new host or simply push the output from a local Jekyll install.</li>
<li>Cost - GitHub Pages is free so I can now cancel my shared hosting account.</li>
<li>Just for the hell of it.</li>
</ol>
<p>If those reasons sound good to you, ask yourself…</p>
<h3 id="should-i-migrate-limitation-and-considerations">Should I migrate? (limitation and considerations)</h3>
<p>Before you start executing my step-by-step super-detailed directions, let’s take a moment to examine some caveats with Jekyll and GitHub Pages:</p>
<ol>
<li><strong>You can’t have dynamic content</strong> - Github runs Jekyll for you, and only generates static content. That means you can’t use any server-side languages or frameworks to generate or handle dynamic content.</li>
<li><strong>No Jekyll plugins</strong> - Github runs Jekyll in safe mode which disables the use of custom plugins.</li>
<li><strong>You will (most likely) have to migrate your site structure as is</strong> - Again, you will have no server-side capabilities so changing up your site structure can be a major pain (Refer to the <a href="#Cleanup">Cleanup</a> section for more info).</li>
<li><strong>Stuff can go wrong</strong> - If it aint broke, don’t fix it, right? As with any migration or new project, there is always something that you didn’t account for or something that didn’t go as planned. This is true of any project.</li>
</ol>
<p>If you’re OK with the caveats, let’s get setup.</p>
<h2 id="setup"><a id="Setup">Setup</a></h2>
<h3 id="make-sure-you-have-a-github-account">Make sure you have a Github account.</h3>
<p>Just go to <a href="https://github.com/signup/free">Github’s signup page</a> and create an account. It’s free for unlimited public (open source) repositories.</p>
<h3 id="create-your-github-pages-repo">Create your Github Pages repo.</h3>
<p>Follow the <a href="https://help.github.com/articles/creating-pages-with-the-automatic-generator">Github Pages setup instructions</a>.</p>
<h3 id="export-your-wordpress-content">Export your WordPress content</h3>
<p>From the WordPress admin backend, go to <code class="language-plaintext highlighter-rouge">Tools > Export</code> and export all of your content to an XML file.</p>
<h3 id="get-python-27x-dont-get-python-3x">Get Python 2.7.X (Don’t get Python 3.X!)</h3>
<p>We’re going to need Python to run the conversion script. <strong>There are major breaking changes between Python 2.X and Python 3.X. Make sure you get 2.7.X for the purpose of the conversion.</strong></p>
<h3 id="install-pip-the-python-package-installer">Install pip, the Python Package Installer</h3>
<p>pip well install all the dependencies we need for the Python script.</p>
<p>(<a href="http://stackoverflow.com/questions/4750806/how-to-install-pip-on-windows">original instuctions from this Stackoverflow question</a>)</p>
<ol>
<li>Download the <a href="http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11.win32-py2.7.exe#md5=57e1e64f6b7c7f1d2eddfc9746bbaf20">last easy installer for Windows</a>: (download the .exe at the bottom of http://pypi.python.org/pypi/setuptools ).</li>
<li>Install the easy installer.</li>
<li>Get the <a href="http://pypi.python.org/packages/source/p/pip/pip-1.1.tar.gz#md5=62a9f08dd5dc69d76734568a6c040508">pip installer source</a> from the <a href="http://pypi.python.org/pypi/setuptools#files">pip page</a>.</li>
<li>Uncompress pip.</li>
<li>
<p>Go to the uncompressed pip directory and run:</p>
<p>python setup.py install</p>
</li>
</ol>
<h3 id="get-exitwp">Get Exitwp</h3>
<p>Exitwp is the Python script that will convert the WordPress XML file to the Jekyll markdown structure.</p>
<ol>
<li>Go to the <a href="https://github.com/thomasf/exitwp">Exitwp Github page</a> and download the source (or clone the repo locally).</li>
<li>Extract the files from the zip you downloaded. I put mine in <code class="language-plaintext highlighter-rouge">C:\Projects\jbubriski\Wordpress to Jekyll Migration\thomasf-exitwp-ede1dd5</code></li>
</ol>
<h3 id="use-pip-to-install-the-exitwp-dependencies">Use pip to install the Exitwp dependencies</h3>
<p>Exitwp needs PyYAML for Reading configuration files and writing YAML headers and Beautiful soup for Parsing and downloading of post images/attachments. It also requires html2text, but that is included with Exitwp. To install the 2 missing dependencies:</p>
<p>(If you have a slightly different version of Python, make sure to change the version number, or if you have Python in your path, you don’t need the full path. If you have multiple version of Python installed, male sure you use the right one.)</p>
<ol>
<li>Navigate to the directory where you extracted Exitwp</li>
<li>Run <code class="language-plaintext highlighter-rouge">C:\Python27\Scripts\pip.exe install --upgrade -r pip_requirements.txt</code></li>
</ol>
<p>You should see some output like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Downloading/unpacking BeautifulSoup (from -r pip_requirements.txt (line 1))
Downloading BeautifulSoup-3.2.1.tar.gz
Running setup.py egg_info for package BeautifulSoup
Requirement already up-to-date: PyYAML in c:\python27\lib\site-packages (from -r pip_requirements.txt (line 2))
Downloading/unpacking html2text (from -r pip_requirements.txt (line 3))
Downloading html2text-3.200.3.tar.gz
Running setup.py egg_info for package html2text
Installing collected packages: BeautifulSoup, html2text
Running setup.py install for BeautifulSoup
Running setup.py install for html2text
Installing html2text-script.py script to C:\Python27\Scripts
Installing html2text.exe script to C:\Python27\Scripts
Installing html2text.exe.manifest script to C:\Python27\Scripts
Successfully installed BeautifulSoup html2text
Cleaning up...
</code></pre></div></div>
<p>Now we should be ready to start the conversion.</p>
<h2 id="the-conversion"><a id="Conversion">The Conversion</a></h2>
<p>Run Exitwp with this command (again, check your Python version):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\Python27\python.exe .\exitwp.py
</code></pre></div></div>
<p>which should produce a structure like this one inside the Exitwp directory:</p>
<ul>
<li>build
<ul>
<li>jekyll
<ul>
<li>[yoursitename]
<ul>
<li>_posts</li>
<li>about</li>
<li>achievements</li>
<li>contact-me</li>
<li>kentico-resources</li>
<li>resources</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="setup-comments-with-disqus">Setup comments with Disqus</h3>
<p>Since Jekyll generates static HTML it wouldn’t make sense for our comments to be imported by Exitwp. To provide comment support we either have to rely on a 3rd party service or a server-side language. Since we’re running Jekyll on GitHub Pages the server-side option is out, so we need a 3rd party service.</p>
<p>There are a few services out there that can provide a free commenting system. Disqus, Livefyre, IntenseDebate, and even Facebook all provide HTML snippets that you can drop into a page or template to automatically provide comments. I happened to choose Disqus since I’ve seen it on a lot of other tech blogs and it’s free. Here is how you set it up:</p>
<ol>
<li>Signup for Disqus.</li>
<li>Install the Disqus plugin for your WordPress site.</li>
<li>Setup the Disqus plugin (go to the Wordpress Admin Comments section and follow the wizard).</li>
<li>Export comments to Disqus.</li>
</ol>
<p>They say it can take up to 24 hours for the import to complete, but don’t wait up. We can still configure Disqus to work with our Jekyll blog even though the comments aren’t live yet. If you’re going to create your own templates, simply grab the Disqus HTML snippet and drop it into the templates. If you’re going to use a blogging framework like Jekyll Bootstrap, wait until we get to the configuration section where it will take 2 seconds to configure.</p>
<h3 id="jekyll-bootstrap">Jekyll Bootstrap</h3>
<p>While Exitwp does a lot for you, it leaves out the supporting structure to actually run your blog. Generating atom feeds, category and tag pages, and other supporting functionality are left up to you. This is where a Jekyll Bootstrap comes in.</p>
<p><a href="http://jekyllbootstrap.com">Jekyll Bootstrap</a> (JB) is</p>
<blockquote>
<p>“a lean blogging framework made for developers and designers.”</p>
</blockquote>
<p>It has the layouts and templates needed to create a standard blog website while providing numerous configuration options for the most common features you might change:</p>
<ul>
<li>Comments provider</li>
<li>Analytics</li>
<li>Social networking/sharing</li>
<li>Other core setup options</li>
</ul>
<p>To get started clone <a href="http://github.com/plusjade/jekyll-bootstrap">Jekyll Bootstrap on GitHub</a> or <a href="https://github.com/plusjade/jekyll-bootstrap/zipball/master">download a zip of the latest code</a> and unzip the files.</p>
<p>From there, you should be able to copy the entire contents of the Jekyll site structure directly on top of your current website that was created by Exitwp. While some of the folders will have the same name, it should be safe to overwrite everything in the directory with the JB files.</p>
<p>The individual files are too numerous to list here, so I’m just going to provide the necessary changes we need to get our blog up and running with as much functionality as is provided out of the box.</p>
<p>Open up the new _config.yml file in the root of the site that was provided by JB. The config file uses the YML format which is extremely user friendly. For our specific use of JB with GitHub Pages, we should set a few config options right off the bat. Put these settings at the top of your config file:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>safe: true
auto: true
server: true
markdown: rdiscount
</code></pre></div></div>
<p>Jekyll runs in safe mode on GitHub Pages, which disables the use of plugins. The <code class="language-plaintext highlighter-rouge">auto</code> setting automatically rebuilds the site when changes are detected. <code class="language-plaintext highlighter-rouge">server</code> starts the Jekyll server when run from the command line. <code class="language-plaintext highlighter-rouge">markdown</code> allows us to set rdiscount as the markdown parser.</p>
<p><em>(GitHub also uses <code class="language-plaintext highlighter-rouge">lsi: false</code> and <code class="language-plaintext highlighter-rouge">pygments: true</code>, but JB should already have those settings defined.)</em></p>
<p>Other than that, you should go to through the rest of the configuration options and set the important ones:</p>
<ul>
<li>permalink - I set mine to <code class="language-plaintext highlighter-rouge">/:year/:month/:day/:title/</code> to match my WordPress permalinks.</li>
<li>production_url (username.github.com)</li>
<li>comments (this is where you set your Disqus short name)</li>
<li>analytics (Google tracking ID)</li>
</ul>
<h2 id="testing"><a id="Testing">Testing</a></h2>
<p>Before we deploy the new site to Github, we should make sure it works locally first! Github had some issues running Jekyll on my content, and there were no helpful error codes or messages. To make sure things go as smoothly as possible, we need to run Jekyll locally.</p>
<h3 id="install-ruby">Install Ruby</h3>
<p>I installed <strong>Ruby 1.9.3 and the Ruby Dev Kit</strong> from <a href="http://rubyinstaller.org/">RubyInstaller.org</a>. For the Dev Kit, follow the install instructions on the <a href="https://github.com/oneclick/rubyinstaller/wiki/Development-Kit">Ruby Dev Kit Wiki</a>.</p>
<h3 id="install-jekyll">Install Jekyll</h3>
<p>At the time of writing GitHub pages runs on Jekyll 0.11.0, so we should use too. Double check that the version hasn’t changed on the <a href="http://help.github.com/pages/">GitHub Pages documentation page</a>. To install our specific version, run:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install Jekyll -v 0.11.0
</code></pre></div></div>
<p>Once installed navigate to the directory of your site and run this command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll --server
</code></pre></div></div>
<p>If everything went smoothly, Jekyll should be listening on port 4000 by default. <a href="http://localhost:4000">Check it out!</a></p>
<p>If the site isn’t running, check the output from the jekyll command to see if it reported any errors. If you get some random errors from Maruku, make sure you set your markdown parser to rdiscount. I found that rdiscount is more durable and gives better error messages. You can set that in the _config.yml, or test it manually:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll --server --rdiscount
</code></pre></div></div>
<p>If you haven’t used rdiscount yet, you might get this error message:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>You are missing a library required for Markdown. Please run:
$ [sudo] gem install rdiscount
ERROR: YOUR SITE COULD NOT BE BUILT:
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
Missing dependency: rdiscount
</code></pre></div></div>
<p>In which case you just install rdiscount:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install rdiscount
</code></pre></div></div>
<p>Now if you have minor syntax errors you can fix them manually, but for a full blog conversion the issues may be more prevalent. Let’s do some major cleanup…</p>
<h2 id="cleanup"><a id="Cleanup">Cleanup</a></h2>
<p>While Exitwp is an awesome tool that saves us a lot of time, it couldn’t handle certain things like WordPress Image Caption tags and certain markup syntax.</p>
<p>For the WordPress Image Captions, I ran a simple regex that extracted the caption text into a span tag.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\[caption.*?caption="(.*?)"\]
<span class="caption">$1</span>
</code></pre></div></div>
<p>This isn’t perfect, and I actually went back and manually cleaned these tags up. I ended up taking the caption text and adding it to to title tag of the image, removing it from the visible portion of the page.</p>
<p>For syntax parsing issues, look for markdown or liquid syntax characters, and replace them with HTML entity codes.</p>
<p><em>(you probably wont have that last one unless you work with <a href="/2010/07/16/adding-macro-support-to-kentico-web-parts/">Kentico macros and blogged about it</a>)</em></p>
<p>Markdown parsers should leave HTML content in place, so hopefully you don’t have anymore major issues. If you do, feel free to drop a comment about something others might encounter.</p>
<h3 id="preserving-existing-category-and-tag-links">Preserving existing category and tag links</h3>
<p>Jekyll handles certain things differently than Wordpress. Mainly, your permalinks and category and tag pages may be different. For me, WordPress was creating a dynamic page for each category and tag. Jekyll however, creates a single page for each type:</p>
<p><img src="/assets/images/2012-07-10-how-to-migrate-from-wordpress-to-jekyll-on-github/tags-tag-list.png" alt="" /></p>
<p><img src="/assets/images/2012-07-10-how-to-migrate-from-wordpress-to-jekyll-on-github/tags-tag-posts.png" alt="" /></p>
<p>Ideally we should setup 301 redirects for these pages, but one thing is for sure: pages are going to be missing. Until Google re-indexes your site, users may click search result links to the category and tag pages and get 404’s.</p>
<p>If you’re running your blog off something other than GitHub pages, you can utilize something like an .htaccess file to setup redirects, but for GitHub Pages we can’t do that. Your options are to accept defeat and take the hit to your SEO rank, or manually setup redirects. For the redirect route, read on…</p>
<p>Below is some HTML you can use to redirect an old URL to a new one.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv=refresh content="0; url=/tags.html#IIS7-ref" />
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Redirecting to new location...</title>
<script type="text/javascript"> function delayer() {window.location = "/tags.html#IIS7-ref"} </script>
</head>
<body onLoad="setTimeout('delayer()', 1000)">
<h1>Redirecting to new location...</h1>
</body>
</html>
</code></pre></div></div>
<p>The specific version above will redirect a page to</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/tags.html#IIS7-ref`
</code></pre></div></div>
<p>So all you need to do is place this HTML in a file at the location:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/tags/IIS7/index.html
</code></pre></div></div>
<p>This isn’t perfect, but it’s better than nothing! I found some posts saying that meta refreshes with a 0 timer are now treated as 301 redirects, mainly for people with no access to server-side redirect functionality. I’m not sure if that is true, but at least your users wont see 404 pages. I also included a JavaScript redirection in case our visitors’ browsers don’t support the meta tag, or block it.</p>
<h3 id="mapping-to-a-new-site-structure">Mapping to a new site structure</h3>
<p>If you’re migrating your site structure as is, I’m happy for you and you can skip this part! However, in my case I was removing part of the path to my blog. My posts went from from:</p>
<blockquote>
<p>http://www.johnnycode.com/blog/2012/….</p>
</blockquote>
<p>to</p>
<blockquote>
<p>http://johnnycode.com/2012/…</p>
</blockquote>
<p>Like we did with the tag and category pages, we need to setup redirects for each post link that we want to preserve. To avoid a lot of manual work we can use a Jekyll plugin locally to generate the redirect pages automatically. While the use of plugins on GitHub are out, there isn’t anything stopping us from using them locally!</p>
<p>Take a look at the <a href="https://github.com/jbubriski/jbubriski.github.com/tree/master/_plugins">redirect plugin on GitHub</a>. If you pull that plugin down into your site, and <strong>disable safe mode</strong>, running Jekyll locally will generate the redirect pages. After doing that once, you can copy the pages from the output directory back into your main source directory! In my case, I left the plugin in the plugins directory, but it wont actually run when deployed to GitHub.</p>
<h2 id="deployment"><a id="Deployment">Deployment</a></h2>
<p>Now that we’ve completed the conversion and cleaned up our site we can finally deploy! Simply use Git to commit and push your content to your GitHub Pages repo. Once you push, GitHub will run Jekyll on your content and copy the output to the hosting destination. If the process is successful, you should receive an email like this one:</p>
<blockquote>
<p>Your page has been built. If this is the first time you’ve pushed, it may take a few minutes to appear, otherwise your changes should appear immediately.</p>
</blockquote>
<p>Unfortunately, things don’t always go as planned. In the event of a failure, you will receive an email like this one:</p>
<blockquote>
<p>The page build failed with the following error:</p>
<p>unable to run jekyll</p>
</blockquote>
<p>Yep, that is the entire email! As you can see, there is no indication to what caused the failure. This is why it’s important to first test your site locally and use the correct settings. If you get a failure notice, do a search through your content for markup issues, or start removing posts 1 by 1 until you find the culprit(s). This is how I discovered the leftover caption tags and other weird markup issues.</p>
<h3 id="double-check-everything">Double check EVERYTHING</h3>
<p>While I’m happy with the end result, and I felt good migrating off Wordpress, I lost about 75% of my blog traffic in the process, due to my own stupidity. Before you flip your DNS (int the next section), make sure all your old links still work!. Mainly, make sure your home page, post pages, category/tag pages, and your RSS/Atom feeds work! Even after a month or two I didn’t realize that my feed (via feedburner) was completely broken!</p>
<p>FYI, this is what happens when you F up DNS and/or your RSS/Atom feed:</p>
<p><img src="/assets/images/2012-07-10-how-to-migrate-from-wordpress-to-jekyll-on-github/this-is-what-happens-when-you-f-up-dns.png" alt="" /></p>
<p>See! SEE!?!??!</p>
<h3 id="flip-the-dns-setup-your-cname">Flip the DNS (Setup your CName.)</h3>
<p>Once you verify that your site was successfull deployed, let’s setup our own custom domain. If you don’t have an existing domain, I would recommend <a href="http://www.namecheap.com?aff=32835">NameCheap</a> (discalimer: my affiliate link).</p>
<p>Setting up GitHub Pages to use your custom domain is super easy. All you need to do is push a special file into your repo, and reconfigure your DNS with you registrar.</p>
<p>Per the <a href="http://help.github.com/pages/#custom_domains">GitHub pages doucmentation on custom domains</a>, just create a file called “CNAME” in the root of your site, and add your domain name to it. Mine looked like this:</p>
<blockquote>
<p>johnnycode.com</p>
</blockquote>
<p>Once that is done, push it up to GitHub.</p>
<p>Now go to your domain registrar and find the pages where you can edit your host records. Mine looked like this:</p>
<p><img src="/assets/images/2012-07-10-how-to-migrate-from-wordpress-to-jekyll-on-github/Modifying-my-host-records-on-Namecheap.png" alt="" /></p>
<p>Set the IP address to be <code class="language-plaintext highlighter-rouge">204.232.175.78</code> (Github’s static IP) for the A record of a top-level domain. For subdomains (like www. or blog.) set the CNAME to be [your username].github.com.</p>
<p>Keep in mind that DNS can take a while to propagate. Notice that I set my TTL to 60 seconds. That will make it easy to fix issues later on if we have any. Once you’ve ironed out any DNS issues, set it to something higher like 1800.</p>
<p>After DNS has propagated successfully, you should go into your _config.yml file and change the production_url setting from <code class="language-plaintext highlighter-rouge">username.github.com</code> to your domain name.</p>
<h2 id="conclusion"><a id="Conclusion">Conclusion</a></h2>
<p>The verdict?</p>
<p><a href="http://knowyourmeme.com/photos/138246-obama-rage-face-not-bad"><img src="http://i2.kym-cdn.com/photos/images/original/000/138/246/tumblr_lltzgnHi5F1qzib3wo1_400.jpg" /></a></p>
<p>But don’t take my word for it. You’re looking at a Jekyll powered blog running on GitHub right now! Browse around the site and check out how it works!</p>
<p>The result of this conversion was reasonable port. I started with a self hosted Wordpress blog and ended with a Jekyll powered blog running on GitHub pages along with Disqus for comments. While I didn’t really gain much, it was a great experience and I’m now more familiar with Jekyll and Markdown.</p>
<p>Would I recommend Jekyll and GitHub Pages to others? Here are my official recommendations:</p>
<h3 id="migrating-your-blog">Migrating Your Blog?</h3>
<p><strong>Use caution when converting your existing blog. Be prepared to spend some time working out the kinks.</strong></p>
<h3 id="creating-a-new-blog">Creating a New Blog?</h3>
<p><strong>Go spend 3 minutes to <a href="http://jekyllbootstrap.com/">setup a new blog with Jekyll Bootstrap</a> you lazy bum.</strong></p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="http://help.github.com/pages/">GitHub Pages Help</a></li>
<li><a href="https://github.com/mojombo/jekyll">Jekyll on GitHub</a></li>
<li><a href="https://github.com/thomasf/exitwp">Exitwp on GitHub</a></li>
<li><a href="http://daringfireball.net/projects/markdown/syntax">Markdown reference</a></li>
</ul>
Why I bought a Crucial M4 SSD2012-05-02T09:00:26+00:00http://johnnycode.com/2012/05/02/why-i-bought-a-crucial-m4-ssd<p>(Disclaimer: This is not a completely scientific analysis. My conclusions are based solely on the user reviews on various retail sites. Do not blame me if you Crucial M4 dies. Yes, that is still a possibility just as it is with any SSD, Hard Drive, or any other piece of hardware.)</p>
<p>So far I’ve owned an 80 GB Intel X25-M and I currently own an 115 GB OCZ Vertex 2. Both drives treated me well, but I was looking for more. More space, that is.</p>
<p><img src="/assets/images/2012-05-02-why-i-bought-a-crucial-m4-ssd/Intel-X25-M-SATA-Solid-State-Drive-SSD.png" alt="" title="Intel X25-M SATA Solid State Drive (SSD)" /></p>
<p><img src="/assets/images/2012-05-02-why-i-bought-a-crucial-m4-ssd/vertex2_new_angle_1.png" alt="" title="OCZ Vertex 2" /></p>
<h2 id="why-do-i-need-an-ssd">Why do I need an SSD?</h2>
<p>I wont go into the nitty-gritty detail, but here’s my take:</p>
<p>My sole machine is a laptop, so I don’t have the luxury of multiple drives and <a href="http://www.codinghorror.com/blog/2011/01/24-gigabytes-of-memory-ought-to-be-enough-for-anybody.html">virtually unlimited RAM</a>. I’m limited to one storage drive, and 8 GB of RAM. You may be lucky and have a laptop that has an extra drive bay instead of a CD drive, or one that supports more RAM, but that’s not me, and that’s definitely not everyone. Take a look at the excerpt from the <a href="http://store.steampowered.com/hwsurvey">Steam Hardware & Software Survey</a> below (from March 2012). It’s specific to gamers, but even gamers don’t have the best machines! In my situation, I don’t feel that 8 GB is enough, and an SSD can help relieve the pain.</p>
<p><img src="/assets/images/2012-05-02-why-i-bought-a-crucial-m4-ssd/Steam-Hardware-Software-Survey-Google-Chrome_2012-04-25_13-05-02.png" alt="" title="Steam Hardware & Software Survey - RAM stats" /></p>
<p>Another bonus for laptop users is durability. Apparently these drives can withstand up to 1500 G’s worth of shock. I’m not sure if that is specific to the memory in the drive, or the electronics as well. Either way, the lack of moving parts should make SSD’s significantly more reliable than a spinning disks in the event of a bump, drop, or mischievous 2-year-old. <a href="http://www.hanselman.com/babysmash/">Baby Smash anyone</a>?</p>
<p>What about desktop users who <em>can</em> jam 24 GB of RAM into their machine? Good for you!!! You probably don’t <em>need</em> an SSD with all that RAM. Once you’re machine is up and running and everything is loaded into RAM, you should be good to go. But what about that first load? An SSD would probably help with that, but the cost/benefit ratio is probably not as good.</p>
<p>But don’t take my word (opinion) for it, take a look at the articles below. Note that they’re not super recent, but most of the reasoning for buying an SSD should still be relevant:</p>
<p>Coding Horror (Jeff Atwood):</p>
<ul>
<li><a href="http://www.codinghorror.com/blog/2009/10/the-state-of-solid-state-hard-drives.html">The State of Solid State Hard Drives</a></li>
<li><a href="http://www.codinghorror.com/blog/2010/09/revisiting-solid-state-hard-drives.html">Revisiting Solid State Hard Drives</a></li>
<li><a href="http://www.codinghorror.com/blog/2011/05/the-hot-crazy-solid-state-drive-scale.html">The Hot/Crazy Solid State Drive Scale</a></li>
</ul>
<p>Hanselminutes (Scott Hanselman):</p>
<ul>
<li><a href="http://www.hanselman.com/blog/YourNewYearsResolutionPutAnEndToSpinningRustAndBuyYourselfASSD.aspx">Your New Year’s Resolution - Put an end to spinning rust and buy yourself a SSD</a></li>
<li><a href="http://www.hanselman.com/blog/UpgradingMyLenovoW500ToAOCZVertex250GBSATAIISolidStateDiskSSD.aspx">Upgrading my Lenovo W500 to a OCZ Vertex 250GB SATA II Solid State Disk (SSD)</a></li>
</ul>
<p>More:</p>
<ul>
<li><a href="http://www.joelonsoftware.com/items/2009/03/27.html">Joel Spolsky - Solid State Disks</a></li>
<li><a href="http://forums.anandtech.com/showthread.php?p=29731857&postcount=2">Anandtech Forums - Why buy/use an SSD?</a></li>
</ul>
<h2 id="so-why-a-crucial-m4-and-not-a-insert-model-insert-brand">So why a Crucial M4 and not a [Insert Model] [Insert Brand]?</h2>
<p>There are many other SSD manufacturer’s out there. Some of the most well-known include:</p>
<ul>
<li>OCZ</li>
<li>Intel</li>
<li>Samsung</li>
<li>Kingston</li>
<li>Corsair</li>
</ul>
<p>Here are the factors that landed the Crucial M4 in my shopping cart, and subsequently, my laptop:</p>
<ul>
<li>Reliability</li>
<li>Reliability</li>
<li>Reliability</li>
</ul>
<p>The perceived reliability of the Crucial M4 blows away any other brand/series on the market today, at least from my perspective. Here are the customer rating stats from my 2 favorite online stores:</p>
<p><a href="http://www.amazon.com/Crucial-2-5-Inch-Solid-State-CT256M4SSD2/dp/B004W2JL2A/ref=sr_1_3?ie=UTF8&qid=1335543334&sr=8-3">Amazon</a> - 4.5/5 average rating from 448 reviews
<a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820148443">NewEgg</a> - 5/5 average rating from 145 reviews.</p>
<p>None of the other drives on the market today come close to having the same number of reviews and average rating. Here are some similar 256 Gb drives I looked at:</p>
<p>(Reviews are from Newegg.com at the time of writing. Note that some drives are listed multiple times, probably for different firmware revisions. I only grabbed the ones that had at least 14 reviews.)
Name/Average Rating/Votes</p>
<ul>
<li>5/5, 71 reviews, Samsung 830 Series</li>
<li>5/5, 45 reviews, Corsair Force Series GT</li>
<li>5/5, 31 reviews, Samsung 830 Series</li>
<li>5/5, 30 reviews, Plextor M3 Series</li>
<li>5/5, 20 reviews, Corsair Performance Pro Series</li>
<li>5/5, 15 reviews, Kingston HyperX</li>
<li>4/5, 115 reviews, OCZ Agility 3</li>
<li>4/5, 54 reviews, Mushkin Enhanced Chronos</li>
<li>4/5, 47 reviews, Mushkin Enhanced Chronos Deluxe</li>
<li>4/5, 42 reviews, Intel 510 Series Elm Crest</li>
<li>4/5, 39 Reviews, OCZ RevoDrive 3 X2 Series</li>
<li>4/5, 38 reviews, Mushkin Enhanced Callisto Deluxe</li>
<li>4/5, 27 reviews, OCZ Vertex 3</li>
<li>4/5, 21 reviews, Kingston HyperX</li>
<li>4/5, 19 reviews, Intel 520 Series Cherryville</li>
<li>3/5, 92 reviews, OCZ Vertex 3</li>
<li>3/5, 32 reviews, Corsair Force Series 3</li>
<li>3/5, 23 reviews, Patriot Wildfire</li>
<li>3/5, 23 reviews, OCZ RevoDrive 3 Series</li>
<li>3/5, 14 reviews, OCZ Vertex 2</li>
</ul>
<h2 id="what-about-performance">What about performance?</h2>
<p>According to online benchmarks the Crucial M4 isn’t the fastest kid on the block, <em>but it’s fast enough</em>. It’s much faster than any other spinning disk drive out there, and if you compare it to other SSD’s the difference probably wont be noticeable in real-world scenarios. Check out the reviews if you want to see an in-depth anlysis:</p>
<ul>
<li><a href="http://www.anandtech.com/show/4253/the-crucial-m4-micron-c400-ssd-review">AnandTech Review</a></li>
<li><a href="http://www.tomshardware.com/reviews/m4-ssd-capacity-comparison,2957.html">Toms Hardware Review</a></li>
</ul>
<h2 id="what-about-price">What about price?</h2>
<blockquote>
<p>Money is money, but time is money too! - me</p>
</blockquote>
<p>How much is your time worth? Sure, you can save as much as $100, but the cost of owning an SSD isn’t limited to it’s purchase price. Below I’ve listed some factors that can increase the cost of ownership of your SSD. YMMV (Your mileage may vary), but if your drive dies, any or all of them can come into play:</p>
<h3 id="shipping-time">Shipping time</h3>
<p>Best case you’re probably looking at 2 day shipping both ways. That’s 4 days that you’re working with your old slow hard drive, or someone else’s old busted computer. Or worse yet, you’re not working at all. Not to mention the…</p>
<h3 id="shipping-costs">Shipping costs</h3>
<p>It depends on what brand you buy, where you buy it, and when the drive dies, but those are 3 different factors that can result in shipping charges.</p>
<h3 id="customer-support-headaches-figuratively-and-literally">Customer support headaches (figuratively and literally)</h3>
<p>I wont name names, but take a look at some of the reviews for other SSD’s. A lot of customers complain about drives dying, but some are <em>more</em> frustrated by poor customer service. <a href="http://en.wikipedia.org/wiki/Stress_(psychological)#Stress_responses">Stress is a killer</a>.</p>
<h3 id="re-setup-time">(Re-)Setup time</h3>
<p>It takes time to install your OS, apps, and games, and then restore your data and configuration. Each one of these things can be quick on their own. Windows 7 has a snappy install process, I mostly use free apps, all my games are on Steam, and my data is mostly in the cloud (along with various config files). So what’s the big deal? If you have a good <a href="http://www.johnnycode.com/blog/2012/04/25/my-cloud-backup-strategy/">cloud backup strategy</a> you’re probably fine. But what if you don’t? Hunting for your OS and game disks, downloading apps, and rummaging through external hard drives isn’t my idea of fun. God forbid you don’t have a good backup strategy which results in…</p>
<h3 id="lost-data">Lost data</h3>
<p>Even if you saved/pushed your documents and code an hour ago, that’s still an hour’s worth of work that’s now gone. Worst case is that you didn’t push it today, or this week. If you don’t backup at all you may as well throw your computer out the window and save yourself from all the waiting.</p>
<h3 id="multiple-failures">Multiple failures</h3>
<p>OK, so you RMA’d your broken drive for another… unreliable drive! Sweet! Now you get to go back to the top of the list and re-read this entire section!</p>
<h2 id="so-the-crucial-m4s-are-perfect">So the Crucial M4’s are perfect?</h2>
<p>I can’t tell you that your drive wont fail. I just bought my Crucial M4, so only time will tell how mine fairs. But as I said in my disclaimer at the top of this post, nothing is immune to failure, SSD’s included. However, <strong>I firmly believe the benefits outweigh the risks</strong>. If you do choose to go with a historically less reliable series/brand you’re taking your time and money into your own hands.</p>
<h2 id="other-links">Other Links</h2>
<ul>
<li><a href="http://forums.anandtech.com">Anandtech</a> - My defacto standard for SSD information, guides, and reviews.</li>
<li><a href="http://forums.anandtech.com/showthread.php?t=2069761">Anandtech Forum Post on all things SSD</a> - A great post that can probably answer 99% of the questions you have about SSD’s.</li>
</ul>
Product Review of AutoCode: Visual Studio Code Snippets on Steroids2012-05-02T09:00:25+00:00http://johnnycode.com/2012/05/02/product-review-of-autocode-visual-studio-code-snippets-on-steroids<p>Disclaimer: I did pay $19.95 for this product, but I may receive a complimentary license in return for writing this review (Scroll to the end of the article for more info).</p>
<h2 id="background">Background</h2>
<p>Code snippets in Visual Studio are great. I Code Snippets all the time! My favorite is probably one of the simpler ones: prop. prop will generate the code for an auto-implemented property, and allow you to easily replace the type and property name. The initial generated code looks like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public int MyProperty { get; set; }
</code></pre></div></div>
<p>which you (easily) modify to this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public string FirstName { get; set; }
</code></pre></div></div>
<p>(If you don’t know what I’m talking about go try it out now! RIGHT NOW! In Visual Studio, in a class block type: “prop <Tab> <Tab>")</Tab></Tab></p>
<p>Yeah… they’re great. <a href="/2010/10/18/some-useful-visual-studio-code-snippets/">I’ve even made a bunch of custom Code Snippets</a>. Generally I have ones for:</p>
<ul>
<li>Inserting tasks comments like “// TODO: “.</li>
<li>A jQuery protection function.</li>
<li>SqlConnection and SqlCommand boilerplate using statements and setup.</li>
<li>Dapper boilerplate code.</li>
<li>Prototyping and stubbing out methods.</li>
<li>Other common ASP.NET markup tags.</li>
</ul>
<p>(<em>I want to throw my generic code snippets in a Github repo, but I haven’t gotten around to it yet. I <strong>do</strong> have my <a href="https://github.com/jbubriski/Dapper-Code-Snippets">Dapper snippets on Github</a>.</em>)</p>
<p>But what if you want to do more fancy things? One thing I’ve always dreamed of having was a code snippet that would take a type name and generate this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var myClass = new MyClass();
</code></pre></div></div>
<p>I cringe everytime I write that code because <em>I shouldn’t have to</em>. I tried every which way to support this in a code snippet, but they are simply not powerful enough. This is where AutoCode from <a href="http://www.devprojects.net/">DevProjects.net</a> comes into play.</p>
<h2 id="how-does-autocode-work">How does AutoCode work?</h2>
<blockquote>
<p>AutoCode is Visual Studio Code Snippets on Steroids - me</p>
</blockquote>
<p>Like regular code snippets, AutoCode snippets allow for templates and replacements, but they also allow <em>code</em> to be run. Much like a T4 template, they take a template, combine it with some potential input, and generate code from it. T4 templates are usually added directly to a project or triggered by Visual Studio for the creation of files. <a href="http://blogs.msdn.com/b/webdevtools/archive/2009/01/29/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers.aspx">ASP.NET MVC makes extensive use of T4 Templates</a>. AutoCode brings the power of T4 to your fingertips. When you press Ctrl+Enter it brings up an intellisense-like dialog:</p>
<p><img src="/assets/images/2012-05-02-product-review-of-autocode-visual-studio-code-snippets-on-steroids/AutoCode-Intellisense-Dialog.png" alt="" title="AutoCode Intellisense Dialog" /></p>
<p>From there, the dialog will guide you with the available snippet shortcuts and their usage. The built in snippets cover most general needs like:</p>
<ul>
<li>Creating properties</li>
<li>Variable assignments</li>
<li>Stubbing out classes and methods</li>
<li>Code statement shortcuts</li>
</ul>
<h2 id="lets-kick-it-up-a-notch">Let’s kick it up a notch!</h2>
<p>But why limit yourself to individual properties and methods? The “classa” shortcut will create an entire class from a single command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int userId string firstName string lastName person classa
</code></pre></div></div>
<p>results in…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class Person
{
public Person()
{
}
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
</code></pre></div></div>
<p>And for those with a careful eye, you did notice my “incorrect” casing in the command, right? The command contained (lower) <a href="http://en.wikipedia.org/wiki/CamelCase">Camel Cased</a> names, but AutoCode is smart enough to translate it into <a href="http://c2.com/cgi/wiki?PascalCase">Pascal Casing</a>!</p>
<h2 id="but-wait-theres-more">But wait, there’s more!</h2>
<p>AutoCode doesn’t stop at templates and replacements. It also contains additional commands for things like:</p>
<ul>
<li><a href="http://www.devprojects.net/gallery/catalog/refactor">Method Refactoring</a></li>
<li><a href="http://www.devprojects.net/gallery/catalog/clipboard">Clipboard Assistance</a></li>
<li><a href="http://www.devprojects.net/gallery/catalog/tools">Code Evaluation</a></li>
<li><a href="http://www.devprojects.net/gallery/catalog/autocode">Creation of custom AutoCode snippets</a></li>
<li><a href="http://www.devprojects.net/gallery/catalog/exec">Commenting/Uncommenting</a></li>
<li><a href="http://www.devprojects.net/gallery/catalog/exec">Closing documents</a></li>
</ul>
<p>Some of these, like method refactoring commands, simply execute IDE commands, but if you’re not familiar with the Visual Studio shortcuts, this can still be helpful.</p>
<h2 id="editions">Editions</h2>
<p>AutoCode comes in 2 versions, Standard and Professional, and this is where we come to my 2 criticisms. The first problem is that the Standard Edition is free but it’s practically unsuable. Every time a command is executed a little “nagger” popup will appear. This really hampers a dev’s ability to gain any benefit from the Standard Edition, and more importantly, evaluate the product for purchase of the Professional Edition. Which brings me to my next criticism…</p>
<p>The “trial” version is annoying but I decided to take my chances and purchase the Professional Edition immediately. But instead of purchasing it for $19.95, I was required to <em>donate</em> $19.95 to get my activation code. I guess this is sort of splitting hairs, but it feels weird that someone accepting donations is forcing me to donate a certain amount of money. Why not simply put a normal price tag on it? I’m not sure if this was done to appear humble, for fee/tax reasons, or for some other reason. Again, I’m probably splitting hairs.</p>
<h2 id="conclusions">Conclusions</h2>
<p>Buy it. It’s only $19.95.</p>
My Cloud Backup Strategy2012-04-25T09:00:26+00:00http://johnnycode.com/2012/04/25/my-cloud-backup-strategy<p>Not going to go into <em>why</em> you should backup, but here is how I handle the things that matter to me: Code, Documents, PC Games, and Photo and Video.</p>
<h2 id="code">Code</h2>
<p>This one is pretty much a no-brainer for me. Use <a href="https://bitbucket.org/">Bitbucket</a> to host your private repositories for free, and use <a href="https://github.com/">GitHub</a> to host your public ones.</p>
<h2 id="documents-and-other-miscellaneous-files">Documents and other miscellaneous files</h2>
<p>Some prefer Microsoft, Google, or another company. Take your pick (numbers from time of writing):</p>
<ul>
<li><a href="https://skydrive.live.com">Microsoft SkyDrive</a> - 7 Gb free</li>
<li><a href="https://drive.google.com/">Google Drive</a> - 5 Gb free</li>
<li><a href="http://db.tt/Cr4Jtd0">Dropbox</a> - 2 GB free (plus referral bonuses)</li>
</ul>
<h2 id="pc-games">PC Games</h2>
<p>Just use <a href="http://store.steampowered.com/">Steam</a>.</p>
<h2 id="photo-and-video">Photo and Video</h2>
<p>I have a <a href="http://www.flickr.com">Flickr</a> <a href="http://www.flickr.com/account/order">Pro Account</a>. For $25/year you get:</p>
<ul>
<li>Unlimited uploads and storage</li>
<li>Unlimited sets and collections</li>
<li>Access to your original files</li>
<li>Stats on your account</li>
<li>Ad-free browsing and sharing</li>
<li>HD video uploads & playback</li>
</ul>
<p>Their upload download procedures aren’t super smooth, but I mostly do uploads and the <a href="http://www.flickr.com/tools/uploadr/">Flickr Uploadr</a> makes that pretty easy. I tried out <a href="https://picasaweb.google.com">Google’s Picasa</a> a while back, but with my massive collection of family photos it was getting very expensive very fast.</p>
<p>I also have a <a href="http://www.synology.com/us/products/DS211j/index.php">Synology DS211J NAS</a> that I use to store all my photos and videos in house. If you edit/view/print your photos a lot, having this local network copy/cache will help out a lot.</p>
<p>Bonus: I have 2 projects on <a href="https://github.com/jbubriski">Github</a> relating to photo management.</p>
<p><a href="https://github.com/jbubriski/Organize-My-Photos">“Organize My Photos”</a> aims to organize all of your local photos into folders by date. It’s a really basic/ugly implementation in Winforms, but it works for my purposes.</p>
<p><a href="https://github.com/jbubriski/Organize-My-Flickr-Photos">“Organize My Flickr Photos”</a> aims to keep your photos “backed up” to Flickr, avoiding duplication. I don’t think this code is fully functional right now. Last I checked I was fighting with the limitations of the Flickr API. Once over those hurdles it shouldn’t be too much work to get some nice sync action going on.</p>
Serializing Circular References with JSON.Net and Entity Framework2012-04-10T13:58:25+00:00http://johnnycode.com/2012/04/10/serializing-circular-references-with-json-net-and-entity-framework<h2 id="the-setup">The Setup</h2>
<p>You’re building a <a href="http://en.wikipedia.org/wiki/Representational_state_transfer">RESTful</a> web service, and your technology stack looks something like this:</p>
<ul>
<li>ASP.NET MVC 4 w/ Web API</li>
<li>Entity Framework Code First (I’m on 4.3.1, available via Nuget)</li>
<li><a href="http://james.newtonking.com/pages/json-net.aspx">Newtonsoft JSON.Net</a> (I’m on 4.5.1, available via Nuget)</li>
</ul>
<p>We’ll pull the data out of the database using EF and <a href="http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx">setup the ASP.NET Web API to use the JSON.Net library to handle serialization/deserialization</a>. To make your life easier you could <a href="https://github.com/jbubriski/ST4bby/">use ST4bby to do the heavy lifting and generate your POCO’s</a>.</p>
<p>Piece of cake, right?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A circular reference was detected while serializing an object of type ...
</code></pre></div></div>
<p>False.</p>
<h2 id="the-problem">The Problem</h2>
<p>Circular reference exception??? Oh dear God, haven’t we figured this out yet???</p>
<p>Let’s start from the beginning.</p>
<p>You’ve setup JSON.Net as your default formatter, right? In case you haven’t done that <a href="http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx">grab the JsonNetFormatter from Henrik’s blog</a> and enable it in the Application_Start method in the Global.asax:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonNetFormatter(new JsonSerializerSettings()));
</code></pre></div></div>
<p>That’s right, we blew away all the formatters, including the XML one and we’re not looking back.</p>
<p>Now let’s look at a simple example of serialization of relational collections, without EF. Below is a simple class which can hold references to other instances of the same class:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class Bro
{
public int BroId { get; set; }
public string Name { get; set; }
public List<bro> Bros { get; set; }
public Bro()
{
Bros = new List<bro>();
}
}
</code></pre></div></div>
<p>Not rocket science. A Bro can have many Bros, right? A more common example would involve Parent/Child relationships, but this is simpler and demonstrates the same issue. Now let’s expose our Bros to the world via an ASP.NET Web API Controller:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class BrosController : ApiController
{
public IEnumerable<bro> Get()
{
var john = new Bro { Name = "John" };
var jared = new Bro { Name = "Jared" };
john.Bros.Add(jared);
jared.Bros.Add(john);
return new List<bro> { john, jared };
}
}
</code></pre></div></div>
<p>Again, not rocket science. If you’re unfamiliar with ASP.NET Web API, this is just like an ASP.NET MVC controller, except that it will handle all of the HTTP/REST stuff for you. The JSON.Net formatter will kick in and serialize our collection of Bros to JSON. Right? Almost.</p>
<p>If you’ve corretly setup our custom JsonNetFormatter, you’re going to get an exception about a circular reference:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Self referencing loop detected for type 'EntityFrameworkCodeFirstWithJsonSerialization.Bro'.
</code></pre></div></div>
<p>If you didn’t setup the JsonNetFormatter, I think that your page is gonna spin until the call stack fills up and you get a <a href="http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx">StackOverflowExpception</a>.</p>
<p>So what gives? Isn’t it the year 2012? Shouldn’t we have figured out a way to serialize this data? Yes we should have, and yes we have.</p>
<h2 id="the-solution">The Solution</h2>
<p>After a lot of searching, I finally found this page in the docs:</p>
<p><a href="http://james.newtonking.com/projects/json/help/">http://james.newtonking.com/projects/json/help/</a> under Serializing and Deserializing JSON -> Serialization and Preserving Object References (or <a href="http://james.newtonking.com/projects/json/help/PreserveObjectReferences.html">Direct link with no navigation</a>)</p>
<p>Which explains to set this setting:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PreserveReferencesHandling = PreserveReferencesHandling.Objects
</code></pre></div></div>
<p>… in order to… you guessed it, preserve references! JSON.Net <em>is</em> smart enough to detect the circular references, but since the default functionality is to serialize by value, it gives up so you don’t get StackOverflowExceptions!</p>
<p>So now your Application_Start method in the global.asax looks more like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var jsonSerializerSettings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonNetFormatter(jsonSerializerSettings));
</code></pre></div></div>
<p>And your Web API Controller works, spitting out JSON like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[
{
"$id": "1",
"BroId": 0,
"Name": "John",
"Bros": [
{
"$id": "2",
"BroId": 0,
"Name": "Jared",
"Bros": [
{
"$ref": "1"
}
]
}
]
},
{
"$ref": "2"
}
]
</code></pre></div></div>
<p>Isn’t that awesome! To be honest, I never knew JSON was so smart! In case you don’t understand what’s happening, JSON.Net is taking the extra step to setup each reference with an additional meta-property called “$id”. When JSON.Net encounters the same instance in another place in the object graph, it simply drops a reference to the original instance, instead of duplicating the data, and causing circular reference issues!</p>
<h2 id="what-about-entity-framework">What about Entity Framework</h2>
<p>You said you were going to help me with my Entity Framework Code First problem!</p>
<p>Funny story: regular EF doesn’t have a problem with this! In fact, it handles it beautifully! All your references to parent and child objects are preserved and your JSON will look like what we saw above!</p>
<p>To “Fix” Code First we need to understand what it is abstracting away for us, and do a little bit more work (nothing you can’t handle dear reader!). If you already tried the above setting on your project you’ll notice that you now get a different Exception that looks something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.
</code></pre></div></div>
<p>OK, so we traded one issue for another… or did we?</p>
<p>If we step back for a minute, we’ll remember that when we read <a href="http://www.amazon.com/gp/product/1449312942/ref=as_li_ss_tl?ie=UTF8&tag=johcod-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1449312942">Julia Lerman’s book on Programming Entity Framework: Code First</a><img src="http://www.assoc-amazon.com/e/ir?t=johcod-20&l=as2&o=1&a=1449312942" alt="" /> it said that Code First generates proxy classes for us, even though we have our POCO’s (actually I don’t think she references the proxy objects in that book, but you should buy it anyway because she’s awesome and that’s a referral link)! So JSON.Net sees these weird proxy classes instead of our actual POCO’s. When it tries to serialize those proxy classes, all Hell breaks lose because the proxy classes are <em>dynamic</em> proxy classes, as in <a href="http://msdn.microsoft.com/en-us/library/dd264741.aspx">the dynamic keyword</a>.</p>
<p>So what’s a Dev to do? Disable Proxy Generation!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using(var yourDbContext = new YourDbContext())
{
yourDbContext.Configuration.ProxyCreationEnabled = false;
return ...
}
</code></pre></div></div>
<p>Now our EF Code First setup works!</p>
<p>But what did I just enable/disable/break?</p>
<blockquote>
<p>When proxy object creation is enabled for POCO entities, changes that are made to the graph and the property values of objects are tracked automatically by the Entity Framework as they occur. For information about change tracking options with and without proxies, see Tracking Changes in POCO Entities.</p>
</blockquote>
<p>Therefore, when proxy object creation is <em>disabled</em>, changes are not tracked automatically. If you can live with that, then you’re all set!</p>
How to Scrape Amazon Wishlists in 1 Line of C#2012-03-19T08:00:02+00:00http://johnnycode.com/2012/03/19/how-to-scrape-amazon-wishlists-in-1-line-of-c<p>So I started a new open source project called <a href="https://github.com/jbubriski/Shing">Shing</a>. It’s goal is simple: Scrape an Amazon Wishlist, get all the Product ID’s and generate the Amazon short links to the products.</p>
<p>I was showing the code to my colleagues when Joey, a friend and former coworker, offered some suggestions to improve the code. This is the original working prototype, thrown together in about 5 minutes:</p>
<p><em>Note: the code below isn’t quite complete. It’s just a simple Regex that finds product links on the wishlist page. There can be other product links on the wishlist page like related products. Just a heads up.</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>string _regex = "/dp/(.*?)/";
/// <summary>
/// Returns a list of product ID's
/// </summary>
/// <returns></returns>
public List<string> Scrape(string urlToScrape)
{
var webClient = new WebClient();
var content = webClient.DownloadString(urlToScrape);
var matches = Regex.Matches(content, _regex);
var productIds = new List<string>();
foreach (Match match in matches)
{
productIds.Add(match.Groups[1].Value);
}
return productIds;
}
</code></pre></div></div>
<p>And here was his suggested version:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private const string WishListRegex = "/dp/(.*?)/";
/// <summary>
/// Returns a list of product ID's
/// </summary>
/// <returns></returns>
public IEnumerable<string> Scrape(string urlToScrape)
{
var content = new WebClient().DownloadString(urlToScrape);
var matches = Regex.Matches(content, WishListRegex);
foreach (Match match in matches)
{
yield return match.Groups[1].Value;
}
}
</code></pre></div></div>
<p>His code returns the exact same results but a few minor differences make it worthwhile.</p>
<ul>
<li><strong>The regex is a constant</strong> - This should make the code a little more efficient by not creating a string every time the Scrape() method is called.</li>
<li>**Scrape() returns an IEnumerable<string>** - This allows for the next one which is...</string></li>
<li><strong>Scrape() incorporates the <em>yield</em> keyword</strong> - This should make the code much more efficient in certain scenarios. Instead of creating a List in memory and then returning the entire thing at the end, the method will simply return results as you ask for them. This should reduce memory consumption and speed things up as well, again, if used correctly.</li>
</ul>
<p>But why stop there? Just make it a one-liner</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>return Regex.Matches(new WebClient().DownloadString(urlToScrape), "/dp/(.*?)/").Cast<match>().ToList().Select(m => m.Groups[1].Value);
</code></pre></div></div>
<p><strong>This is purely for fun. I would never do this except as a joke.</strong></p>
<p>The code should produce the same results, except that the regex isn’t a constant, and yield isn’t incorporated. Fun though.</p>
Getting a List of Alternative Forms2012-02-28T08:00:01+00:00http://johnnycode.com/2012/02/28/getting-a-list-of-alternative-forms<p>I forget why I needed to do this, but I was doing some heavy development around <a href="http://www.kentico.com/">Kentico</a>’s <a href="/tags.html#Kentico BizForms-ref">BizForm</a>’s at the time and needed to pull back a list of alternative forms for a given BizForm. It’s not very complex, but it might not be obvious if you’re not familiar with Kentico’s database structure and their use of classes.</p>
<p>Anyway, here is the code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SELECT ca.FormID, ca.FormDisplayName
FROM CMS_Class cc
JOIN CMS_AlternativeForm ca ON ca.FormClassID = cc.ClassID
WHERE cc.ClassName = 'BizForm.ContactUs'
</code></pre></div></div>
<p>Let me know if this helped you!</p>
Logging Events with Kentico2012-02-27T08:00:47+00:00http://johnnycode.com/2012/02/27/logging-events-with-kentico<p>Developing a custom web part or module and want to log some events into the Kentico Event Log? Here is some sample code to get you started.</p>
<p>Logging Exceptions:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var eventLogProvider = new EventLogProvider();
eventLogProvider.LogEvent("E", eventName, ex);
</code></pre></div></div>
<p>Logging Custom Events:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var eventLogProvider = new EventLogProvider();
eventLogProvider.LogEvent("E", DateTime.Now, "source", "code");
</code></pre></div></div>
<p>FYI, I believe that the <code class="language-plaintext highlighter-rouge">EventLogProvider</code> has some static methods on it to log events, but I thing they are the more verbose versions of the methods above. Happy logging!</p>
Using HttpClient to Consume ASP.NET Web API REST Services2012-02-23T08:00:34+00:00http://johnnycode.com/2012/02/23/consuming-your-own-asp-net-web-api-rest-service<p>So you installed the <a href="http://www.asp.net/mvc/mvc4">ASP.NET MVC 4 Beta</a> and followed the <a href="http://www.asp.net/web-api">Web API introduction</a> over at the <a href="http://www.asp.net">ASP.NET website</a>. Great! You now have a nice HTTP based API that plays nicely with jQuery and other client side JavaScript libraries, and even other server-side technologies. But how exactly do we perform server side consumption of that API in .NET?</p>
<p><strong>**UPDATE</strong>**</p>
<p><strong>I updated the post and the examples with the full code for making GET’s, POST’s, PUT’s, and DELETE’s. I didn’t have much time, so let me know if there are any mistakes/issues.</strong></p>
<p>Let’s say that you want to build an uber-flexible n-tier architecture for your next great app. One option for decoupling your layers is to build them as web services. That way you not only decouple the code relationships, but you decouple the platforms as well.</p>
<p>For example, if you build your BLL (Business Logic Layer) as a web service any platform can interact with it. Your presentation layer can be a MVC site, a WPF app, a mobile app, or anything else you can think up. The only requirement is that the front end be able to reach the web service and correctly talk to it.</p>
<h2 id="wheres-the-meta-data">Where’s the meta data???</h2>
<p>How are we going to generate the proxy classes for this new web service??? I’m not going to lie and say that your old friend the “Add Service Reference…” dialog is going to be able to help you out here. Because this is a simple HTTP based API, no meta data gets generated about the API itself (at least as far as I know, and at the time of writing this post).</p>
<p>While I love the “automagical” nature of the “Add Service Reference…” dialog, it always scared me a little bit. It hid a lot of code and required an active instance of the web service to be up and running somewhere (locally was fine). Now, we have complete control over the serialization and deserialization of the data and can write more testable code (more on that later).</p>
<h2 id="show-me-the-frickin-code">Show me the frickin’ code!</h2>
<p>Attached is a working sample solution that demonstrates my examples below.</p>
<p>First, create a new ASP.NET MVC 4 project and select the Web API template. I called mine “WebApi”:</p>
<p><a href="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/New-ASP.NET-MVC-4-Project-Dialog.png"><img src="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/New-ASP.NET-MVC-4-Project-Dialog.png" alt="" /></a></p>
<p>After the solution loads let’s make sure that our web service is in an accesible location. Open up the project Properties > Web and then set the Specific Page to be “Values” and the Specific Port to be 9000. We’ll reference that port in our test consumer in a minute:</p>
<p><a href="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/Web-API-Project-Settings.png"><img src="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/Web-API-Project-Settings.png" alt="" /></a></p>
<p>You can test out the default API by just hitting F5. The local web service URL (http://localhost:9000/api/values) should open in your default browser and you should see some XML (The styling may be different in your browser):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><string>value 1</string>
<string>value 2</string>
</code></pre></div></div>
<p>(Note: If you want to see the JSON, you can send an HTTP “Accept Header”. The Web API will see this and spit back your data serialized to JSON. Make sure you use this header when making requests from jQuery. Check out the <a href="http://www.asp.net/web-api">ASP.NET Web API Introduction</a> for an example, or use <a href="http://fiddler2.com/fiddler2/">Fiddler</a>.)</p>
<p>When you ran your project, a route defined in the Global.asax sent your request to the ValuesController in the Controllers folder. In the ValuesController, the request matched the first action via the HTTP request method verb and the parameters. To see this in action try going to http://localhost:9000/api/values/5. Additionally, requests can be mapped by name too.</p>
<p>So far so good. Let’s spice up the API a little bit and return our own custom type. Create a new class library project within your solution. I called mine “WebApi.Dal”. Rename the deafult “class1.cs” to “MyDataClass.cs” and let Visual Studio auto update the references. Now add some properties. Mine ended up like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WebApi.Dal
{
public class MyDataClass
{
public string MyProperty1 { get; set; }
public bool MyProperty2 { get; set; }
public int MyProperty3 { get; set; }
public decimal MyProperty4 { get; set; }
}
}
</code></pre></div></div>
<p>Now let’s switch back to the Web API project. Add a reference to your DAL project and replace the first controller action with this one:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// ... usings, namespace and class/controller declarations.
// GET /api/values
public MyDataClass Get()
{
return new MyDataClass
{
MyProperty1 = "Property 1", // String
MyProperty2 = true, // Bool
MyProperty3 = 987654, // Integer
MyProperty4 = 100.87m // Decimal
};
}
// Rest of the class/controller definition...
</code></pre></div></div>
<p>Now run the solution again and you should see this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><mydataclass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<myproperty1>Property 1</myproperty1>
<myproperty2>true</myproperty2>
<myproperty3>987654</myproperty3>
<myproperty4>100.87</myproperty4>
</mydataclass>
</code></pre></div></div>
<p>Great! Piece of cake! Now back to the problem at hand.</p>
<h2 id="consuming-the-web-api-service">Consuming the Web API Service</h2>
<p>Back in Visual Studio create a Console Application project. I called mine “WebApi.Tester”. <strong>Add a reference to the WebApi.Dal project, but you don’t need to add one to the WebApi project</strong>. Having access to the classes that were used to serialize the Web API data will allow us to deserialize the data easily, and we don’t need any “direct” relation to the web service itself, just the data it provides.</p>
<p>In the Nuget Package Manager search for System.Net.Http and install the package that matches that name (a bunch of other results show up, but get the one from Microsoft) and the one that matches the name with “Formatter” on the end.</p>
<p>Then search for “json” and add the Json.NET package from Newtonsoft.</p>
<p>Then Add a Reference to System.Net.Http.Formatting and System.Json.</p>
<p>Now you should now have references to:</p>
<ul>
<li>Newtonsoft.Json</li>
<li>System.Json</li>
<li>System.Net.Http</li>
<li>System.Net.Http.Formatting</li>
<li>System.Net.Http.WebRequest</li>
<li>WebApi.Dal</li>
</ul>
<p>When we go to test this setup, we want both the WebApi MVC project to run, as well as the WebApi.Tester Console app. To do that, open up the Solution Properties, check the radio button that says “Multiple startup projects”, and set WebApi and WebApi.Tester as startup projects:</p>
<p><a href="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/Setting-Multiple-Startup-Projects-in-Visual-Studio.png"><img src="/assets/images/2012-02-23-consuming-your-own-asp-net-web-api-rest-service/Setting-Multiple-Startup-Projects-in-Visual-Studio.png" alt="" /></a></p>
<p>Now we are ready to write some code. Here is a base client class I whipped up that provides a generic interface to the Web API service:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class BaseClient
{
protected readonly string _endpoint;
public BaseClient(string endpoint)
{
_endpoint = endpoint;
}
public T Get()
{
using (var httpClient = new HttpClient())
{
T result = default(T);
Task responseTask = null;
httpClient.GetAsync(_endpoint).ContinueWith((requestTask) =>
{
responseTask = requestTask;
HttpResponseMessage response = requestTask.Result;
response.EnsureSuccessStatusCode();
response.Content.ReadAsAsync().ContinueWith((readTask) =>
{
result = readTask.Result;
});
});
// HACK: My version of the await keyword
while (responseTask == null || !responseTask.IsCompleted || result == null) { }
return result;
}
}
}
</code></pre></div></div>
<p><strong>(Important: As of this writing, the above code may fail. Keep reading for a solution.)</strong></p>
<p>So about that code above… it doesn’t always work… It appears that there is some issue with the deserializer and I get the following exception when reading the result from the inner async method:</p>
<blockquote>
<p>“The input stream contains too many delimiter characters which may be a sign that the incoming data may be malicious.”</p>
</blockquote>
<p>Basically, there is some sort of “security” measure in place in case the data is too big and there are too many delimiters.</p>
<p>Not to worry, I got your back! Just substitute that inner async call with this one, which delegates the deserialization to the Newtonsoft JSON library!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>response.Content.ReadAsStringAsync().ContinueWith((readTask) =>
{
result = JsonConvert.DeserializeObject(readTask.Result);
});
</code></pre></div></div>
<p>I asked about the above issue on the official ASP.NET forums and I got a response on <a href="http://forums.asp.net/p/1772531/4845321.aspx">this thread</a>. It looks like you just need to set the <code class="language-plaintext highlighter-rouge">SkipStreamLimitChecks </code>static property to true on the MediaTypeFormatter class. As of this writing, I haven’t tested that solution but I left the commented samples intact in case you want to give it a go.</p>
<p><em>But let’s be honest with eachother</em>. You think that code is ugly. It <strong><em>is</em></strong> ugly, it’s not just you. So I started another thread about how to reign that code in and clean it up. I got a great response from a guy in <a href="http://forums.asp.net/p/1772530/4845269.aspx">this thread</a>. Since the async code is so ugly in .NET 4, and in my case it wasn’t really needed, I left it out. So the first return is the one that executes in the example and it’s still using Newtonsoft JSON:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public T Get()
{
using (var httpClient = new HttpClient())
{
var response = httpClient.GetAsync(_endpoint).Result;
// This works:
return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
// This may not work:
return response.Content.ReadAsAsync().Result;
// This may not work:
return response.Content.ReadAsOrDefaultAsync().Result;
}
}
</code></pre></div></div>
<p>So now my code is a lot shorter, cleaner and easier to grok. For now we’re basically skipping the async stuff, but I think that’s a smart decision until we can leverage the <code class="language-plaintext highlighter-rouge">await</code> keyword and all it’s compiler magic. For a quick sample of how the await keyword in .NET 4.5 relates to the Web API, check out this post by the architect behind all this stuff, <a href="http://blogs.msdn.com/b/henrikn/archive/2012/02/16/httpclient-is-here.aspx">Henrik F Nielsen</a>.</p>
<h2 id="sample-solution">Sample Solution</h2>
<p>I threw together a simple sample solution that is a complete working example. Nuget package restore is enabled and I removed all the packages to make the zip file as small as possible. The first build of the solution will take a minute because it has to go fetch all the packages and their dependencies. Let me know if you have any problems running the code.</p>
<p><a href="http://www.johnnycode.com/blog/wp-content/uploads/2012/02/WebApi_v2.zip">Web API with HttpClient Sample Solution</a></p>
<p>In case you don’t feel like downloading the zip, the full relevant code from the solution is below:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class BaseClient
{
protected readonly string _endpoint;
public BaseClient(string endpoint)
{
_endpoint = endpoint;
}
public T Get<t>(int top = 0, int skip = 0)
{
using (var httpClient = new HttpClient())
{
var endpoint = _endpoint + "?";
var parameters = new List<string>();
if (top > 0)
parameters.Add(string.Concat("$top=", top));
if (skip > 0)
parameters.Add(string.Concat("$skip=", skip));
endpoint += string.Join("&", parameters);
var response = httpClient.GetAsync(endpoint).Result;
return JsonConvert.DeserializeObject<t>(response.Content.ReadAsStringAsync().Result);
}
}
public T Get<t>(int id)
{
using (var httpClient = NewHttpClient())
{
var response = httpClient.GetAsync(_endpoint + id).Result;
return JsonConvert.DeserializeObject<t>(response.Content.ReadAsStringAsync().Result);
}
}
public string Post<t>(T data)
{
using (var httpClient = NewHttpClient())
{
var requestMessage = GetHttpRequestMessage<t>(data);
var result = httpClient.PostAsync(_endpoint, requestMessage.Content).Result;
return result.Content.ToString();
}
}
public string Put<t>(int id, T data)
{
using (var httpClient = NewHttpClient())
{
var requestMessage = GetHttpRequestMessage<t>(data);
var result = httpClient.PutAsync(_endpoint + id, requestMessage.Content).Result;
return result.Content.ReadAsStringAsync().Result;
}
}
public string Delete(int id)
{
using (var httpClient = NewHttpClient())
{
var result = httpClient.DeleteAsync(_endpoint + id).Result;
return result.Content.ToString();
}
}
protected HttpRequestMessage GetHttpRequestMessage<t>(T data)
{
var mediaType = new MediaTypeHeaderValue("application/json");
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.Converters.Add(new IsoDateTimeConverter());
var jsonFormatter = new JsonNetFormatter(jsonSerializerSettings);
var requestMessage = new HttpRequestMessage<t>(data, mediaType, new MediaTypeFormatter[] { jsonFormatter });
return requestMessage;
}
protected HttpClient NewHttpClient()
{
return new HttpClient();
}
}
</code></pre></div></div>
<h2 id="resources">Resources</h2>
<ul>
<li>
<p><a href="http://www.asp.net/web-api">Web API Section on ASP.NET</a></p>
</li>
<li>
<p><a href="http://blogs.msdn.com/b/henrikn/">Henrik F Nielsen’s Blog</a></p>
</li>
<li>
<p><a href="http://forums.asp.net/1246.aspx/1?Web+API">ASP.NET Web API Forums</a></p>
</li>
</ul>
Get BizForm Record ID2012-02-22T08:00:38+00:00http://johnnycode.com/2012/02/22/get-bizform-record-id<p>Here is a post I wanted to write a few months ago while I was actively developing <a href="http://www.kentico.com/">Kentico</a> based websites, but I never got the chance to finish it. The code should be solid, and I’ll explain it as best I can.</p>
<p>If you’re working with <a href="/tags.html#Kentico BizForms-ref">BizForm’s</a> programmatically you’re going to need to get the ID of a specific row so you can update or delete it. If you know the table structure, there’s nothing stopping you from going straight to the database, but if you do it using Kentico API’s and queries the code should be more upgrade-friendly.</p>
<p>This code makes some minor assumptions that are hard coded, but could be easily abstracted out:</p>
<ul>
<li>The BizForm’s code name is “ContactUs” with an ID field (Primary Key) of “ContactUsId”.</li>
<li>I’m using a hard-coded where condition getting the first record. This could easily be changed to pass in another parameter to search on.</li>
</ul>
<p>Without further ado, here’s the code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public int GetRecordId()
{
// Given the Code Name of the BizForm and the current site, get the BizForm object.
var bizFormInfo = BizFormInfoProvider.GetBizFormInfo("ContactUs", uxBizForm.SiteName);
if (bizFormInfo != null)
{
var dataClassInfo = DataClassInfoProvider.GetDataClass(bizFormInfo.FormClassID);
if (dataClassInfo != null)
{
// Using the built in Select query, get the record we're looking for.
var connection = ConnectionHelper.GetConnection();
var whereCondition = String.Format("ContactUsId = '1'");
var dataSet = connection.ExecuteQuery(dataClassInfo.ClassName + ".selectall", null, whereCondition);
// Note the use of Kentico's aptly named DataHelper class.
if (!DataHelper.DataSourceIsEmpty(dataSet) && dataSet.Tables[0].Rows.Count == 1)
{
return ValidationHelper.GetInteger(dataSet.Tables[0].Rows[0][0], 0);
}
}
}
// If we get here, we didn't find a valid record.
// If we get here you should probably do one of the following:
// Redirect to the "new record" page
// Redirect to an error page
// Or throw an exception
return 0;
}
</code></pre></div></div>
How to Recursively Get Files in C# the Easy Way2012-02-21T08:00:37+00:00http://johnnycode.com/2012/02/21/how-to-recursively-get-files-in-c-the-easy-way<p>Need to get all the files contained in a directory, recursively searching through sub directories? No problem!</p>
<p>Here is how to do it without writing your own recursive function:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var fileNames = Directory.GetFiles(directoryName, "*.*", SearchOption.AllDirectories);
</code></pre></div></div>
<p>That’s it! No explicit recusrion required!</p>
<p>If you want to do searching where you can stop when a given file is found, then you would need to implement the recursion yourself. This article shows you how to do that if needed:</p>
<p><a href="http://support.microsoft.com/kb/303974">How to recursively search directories by using Visual C#</a></p>
Filtering Out Linked Documents2012-02-21T08:00:36+00:00http://johnnycode.com/2012/02/21/filtering-out-linked-documents<p>Note: I wanted to add some screenshots to this post, but didn’t have the time. I don’t think it’s super important, but it would definitely help outline the potential issue with Linked Documents.</p>
<p>Linked Documents are a great feature of Kentico. They allow you to create a page that is essentially a shortcut to another page in the content tree. To create a linked document you simply create a new document, and you select “Linked Document” instead of selecting a document type. If you’re not familiar with the functionality, check out the <a href="http://devnet.kentico.com/docs/devguide/index.html?creating_a_linked_document.htm">well-written docs</a>.</p>
<p>While linked documents provide some great functionality they can also cause a duplication issue. If you’re using a Repeater to select a path that contains both the original and the linked document, both will appear in the list!</p>
<h2 id="repeaters">Repeaters</h2>
<p>Fixing this with a repeater is easy. Simply configure the repeater and check the box that says “Filter out duplicate documents”!</p>
<p>Piece of cake!</p>
<h2 id="other-list-controls">Other List Controls</h2>
<p>But what about menu web parts like the CSS List Menu or Drop Down Menu? This is a little trickier since they don’t have options to automatically filter out the linked documents. Instead we can do it using a simple SQL Where clause. If a document is a Linked Document, the “NodeLinkedNodeID” field in the CMS_Tree table will be the ID of the original Tree Node. So we can use this as the Where clause for the menu web part:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>NodeLinkedNodeId IS NULL"
</code></pre></div></div>
<p><strong>(Note: you don’t need to put “WHERE” at the beginning of the where clause when configuring Kentico controls)</strong></p>
<p>Another piece of cake!</p>
Introducing Encryptamajig, Symmetric Encryption in C# using AES2012-02-15T08:00:30+00:00http://johnnycode.com/2012/02/15/symmetric-encryption-in-c-using-aes<p>This isn’t my normal type of “full” post. Rather, I wanted to plug my own project which attempts to “standardize” the way people do <a href="http://en.wikipedia.org/wiki/Symmetric-key_algorithm">Symmetric Encryption</a> in .NET using the <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES algorithm</a> (the successor to Rijndael).</p>
<p><strong>It’s called <a href="https://github.com/jbubriski/Encryptamajig">Encryptamajig</a>.</strong></p>
<p>To quote the project readme:</p>
<blockquote>
<p>“When you look at encryption examples online many are verbose, misleading, outdated, or flat out insecure. By creating this project I hope to provide a single resource that myself and others can use to incoporate encryption into their .NET projects.</p>
</blockquote>
<p>My goal is to make sure this project uses an up-to-date encryption algorithm and forces appropriate usage of that algorithm.”</p>
<p>The interface has been simplified so all you need to do is make 2 calls, 1 for encryption and 1 for decryption:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var _key = "Keep me safe";
var _plainText = "Some plaintext you want to encrypt";
var encrypted = AesEncryptamajig.Encrypt(_plainText, _key);
var roundtrip = AesEncryptamajig.Decrypt(encrypted, _key);
</code></pre></div></div>
<p>For more information about the project, and encryption, take a look at the well written readme on <a href="https://github.com/jbubriski/Encryptamajig">the project page</a>. If you have something to contribute to the project, just send me a pull request on Github!</p>
Ignoring Elmah Exception Spam2012-02-13T08:00:53+00:00http://johnnycode.com/2012/02/13/ignoring-elmah-exception-spam<p>Did you setup Elmah on your website or web application? Yes? Great.</p>
<p>Are you getting 100’s or 1000’s of exception emails every day for bots probing your site for various applications and application frameworks? Yes? Not great.</p>
<p>Did you filter all those emails into a folder in your inbox? Yes? Then you’re doing it wrong.</p>
<h2 id="im-on-iis-7">I’m on IIS 7</h2>
<p>Nip it in the bud and implement some filtering to kill those requests so that you never even see them! <a href="http://stackoverflow.com/questions/8118703/asp-net-mvc3-what-do-you-do-with-probing-requests">This question on StackOverflow</a> has a great way of using the <a href="http://learn.iis.net/page.aspx/143/use-request-filtering/">Request Filtering Module</a> to accomplish just that in IIS 7.</p>
<h2 id="but-what-about-iis-6">But what about IIS 6?</h2>
<p>We can’t all be on the latest and greatest. As far as I know, we don’t have Request Filtering in IIS 6, nor can we use the official <a href="http://www.iis.net/download/urlrewrite">IIS URL Rewrite Module</a> (Available for free via the <a href="http://www.microsoft.com/web/downloads/platform.aspx">Web Platform Installer</a> if you are running IIS 7).</p>
<p>While this is less than ideal, it’s not hard to take those problematic requests and ignore them through and <a href="http://code.google.com/p/elmah/wiki/ErrorFilterExamples">Elmah Error Filter</a>.</p>
<p>First we need to use the <a href="http://urlrewriter.net/">Open Source URL Rewriter for .NET</a> to return a <a href="http://en.wikipedia.org/wiki/HTTP_403">403 Forbidden</a> result for those requests. In my case, 99% of those requests are looking for various PHP applications that probably have vulnerabilities in older versions. So I’m going to forbid any PHP files right off the bat by adding this to my Web.Config:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><rewriter>
<if url="^(.+)\.php$">
<forbidden></forbidden>
</if>
</rewriter>
</code></pre></div></div>
<p>Now that you have the PHP requests returning a 403 Forbidden status code we can ignore them with an Elmah Error Filter block in the Web.Config.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><elmah>
<errorfilter>
<test>
<equal type="Int32" binding="HttpStatusCode" value="403"></equal>
</test>
</errorfilter>
</elmah>
</code></pre></div></div>
<p>In my case, I’m dealing with a simple public website that doesn’t incorporate any authentication or authorization, so I never actually use 403 Forbidden status code. There may be a more elegant way to do this. But this works.</p>
SQL Server Cell-Level Symmetric Encryption: The right way2012-02-09T08:00:33+00:00http://johnnycode.com/2012/02/09/sql-server-cell-level-symmetric-encryption-the-right-way<p>So I needed to encrypt some sensitive data being stored in SQL Server. I looked into encrypting the data at the application level via C#, but that would mean I would need to ship encrypted data and keys around, which defeats the purpose (we use a thick client). So I turned to SQL Server to handle the encryption for me, and I was pleasantly surprised!</p>
<h2 id="types-of-encryption">Types of Encryption</h2>
<p>There are 2 general types of encryption in SQL Server that you can employ:</p>
<ul>
<li><strong>TDE (Transparent Data Encryption)</strong> - Encrypts your whole database. Available only in SQL Server 2008 Enterprise Edition and SQL Server 2008 Developer Edition (and later).</li>
<li><strong>Cell-Level Encryption</strong> - Encrypts individual cells. Available in all SQL Server editions (since 2000 I think).</li>
</ul>
<p>There are other ways to encrypt your data, such as encrypting your entire hard drive, but we’ll focus on the options directly provided by SQL Server. For the purpose of this article, we’ll be focusing on Cell-Level Encryption.</p>
<h2 id="when-is-sql-server-encryption-recommended">When is SQL Server Encryption Recommended?</h2>
<p>You might want to use SQL Server Encryption if you want to minimize the changes to your application code. Injecting encryption code into an existing codebase can be painful, especially if you have to modify all your data access code. Encryption via SQL Server can help limit your attack surface since your sensitive data will spend less time at the client, whether that be your web server or a thick client.</p>
<h2 id="limitationsdrawbacks">Limitations/Drawbacks.</h2>
<p>You have to modify your database to use varbinary fields instead of plain varchar or nvarchar fields. While I don’t think this is a huge deal, it might be a problem for those who don’t have free reign over their DB schema, or when the database table is being accessed directly by multiple applications. If you’re using Stored Procedures or a common Data Access Layer, this isn’t a big deal.</p>
<h2 id="show-me-the-code">Show me the code!</h2>
<p>Let’s say we want to encrypt some credit cards. I’m using the <a href="http://msftdbprodsamples.codeplex.com/">AdventureWorks</a> sample database from Microsoft for my example so the code below should work on your machine too. Plus, the AdventureWorks DB is already storing unencrypted credit cards! Oh noes!</p>
<p>First, we need a Master Key. The Master Key encrypts your other keys to keep them safe.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>IF NOT EXISTS
(SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
CREATE MASTER KEY ENCRYPTION BY
PASSWORD = 'Some long key that you will guard with your life'
GO
</code></pre></div></div>
<p><strong>(Important: Make sure you save your Master Key Password someplace safe!)</strong></p>
<p>Now we need to create a Symmetric Key that will encrypt the data, and a Certificate to access the Key:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CREATE CERTIFICATE CreditCards
WITH SUBJECT = 'Customer Credit Card Numbers';
GO
CREATE SYMMETRIC KEY CreditCards_Key_01
WITH KEY_SOURCE = 'A pass phrase from which to derive the key.',
IDENTITY_VALUE = 'An identity phrase from which to generate a GUID for tagging data that is encrypted with a temporary key',
ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE CreditCards;
GO
</code></pre></div></div>
<p><strong>(Important: Like the Master Key Password, make sure you store the Symmetric Key KEY_SOURCE and IDENTITY_VALUE someplace safe!)</strong></p>
<p>The first block will generate a Certificate that allows you to easily work with the Key without having to provide the Password for that Key. The second block will generate the actual Symmetric Key that is used to perform the encryption and decryption. The Key_Source and Identity_Value options tell SQL Server to generate the Key in a specific way. If we need to regenerate the key on another instance/server we can pass in the same values and get the same Key. This is very important in the case that your server ever dies or you need to migrate your keys for other reasons. The Algorithm is specifying the 256 bit version of the AES encryption algorithm. It’s a standardized, strong algorithm that is frequently used. Finally, note the 2nd to last line where we reference the Certificate.</p>
<p>I would recommend that you always create your Key with a Key_Source and Identity_Value. Without them, I’m not even sure if you can retrieve your Key, and it will definitely be easier tto recreate the Key having those two items on hand. As <a href="http://sqlblog.com/blogs/michael_coles/archive/2009/06/17/cloning-symmetric-keys.aspx">Michael Coles</a> said:</p>
<blockquote>
<p>“For my tastes, it would make more sense to require <code class="language-plaintext highlighter-rouge">IDENTITY_VALUE</code> and <code class="language-plaintext highlighter-rouge">KEY_SOURCE</code> options by default.”</p>
</blockquote>
<p>Now let’s add an extra column to our table to store the encrypted data:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ALTER TABLE Sales.CreditCard
ADD CreditCardNumberEncrypted varbinary(128);
GO
</code></pre></div></div>
<p><strong>(Note: I haven’t run into any problems with my own data, but if you’re storing “bigger” data, then you might need to increase the varbinary column size)</strong></p>
<p>Great! Now we can encrypt our existing data into the new column:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OPEN SYMMETRIC KEY CreditCards_Key_01
DECRYPTION BY CERTIFICATE CreditCards
UPDATE Sales.CreditCard
SET CreditCardNumberEncrypted = EncryptByKey(Key_GUID('CreditCards_Key_01'), CardNumber);
GO
</code></pre></div></div>
<p>Finally, let’s look at the data in the table now.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OPEN SYMMETRIC KEY CreditCards_Key_01
DECRYPTION BY CERTIFICATE CreditCards;
GO
SELECT
CardNumber
, CreditCardNumberEncrypted
, CONVERT(nvarchar, DecryptByKey(CreditCardNumberEncrypted)) AS 'Decrypted Credit Card Number'
FROM Sales.CreditCard
GO
</code></pre></div></div>
<p><strong>(Important: If you’re not seeing the correct data come back, make sure that you are converting to the correct type of the original data! In this case, the data was from a nvarchar column. Also, make sure you’re decrypting the correct column.)</strong></p>
<p>That should spit back the original credit card number, the encrypted version, and then the decrypted version (which should match the original).</p>
<p>At this point all of your data should be encrypted, and you should be able to drop the unencrypted column. If you’re working with existing code, you can rename the Encrypted column to match the old name, and just make sure you decrypt the data in your queries. In the specific case of credit cards, you might want to add an additional column to store the last four digits unencrypted for easier retrieval.</p>
<p><strong>(Important: Never store the CCV/CVV from credit cards. I’m pretty sure it’s illegal.)</strong></p>
<p>One last note. If your application user doesn’t have full access to the database (which it probably shouldn’t) then you will need to grant some permissions in order for the user to use the encryption Certificate and Key. From the MSDN: “VIEW DEFINITION permission on the Symmetric Key and CONTROL permission on the Certificate” are required:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GRANT VIEW DEFINITION ON SYMMETRIC KEY::CreditCards_Key_01
TO Test;
GRANT CONTROL ON CERTIFICATE::CreditCards
TO Test;
</code></pre></div></div>
<p>Just make sure that you are handling permissions correctly!</p>
<p>Thanks for listening, and let me know if you have any feedback!</p>
<h2 id="full-script">Full Script</h2>
<p>Attached is a SQL Server script of all the commands from the post:</p>
<p><a href="http://www.johnnycode.com/blog/wp-content/uploads/2012/02/Setup-Credit-Card-Encryption-on-AdventureWorks.zip">Setup Credit Card Encryption on AdventureWorks SQL Script</a></p>
<h2 id="resourcesreferences">Resources/References</h2>
<p>Below are some of the references and resources I used to write this post.</p>
<h3 id="general">General</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/cc278098(v=sql.100).aspx#_Toc189384675"> Good overview of Encryption in SQL Server 2008</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms189586(v=sql.100).aspx"> Encryption Hierarchy</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms179331(v=sql.100).aspx"> How to: Encrypt a Column of Data</a></li>
</ul>
<h3 id="backupregeneration-of-keys-and-certificates">Backup/Regeneration of Keys and Certificates</h3>
<ul>
<li><a href="http://sqlblog.com/blogs/michael_coles/archive/2009/06/17/cloning-symmetric-keys.aspx"> “Cloning” Symmetric Keys</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms366281.aspx"> How to: Create Identical Symmetric Keys on Two Servers</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms156010.aspx"> Deleting and Re-creating Encryption Keys</a></li>
<li><a href="http://serverfault.com/questions/356237/do-i-need-to-back-up-the-sql-server-encryption-password-and-symmetric-key/356303#356303"> My ServerFault question on the subject</a></li>
</ul>
<h3 id="msdn-t-sql-references">MSDN T-SQL References</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/swbw1ewb(v=vs.80).aspx"> varbinary</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms188357.aspx"> CREATE SYMMETRIC KEY</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms190499.aspx"> OPEN SYMMETRIC KEY</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms179887.aspx"> GRANT Symmetric Key Permissions</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms186278.aspx"> GRANT Certificate Permissions</a></li>
</ul>
In IIS6 HTTP 301 Redirect from non-www to www2012-01-04T09:00:59+00:00http://johnnycode.com/2012/01/04/in-iis6-http-301-redirect-from-non-www-to-www<p>This article applies to IIS6, but the concept applies to almost any public website. <strong>You should probably setup a 301 redirect from http://example.com to http://www.example.com</strong> (or the other way around). If you don’t, <a href="http://webmasters.stackexchange.com/q/23649/10793">bad things can happen</a>. Anyway, here is how you can do it in IIS6:</p>
<h2 id="instructions">Instructions</h2>
<p>Create a new website with the same IP and host name as your main website, <strong>but do not include the www</strong>. FYI, I think that IIS will yell at you if you try and create 2 websites with the same IP and host name. I add “redirect” to the end of mine so that I know it’s the redirect website.</p>
<p><img src="/assets/images/2012-01-04-in-iis6-http-301-redirect-from-non-www-to-www/IIS6-Redirect-website-setup.png" alt="" title="IIS6 Redirect Website Setup" /></p>
<p>Then, in the “Home Directory” tab of the redirect website:</p>
<ol>
<li>Check the radio button that says “A redirection to a URL”.</li>
<li>Enter in your domain like this, without the double quotes: “http://www.example.com$S$Q”</li>
<li>Check the box that says “The exact URL entered above”.</li>
<li>Check the box that says “A permanent redirection for this resource”.</li>
</ol>
<p><img src="/assets/images/2012-01-04-in-iis6-http-301-redirect-from-non-www-to-www/IIS6-Website-Settings.png" alt="" title="IIS6 Website Settings" /></p>
<p>Now I would test that the non-www version of your website redirects to the www version. If you want to be 100% sure what is happening, look at the <a href="http://getfirebug.com/wiki/index.php/Net_Panel">Net tab in Firebug</a> or the <a href="http://code.google.com/chrome/devtools/docs/network.html">Network tab in the Google Chrome Web Inspector</a>.</p>
<h2 id="caveatsdebugging">Caveats/Debugging</h2>
<p>If your company manages your internal DNS, you might encounter an issue resolving some of the hostnames internally. For example, at the time of writing, “http://example.com” doesn’t work from inside our corporate network! It’s not a big deal, but in our case it times out so it might give the illusion that the website is down.</p>
<p>I’m pretty sure this wont handle the HTTPS version of your site. You would need to add another redirect website for that. <strong>However</strong>, I don’t think that will work correctly because modern browsers will realize that there is no cert for the non-www, and never even load the content from the site. You would probably get some big warning instead. So just make sure that you don’t link the https://example.com anywhere.</p>
<h2 id="credit">Credit</h2>
<p>I actually found this solution inside <a href="http://stackoverflow.com/q/643382/57698">a question on Stackoverflow about a problem with setting up 301 redirects in IIS 6</a>. There is also a link in the first paragraph of this post about reasons you should do this.</p>
New Developer Resources Page on Johnny Code!2011-11-17T09:00:52+00:00http://johnnycode.com/2011/11/17/new-developer-resources-page-on-johnny-code<p>I’ve added a new page called <strong><a href="/resources/">Developer Resources</a></strong>. It’s going to be a repository of all of the blogs I read and podcasts I listen to. It’s a work in progress, but most of the podcasts I listen to regularly are up there now. Feel free to post suggestions! Most everything there will be programming/IT related.</p>
ASP.NET MVC Extension Method for the ID in the Route2011-11-09T09:00:38+00:00http://johnnycode.com/2011/11/09/asp-net-mvc-extension-method-for-id-in-route<p>If you’ve worked on an ASP.NET MVC site, you may have had to reference the ID in the current route. In a Razor view you can reference it via the following variable:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Url.ViewContext.RouteData.Values["id"]
</code></pre></div></div>
<p>You may use this a lot if you have a lot of inter-action navigation. Why not throw it into an extension method!?</p>
<p>This makes the assumption that you’re using the default route, or a similar one with an “id” parameter:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>namespace System.Web.Mvc
{
public static class ContextExtensions
{
public static string Id(this HtmlHelper helper)
{
return helper.ViewContext.RouteData.Values["id"].ToString();
}
}
}
</code></pre></div></div>
<p>Now you can reference the id much easier like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Html.Id()
</code></pre></div></div>
<p>And if you ever need to change it, you can update it in one place!</p>
Custom Validation with BizForms2011-10-17T09:00:02+00:00http://johnnycode.com/2011/10/17/custom-validation-with-bizforms<p>Ever need to inject some custom validation into a BizForm? Check it:</p>
<p>Below I’ve provided a method you can drop into your BizForm code behind, or the code behind of a BizForm clone. Then, call this method from an event handle for the OnBeforeValidate event. If <em>Field A</em> has a value this validation method forces the user to enter a value for <em>Field B</em>.</p>
<p>Keep in mind that this is <strong><em>simply an example</em></strong> of adding custom validation. Just remember: the sky is the limit!</p>
<p>One last quick note: This example used BizForms, but you can probably apply this same technique to Document Forms and Custom Table Forms.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void ShowErrorIfParentHasValueAndChildIsEmpty(string fieldAName, string fieldBName, string errorMessage)
{
var parentControl = (EditingFormControl)uxBizForm.BasicForm.FieldEditingControls[fieldAName];
var childControl = (EditingFormControl)uxBizForm.BasicForm.FieldEditingControls[fieldBName];
var parentControlValue = parentControl.Value.ToString();
var childControlValue = childControl.Value.ToString();
if (!string.IsNullOrWhiteSpace(parentControlValue) && string.IsNullOrWhiteSpace(childControlValue))
{
var errorLabel = uxBizForm.BasicForm.FieldErrorLabels[fieldBName] as LocalizedLabel;
errorLabel.Text = errorMessage;
errorLabel.Visible = true;
uxBizForm.BasicForm.StopProcessing = true;
}
else
{
var errorLabel = uxBizForm.BasicForm.FieldErrorLabels[fieldBName] as LocalizedLabel;
errorLabel.Text = "";
errorLabel.Visible = false;
}
}
</code></pre></div></div>
<p>And here is the wire up code for the event handler (Put this in the SetupControl method):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uxBizForm.OnBeforeValidate += uxBizForm_OnBeforeValidate;
</code></pre></div></div>
<p>And here is the event handler where you can call the validation method from above:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected void uxBizForm_OnBeforeValidate()
{
ShowErrorIfParentHasValueAndChildIsEmpty("FirstName", "LastName", "We don't like John and Aaron and nobody!");
}
</code></pre></div></div>
New Kentico Pages on Johnny Code!2011-10-13T09:00:41+00:00http://johnnycode.com/2011/10/13/new-kentico-pages-on-johnny-code<p>I just wanted to let you know that I have 2 new pages on the site!</p>
<p>There is a new <a href="/kentico-resources/">Kentico Resources</a> page that contains a short list of some important resources. Feel free to let me know about any others</p>
<p>Also, there is a new <a href="/kentico-resources/kentico-tips-and-tricks/index.html">Kentico Tips and Tricks</a> page that contains… you guessed it! Tips and Tricks! Really, it’s just a place I’m going to start putting some of the API calls and other information that is hard to find.</p>
5 More Visual Studio Productivity Tips Every Developer Should (Probably) Know2011-09-12T09:00:50+00:00http://johnnycode.com/2011/09/12/5-more-visual-studio-productivity-tips-every-developer-should-probably-know<h2 id="code-snippets">Code Snippets</h2>
<p>Another great tip for cranking out the code, or in case you don’t remember the syntax of certain keywords. Just start typing the shortcut for a code snippet and hit tab twice, it’s that easy.</p>
<p>prop ->tab tab</p>
<p>For example, after you type “prop” you should see this:</p>
<p><img src="/assets/images/2011-09-12-5-more-visual-studio-productivity-tips-every-developer-should-probably-know/prop-code-snippet.png" alt="" /></p>
<p>Then you will see this after you press “Tab” twice:</p>
<p><img src="/assets/images/2011-09-12-5-more-visual-studio-productivity-tips-every-developer-should-probably-know/prop-code-snippet-2.png" alt="" /></p>
<h2 id="search-quickly">Search Quickly</h2>
<p>Ever notice that little text box on the menu bar? That is for searching</p>
<blockquote>
<p>ctrl + d</p>
</blockquote>
<h2 id="delete-lines">Delete Lines</h2>
<p>We all mistakes! Quickly delete code by the line using this shortcut:</p>
<blockquote>
<p>ctrl + l</p>
</blockquote>
<p>or the lazy-man’s shortcut would be to “cut” while having no selection on the desired line (However, that obviously overwrites your clipboard buffer):</p>
<blockquote>
<p>ctrl + x</p>
</blockquote>
<h2 id="extract-an-interface">Extract an Interface</h2>
<p>Let’s say you’re creating a shiny new ASP.NET MVC site and you want to use Inversion Of Control of Dependency Injection. You probably need an interface for the services/providers that you will be injecting into your controllers. If you already have those service or provider classes, you can use the built in Visual Studio refactoring features to automatically extract an interface.</p>
<p>Right click on your class:</p>
<p><img src="/assets/images/2011-09-12-5-more-visual-studio-productivity-tips-every-developer-should-probably-know/Extract-Interface.png" alt="" title="Right click to extract an interface" /></p>
<p>Click “Extract Interface” to bring up the “Extract Interface” dialog:</p>
<p><img src="/assets/images/2011-09-12-5-more-visual-studio-productivity-tips-every-developer-should-probably-know/Extract-Interface-Dialog.png" alt="" title="Extract Interface Dialog" /></p>
<p>And here is the generated interface:</p>
<p><img src="/assets/images/2011-09-12-5-more-visual-studio-productivity-tips-every-developer-should-probably-know/Extract-Interface-Code.png" alt="" title="Extract Interface Code" /></p>
<p>Pretty nice! Just don’t forget to mark the interface as Public if you need to. That often bites me because I have my interfaces in a separate class library from my implementations.</p>
<h2 id="extend-your-visual-studio">Extend Your Visual Studio</h2>
<p>OK, so I couldn’t really think of a good tip off the top of my head, so I instead am copping out and telling you about the Extension Manager which is new in Visual Studio 2010. You probably know about this <strong><em>unless</em></strong>:</p>
<ol>
<li>You don’t have Visual Studio 2010.</li>
<li>You have Visual Studio 2010 C# Express Edition (or Web Developer, or whatever).</li>
<li>You didn’t look at the feature list.</li>
<li>You live under a rock.</li>
</ol>
<p>The extension manager has all sorts of goodies. There is everything from free extensions, to paid version, to ones provided by Microsoft to support out-of-band releases. Take a look at what’s there, and let me know if you find something good! Here is what I use:</p>
<ul>
<li>Indent Guides</li>
<li>JScript extensions (All the ones from Microsoft to enhance the IDE’s JavaScript support)</li>
<li>NuGet Package Manager</li>
<li>PowerCommands for Visual Studio 2010</li>
<li>Productivity Power Tools</li>
<li>VS Commands 2010</li>
<li>WoVS Quick Add Reference</li>
</ul>
<p>I’ve used a bunch of others, but some of them didn’t stick, or I wasn’t actively using them so I removed them. Keep in mind that any extensions you install could cause instability or performance issues.</p>
Can't reinstall IIS issue2011-09-05T09:00:39+00:00http://johnnycode.com/2011/09/05/cant-reinstall-iis-issue<p>I ran into this fun issue the other day where I I couldn’t access one of my sites. I assumed it was a problem with ASP.NET so I uninstalled it. To my dismay, the reinstall failed! That has never happened before!
The problem was actually a simple one. I had moved one of the many websites I had running in IIS, but didn’t bother to update the actual IIS website (I wasn’t actively working on that site). However, when trying to install ASP.NET again, it was using the IIS metabase to add some files to each site. So when it tried to add files for the site I had moved it couldn’t find the directory and the install failed.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2010-03-02 16:06:59 Success Creating list of client site scripts dirs
2010-03-02 16:06:59 Starting Copy the client side script or web admin files to a list of directories.
2010-03-02 16:06:59 Success Copy the client side script or web admin files to a list of directories.
2010-03-02 16:06:59 Starting Setting IIS key for script files
2010-03-02 16:06:59 Success Setting IIS key for script files
2010-03-02 16:06:59 Starting Creating list of client site scripts dirs
2010-03-02 16:06:59 Starting Creating directory: C:\Inetpub\wwwroot\Test\aspnet_client
2010-03-02 16:06:59 Failure Creating directory: C:\Inetpub\wwwroot\Test\aspnet_client: CreateDirectoryInternal failed with HRESULT 80070003: 'The system cannot find the path specified. '
2010-03-02 16:06:59 Failure Creating list of client site scripts dirs: CreateSiteClientScriptDir failed with HRESULT 80070003: 'The system cannot find the path specified.
Setup has detected some errors during the operation. For details, please read the setup log file C:\DOCUME~1\ME\LOCALS~1\Temp\ASPNETSetup_00002.log
C:\Documents and Settings\me\Local Settings\Temp
</code></pre></div></div>
<p>Fixed by calling the registration script with these options:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aspnet_regiis.exe -iru
</code></pre></div></div>
<p>from the framework directory:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
</code></pre></div></div>
Quick Tip: Using LINQ to convert from List to Dictionary2011-08-31T09:00:51+00:00http://johnnycode.com/2011/08/31/quick-tip-using-linq-to-convert-from-list-to-dictionary<p>Ever need to easily access a collection of items by their key? Exactly, you use a Dictionary!</p>
<p>But how do you easily convert a List to a Dictionary? Just use a little LINQ. Let’s say you have a simple class:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public class Stuff
{
public int Key { get; set; }
public Stuff(int key)
{
Key = key;
}
}
</code></pre></div></div>
<p>Here is how you can take a List of Stuff and convert it into a Dictionary with the Key property as the accessor:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var listofStuff = new List
{
new Stuff(1),
new Stuff(2),
new Stuff(3)
};
var dictionaryOfStuff = listofStuff.ToDictionary(s => s.Key);
</code></pre></div></div>
<p>No you can access the Stuff objects by their key!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var stuff1 = dictionaryOfStuff[1];
var stuff2 = dictionaryOfStuff[2];
var stuff3 = dictionaryOfStuff[3];
</code></pre></div></div>
<p>Nice and easy!</p>
Wildcard URL's in Kentico2011-08-29T15:21:41+00:00http://johnnycode.com/2011/08/29/wildcard-urls-in-kentico<p>A little known feature in Kentico is the ability to have “Wildcard URL’s”. Wildcard URL’s are essentially the ability to route multiple URL’s to the same page. It’s similar to the routing features in ASP.NET MVC or ASP.NET 4.0.</p>
<h2 id="a-built-in-example">A Built In Example</h2>
<p>If you want to see a working example of Wildcard URL’s you can create a new site using the community site template that ships with Kentico. Under the members section there is a single page located at “/members/profile/”, but this actually handles the profile pages for all the site members. It “generates” URL’s like these:</p>
<ul>
<li>/members/john.aspx</li>
<li>/members/tiffany.aspx</li>
<li>/members/aaron.aspx</li>
</ul>
<p>I say “generates” because the URL’s don’t really exist in Kentico. This will make more sense later. To see how these URL’s work, just go to the Page Properties -> URLs. You should see this:</p>
<p><img src="/assets/images/2011-08-29-wildcard-urls-in-kentico/The-URLs-section-of-the-Members-page-Properties.png" alt="" title="The URLs section of the Members page Properties" /></p>
<p>You can see that the Document URL Path is a Wildcard URL. Anything inside a set of curly braces is a placeholder that gets converted to a URL query string parameter. The Document Alias is only used behind the scenes now. For example, if I make a request to this URL:</p>
<p>/members/john.aspx</p>
<p>it gets converted to this URL behind the scenes:</p>
<p>/members/profile.aspx?username=john</p>
<p>Then, any web parts on the page can programmatically access the wildcard section of the URL. At this point the username parameter is just a querystring parameter, and can be accessed like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var username = Request.QueryString["username"];
// The rest of your code that handles the page for the given user
...
</code></pre></div></div>
<h2 id="a-complex-real-world-example">A Complex Real World Example</h2>
<p>The above example is practical, but basic. What about a more complex real world scenario?</p>
<p>We recently developed a mobile site for a customer who already had an existing desktop site. They had a section of their site where they had numerous categories and products. We wanted to avoid any duplication, and avoid a site re-architecture so we used Kentico’s Wildcard URL’s to create unique URL’s for each of the product and category pages within the mobile section of their site.</p>
<p>Here is an example of their old site structure:</p>
<ul>
<li>/category/</li>
<li>/category/subcategory/</li>
<li>/category/subcategory/product/</li>
</ul>
<p>And their new site wanted to incorporate a mobile section that followed similar conventions, but under a mobile sub-folder:</p>
<ul>
<li>/mobile/category/</li>
<li>/mobile/category/subcategory/</li>
<li>/mobile/category/subcategory/product/</li>
</ul>
<h2 id="the-solution-wildcardurls-to-the-rescue">The Solution: Wildcard URL’s to the rescue!</h2>
<p>Using wildcard URL’s we only needed to create 3 pages and 3 templates to reproduce the entire product/category hierarchy for the mobile site. Here is what the Document Name Paths were set to:</p>
<ul>
<li>/mobile/{category}/</li>
<li>/mobile/{category}/{subcategory}/</li>
<li>/mobile/{category}/{subcategory}/{product}/</li>
</ul>
<p>The last thing to do was to create web parts to render the content. However, in our example we can just use a repeater to read the query string parameters to automatically render the document from the desktop version of the site! No programming needed!</p>
Creating User Specific, Editable BizForms2011-04-19T13:00:09+00:00http://johnnycode.com/2011/04/19/creating-user-specific-editable-bizforms<p>In this article I’ll show you how to create a special type of BizForm that will allow each user to edit their specific form data over and over. When a user returns to a page that has the BizForm on it, their data will be automatically loaded from the BizForm table. This is a simple and easy way to store per user data, without mucking with the System Tables which aren’t intended to store this type of data. You also retain the benefits that a BizForm has over a System Table (A view of the data, Notifications, attachments, etc.). Here we go…</p>
<p>You can download the files that are used in this article here: <a href="http://www.johnnycode.com/blog/wp-content/uploads/2011/04/Bizform_continue.zip">Bizform_continue Web Part Files</a>.</p>
<p>First, we’ll clone the existing BizForm Web Part.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/01-Cloning-the-existing-BizForm-webpart.jpg" alt="" title="Cloning the existing BizForm webpart" /></p>
<p>We don’t need to change anything with the configuration, but we’ll use our own set of files for the Web Part. I will show the code later below, and you can download the zip here: <a href="http://www.johnnycode.com/blog/wp-content/uploads/2011/04/Bizform_continue.zip">Bizform_continue Web Part Files</a>.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/02-Cloning-the-existing-BizForm-webpart-settings.jpg" alt="" title="Cloning the existing BizForm webpart settings" /></p>
<p>Now that we have our new Web Part setup, let’s go make a new BizForm.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/03-Create-a-new-BizForm.jpg" alt="" title="Create a new BizForm" /></p>
<p>Create a field in that BizForm that will hold the User ID. Set the Default Value property to be this macro so that the User ID is filled automatically:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{<span></span>%cmscontext.currentuser.userid%<span></span>}
</code></pre></div></div>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/04-Create-a-field-to-store-the-User-ID.jpg" alt="" title="Create a field to store the User ID" /></p>
<p>Make sure you don’t show the field on the public form! We want to rely on the macro to tell us who is editing a row. My crappy screenshot above has it selected, but just de-select it and re-save if you already saved the field.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/05-Dont-show-the-field-on-the-pulic-form.jpg" alt="" title="Don't show the field on the pulic form" /></p>
<p>Now make some other data fields, whatever you want!</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/06-Create-some-more-fields-to-store-user-data.jpg" alt="" title="Create some more fields to store user data" /></p>
<p>Now that our BizForm is all set, let’s add it to a page template. I am adding mine to the main content area of the home page, just for testing. Make sure you select our new Web Part, and not the original.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/07-Add-our-new-BizForm-Continue-Web-Part.jpg" alt="" title="Add our new BizForm Continue Web Part" /></p>
<p>For the properties, all we really need is the Form Name, but I also set “Display to Roles” to be only authenticated users, since the rows will be tied to a specific user.</p>
<p><img src="/assets/images/2011-04-19-creating-user-specific-editable-bizforms/08-Setting-the-Web-part-properties-of-our-BizForm-Continue.jpg" alt="" title="Setting the Web part properties of our BizForm Continue" /></p>
<p>Now let’s take a look at the code. The only real change is that we added a method that happens before load of the data for the form. We simply call a method that contains the following code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var bizFormInfo = BizFormInfoProvider.GetBizFormInfo(viewBiz.FormName, viewBiz.SiteName);
if (bizFormInfo != null)
{
var dataClassInfo = DataClassInfoProvider.GetDataClass(bizFormInfo.FormClassID);
if (dataClassInfo != null)
{
var connection = ConnectionHelper.GetConnection();
var whereCondition = String.Format("UserId = '{0}'", CMSContext.CurrentUser.UserID);
var dataSet = connection.ExecuteQuery(dataClassInfo.ClassName + ".selectall", null, whereCondition);
if (!DataHelper.DataSourceIsEmpty(dataSet) && dataSet.Tables[0].Rows.Count == 1)
{
var formRecordId = ValidationHelper.GetInteger(dataSet.Tables[0].Rows[0][0], 0);
viewBiz.FormMode = FormModeEnum.Update;
viewBiz.ItemID = formRecordId;
return;
}
viewBiz.FormMode = FormModeEnum.Insert;
}
}
</code></pre></div></div>
<p>We get the BizFormInfo, the DataClassInfo, and check to see if there is an existing record. If there is an existing record we set the BizForm to Update mode and tell it what row to load . If there is no record found, we simply use insert mode.</p>
<p>Hope that this was clear and helps somebody make their site even more awesome!</p>
<p>You can download the files that are used in this article here: <a href="http://www.johnnycode.com/blog/wp-content/uploads/2011/04/Bizform_continue.zip">Bizform_continue Web Part Files</a>.</p>
Kentico "Did You Know": Document Type System Attributes2011-04-07T13:00:47+00:00http://johnnycode.com/2011/04/07/kentico-did-you-know-document-type-system-attributes<p>Did you know that you can create Document Type Attributes that map to System Attributes? System Attributes are the fields that are inherent to all documents in Kentico, and are <em>generally</em> edited through the Properties tab in the CMS Desk (Some are not editable, and some are hidden entirely). Here are some System Attributes you might recognize:</p>
<ul>
<li>NodeAlias</li>
<li>NodeAliasPath</li>
<li>NodeCustomData</li>
<li>DocumentName</li>
<li>DocumentMenuCaption</li>
<li>DocumentPageTitle</li>
<li>DocumentTags</li>
<li>DocumentCustomData</li>
</ul>
<p>Notice above that there are two type of System Attributes: Node Attributes and Document Attributes. The difference is that the Node Attributes “live” on the Tree Node object and are stored in the CMS_Tree table while the Document Attributes “live” on the Document object and are stored in the CMS_Document table.</p>
<p>Note: In case you don’t know, attributes are the fields on a document type. I may use the term attribute and field interchangeably.</p>
<p>If you want to see a System Attribute in action, take a look at the built in Blog Post Document Type “DocumentTags” attribute:</p>
<p><img src="/assets/images/2011-04-07-kentico-did-you-know-document-type-system-attributes/BlogPost-DocumentTags-System-Attribute.png" alt="" title="BlogPost DocumentTags System Attribute" /></p>
<p>Notice that the top options are grayed out. The field relies on the configuration of the inherited System Attribute. In this case we have a field called “Tags” that is relying on the “DocumentTags” System Attribute. While we can’t change the fact that it is a “Long Text” attribute type, we can change the field type which dictates the control that is used when interacting with the field. The Document Type uses the Tag Selector control.</p>
<p>So you might say to yourself: “When is this useful, I can probably already edit that data through the Properties tab, right?” That is exactly right, but you would need to go to the properties tab every time you were creating or editing a document! Instead of having to drill in there, you can simplify your process so that the field shows up in the Form tab. This way you can set the tags while you’re inputting the rest of the content for your Blog Post or other Document Type.</p>
<p>Keep in mind that while you <strong><em>can</em> **use System Attributes to change most core data for a document or node, **<em>that doesn’t mean you should</em></strong>. Modifying the DocumentClassID would probably end badly for your content editors (or maybe even you!).</p>
<p>Another way you might use this feature would be to store custom data on every document or node. Both objects have a CustomData field called DocumentCustomData and NodeCustomData. Since they exist on every document in the CMS, they will always be available via API calls or inside a transformation. This is a little easier than creating and configuring an actual attribute on every single document type. So if you are selecting multiple type of documents within a repeater, these fields would both be available to the transformation. Normally when you “join” different document types in a repeater, you can only access the core attributes, and not the custom ones you define.</p>
<p>Below is a full list of all of the Document Attributes:</p>
<ul>
<li>DocumentCampaign</li>
<li>DocumentCheckedOutByUserID</li>
<li>DocumentCheckedOutVersionHistoryID</li>
<li>DocumentCheckedOutWhen</li>
<li>DocumentContent</li>
<li>DocumentCreatedByUserID</li>
<li>DocumentCreatedWhen</li>
<li>DocumentCulture</li>
<li>DocumentCustomData</li>
<li>DocumentExtensions</li>
<li>DocumentForeignKeyValue</li>
<li>DocumentGroupWebParts</li>
<li>DocumentID</li>
<li>DocumentLastPublished</li>
<li>DocumentMenuCaption</li>
<li>DocumentMenuClass</li>
<li>DocumentMenuClassHighlighted</li>
<li>DocumentMenuClassOver</li>
<li>DocumentMenuItemHideInNavigation</li>
<li>DocumentMenuItemImage</li>
<li>DocumentMenuItemImageHighlighted</li>
<li>DocumentMenuItemImageOver</li>
<li>DocumentMenuItemInactive</li>
<li>DocumentMenuItemLeftImage</li>
<li>DocumentMenuItemLeftImageHighlighted</li>
<li>DocumentMenuItemLeftImageOver</li>
<li>DocumentMenuItemRightImage</li>
<li>DocumentMenuItemRightImageHighlighted</li>
<li>DocumentMenuItemRightImageOver</li>
<li>DocumentMenuJavascript</li>
<li>DocumentMenuRedirectUrl</li>
<li>DocumentMenuStyle</li>
<li>DocumentMenuStyleHighlighted</li>
<li>DocumentMenuStyleOver</li>
<li>DocumentModifiedByUserID</li>
<li>DocumentModifiedWhen</li>
<li>DocumentName</li>
<li>DocumentNamePath</li>
<li>DocumentNodeID</li>
<li>DocumentPageDescription</li>
<li>DocumentPageKeyWords</li>
<li>DocumentPageTemplateID</li>
<li>DocumentPageTitle</li>
<li>DocumentPriority</li>
<li>DocumentPublishedVersionHistoryID</li>
<li>DocumentPublishFrom</li>
<li>DocumentPublishTo</li>
<li>DocumentRatings</li>
<li>DocumentRatingValue</li>
<li>DocumentShowInSiteMap</li>
<li>DocumentStylesheetID</li>
<li>DocumentTagGroupID</li>
<li>DocumentTags</li>
<li>DocumentType</li>
<li>DocumentUrlPath</li>
<li>DocumentUseCustomExtensions</li>
<li>DocumentUseNamePathForUrlPath</li>
<li>DocumentWebParts</li>
<li>DocumentWildcardRule</li>
<li>DocumentWorkflowStepID</li>
</ul>
<p>…And the Node Attributes</p>
<ul>
<li>IsSecuredNode</li>
<li>NodeACLID</li>
<li>NodeAlias</li>
<li>NodeAliasPath</li>
<li>NodeBodyElementAttributes</li>
<li>NodeCacheMinutes</li>
<li>NodeChildNodesCount</li>
<li>NodeClassID</li>
<li>NodeCustomData</li>
<li>NodeDocType</li>
<li>NodeGroupID</li>
<li>NodeGUID</li>
<li>NodeHeadTags</li>
<li>NodeID</li>
<li>NodeInheritPageLevels</li>
<li>NodeLevel</li>
<li>NodeLinkedNodeID</li>
<li>NodeName</li>
<li>NodeOrder</li>
<li>NodeOwner</li>
<li>NodeParentID</li>
<li>NodeSiteID</li>
<li>NodeSKUID</li>
<li>RequiresSSL</li>
</ul>
How To Render An ASP.NET Control To A String2011-03-31T13:00:07+00:00http://johnnycode.com/2011/03/31/how-to-render-an-asp-net-control-to-a-string<p>A simple code snippet. I like to use “using” statements to make sure the various resources get cleaned up in a timely fashion.</p>
<p>Here it is:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var newContent = string.Empty;
using (var stringWriter = new StringWriter())
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
foreach (var control in controls)
{
control.RenderControl(htmlWriter);
}
newContent = stringWriter.ToString();
}
return newContent;
</code></pre></div></div>
Kentico Custom Form Control: Required Checkbox2010-12-03T14:00:55+00:00http://johnnycode.com/2010/12/03/kentico-custom-form-control-required-checkbox<p>Kentico is great but nobody is perfect! One small detail they’ve missed is a checkbox control that you can set to be “required”. By required I mean “You have to check this box”. After doing some Googling, I found this thread which confirmed my suspicion:</p>
<p><a href="http://devnet.kentico.com/Forums/f45/t17269/Making-a-Required-CheckBox-in-Alternative-Form.aspx?replyto=17359">http://devnet.kentico.com/Forums/f45/t17269/Making-a-Required-CheckBox-in-Alternative-Form.aspx?replyto=17359</a></p>
<blockquote>
<p>“We have validators for empty values, which means that if some field have “Allow empty value” property disable and is not filled (is null), validator will appear.</p>
</blockquote>
<p>But checkbox control is never null. It is true, or false, but never null. So you can’t validate it by this simple way”</p>
<p>So, as suggested, I whipped up the Form Control, and have provided the exported control as a download! <a href="http://www.johnnycode.com/blog/wp-content/uploads/2010/12/cms_formusercontrol_RequiredCheckbox.zip">Download the Custom Required Checkbox Form Control</a></p>
How to correctly use a Try/Catch block in C#2010-10-25T12:00:13+00:00http://johnnycode.com/2010/10/25/how-to-correctly-use-a-trycatch-block-in-c<p>If you ever do something like this…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>try
{
// Some potentially dangerous code
}
catch (Exception ex)
{
// Do nothing and swallow the exception
}
</code></pre></div></div>
<p>…DON’T.</p>
<p>There is never a good reason to do this! If you have this code in a Class Library the problem is magnified! Doing this makes it hard to know when an error actually occurs. If you’re not going to actually handle the exception, either remove the try/catch block or add a “throw;” statement to the catch block:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>try
{
// Some potentially dangerous code
}
catch (Exception ex)
{
// Re-throw the exception
// Make sure you don't use "throw ex;", as this will obliterate the stack trace
throw;
}
</code></pre></div></div>
<p>This is pretty much the same as removing the try/catch, but it is an indication that something is potentially dangerous. Later on, you can go back and correctly handle the exception using Elmah with some code like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>try
{
// Some potentially dangerous code
}
catch (Exception ex)
{
// If it's not a critical piece of code log to Elmah then let the application/request continue
ErrorSignal.FromCurrentContext().Raise(ex);
}
</code></pre></div></div>
<p>Utilizing Elmah will allow you to be notified of the error (Or have it logged), but still let the application continue. Of course, you could write your own custom logging or notification component, but why reinvent the wheel? If you do need some custom code, you could write an Elmah handler.</p>
Some useful Visual Studio code snippets2010-10-18T13:00:44+00:00http://johnnycode.com/2010/10/18/some-useful-visual-studio-code-snippets<p>So recently I’ve created a couple useful code snippets, and here they are for you to download!</p>
<p><a href="http://www.johnnycode.com/blog/wp-content/uploads/2010/10/Code-Snippets.zip"></a><a href="http://www.johnnycode.com/blog/wp-content/uploads/2010/10/Code-Snippets1.zip">Download My Code Snippets</a></p>
<p>To use them, just place them in your custom code snippets directory, which will be something like:</p>
<p><code class="language-plaintext highlighter-rouge">C:\Users\{username}\Documents\Visual Studio 2010\Code Snippets</code></p>
<p>Here are the snippets that are included in the zip file download:</p>
<h2 id="c">C#</h2>
<p>sql.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
var sqlCommandText = @"
";
using (var sqlConnection = new SqlConnection(connectionString))
using (var sqlCommand = new SqlCommand(sqlCommandText, sqlConnection))
{
sqlCommand.Connection.Open();
sqlCommand.ExecuteNonQuery();
sqlCommand.Connection.Close();
}
</code></pre></div></div>
<p>void.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void Go( )
{
}
</code></pre></div></div>
<h2 id="aspnet-markuphtmljavascript">ASP.NET Markup/HTML/JavaScript</h2>
<p>jref.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><script type="text/javascript">
(function ($) {
$(function () {
});
})(jQuery);
</script>
</code></pre></div></div>
<p>jscript.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
</code></pre></div></div>
<p>txt.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><asp:TextBox runat="server" ID="uxTextBox" />
</code></pre></div></div>
<p>btn.snippet</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><asp:Button runat="server" ID="uxButton" Text="Submit" />
</code></pre></div></div>
(Really) Getting Started with the Netduino2010-10-11T12:00:51+00:00http://johnnycode.com/2010/10/11/really-getting-started-with-the-netduino<h2 id="introduction">Introduction</h2>
<p>I’m a regular developer like you, foraying into the world of embedded programming. Here is how I got started with the Netduino and some solutions to the issues I’ve dealt with.</p>
<h2 id="where-to-start">Where To Start?</h2>
<p>First off, if you haven’t already, check out the <a href="http://www.netduino.com/downloads/gettingstarted.pdf">Getting Started</a> guide on the Netduino site. This a basic tutorial to get your Netduino blinking the onboard LED. After that you’re sort of left to your own devices (hahaha)… until now!</p>
<h2 id="what-next">What Next?</h2>
<p>In order to understand what is happening with the parts you connect, you need to learn a little bit about electricity. I found <a href="http://www.allaboutcircuits.com/">All About Circuits</a> is a good place to start. Make sure you go to the section on DC, as that is what applies to basic Netduino circuits. I think that AC is more applicable to larger scale applications, like the electricity around your home. I think that DC is generally for the smaller applications, although you can convert between the two. For example, I think that you would need to convert the AC power from your wall socket into DC power to run your Netduino. Possible, but not something you want to tackle right away.</p>
<h2 id="parts">Parts</h2>
<p>So you have your Netduino, you have the knowledge, what next? You need some parts. Parts can be easily bought here:</p>
<ul>
<li><a href="http://www.sparkfun.com/commerce/categories.php">SparkFun Electronics</a></li>
<li><a href="http://www.makershed.com/">Maker Shed</a></li>
<li><a href="http://www.adafruit.com/">Adafruit Industries</a></li>
<li><a href="http://www.radioshack.com">Radio Shack</a> (So you don’t have to pay shipping costs, or if you prefer buying from a brick and mortar)</li>
</ul>
<p>I am not affiliated with these companies, I just know that they sell various electronics and related Arduino parts. What parts do you buy? Here is a basic list to get you started. All of these items are relatively cheap (The links are to SparkFun for no apparent reason):</p>
<ul>
<li>Breadboard - A breadboard is basically a prototyping board that you can use to setup your circuits. <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=7916">Breadboard Mini Self-Adhesive</a></li>
<li>Wires - Duh. You use them to connect your parts together. The one piece of advice I have is that they make some “fancy” wires that have nice grips on the ends of them. They are pricier, but some people seem to love them. <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=9385">“Premium” Jumper Wires</a> (or get cheaper ones at Radio Shack)</li>
<li>LED’s (Light Emitting Diodes) - These are simply lights that you can easily hookup to your board. The simplest Netduino project would involve blinking these on and off. The Getting Started guide I mentioned earlier tells you how to blink the onboard LED.</li>
<li>Resistors - While these parts aren’t very exiting, they are an integral part of almost any circuit you create. They add “resistance” to your circuit and lower the amount of current passing through the wires. These are helpful to make sure your parts are supplied with the right amount of current and don’t get overloaded (and explode!). A few of each type should be more than enough to start with:
<ul>
<li><a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8980">Resistor 1k Ohm 1/6 Watt PTH</a></li>
<li><a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8374">Resistor 10k Ohm 1/6th Watt PTH</a></li>
<li><a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8377">Resistor 330 Ohm 1/6th Watt PTH</a></li>
</ul>
</li>
<li>Push Buttons - When pressed it completes a part of your circuit, but when released it breaks the connection. Allows you to make your circuits interactive! <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=97">Mini Push Button Switch</a></li>
<li>Switches - Allow you to toggle on and off various parts of your circuit (or the whole thing). <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=9609">SPDT Slide Switch</a></li>
<li>Photocell / Photoresistor - This is a special type of resistor whose resistance depends on the amount of ambient light in the room. It’s basically a light sensor. I’ve created a simple circuit that makes an LED brighter the darker the room is. <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=9088">Mini Photocell</a></li>
<li>Potentiometer - An adjustable resistor to do things like make a volume control, or use it to dim your LED’s at will!</li>
<li>Piezoelectric buzzer - A simple speaker that let’s you create simple music and sounds. <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=7950">Buzzer - PC Mount 12mm 2.048kHz</a></li>
<li>Capacitors - I know that these are important, but for the life of me I can’t remember what they do… they’re like a battery… or something…</li>
<li>9V battery and Size M Coaxial DC Power Plug - Go mobile with a battery and accompanying slot! I was able to hook these two up no problem and am able to power the Netduino separate from my computer!</li>
<li>7-segment display - A simple numerical display with a decimal point. Easy to hook up, if a bit time consuming though.</li>
<li>Transistor - Allows you to toggle your circuits using signals sent via code. Switch things on and off through code!</li>
<li>Servo Motor - A simple motor small enough to be powered by your 9 volt battery and the 5V output of the Netduino. Easily control the angle/rotation of the motor!</li>
</ul>
<h2 id="how-do-i-learn">How do I learn?</h2>
<p>Now that I have all the parts, what do I do with them? I would suggest building a proof of concept circuit with each of the above parts.</p>
<ul>
<li>Attach some LED’s to the breadboard and make them blink (Make sure you use a resistor so you don’t overload the LED).</li>
<li>Incorporate the push buttons and switch to switch your LED’s on and off.</li>
<li>Build a light sensor that outputs the current brightness in the room.</li>
<li>Build another light sensor that controls the brightness of the LED.</li>
<li>Play some sounds on the buzzer.</li>
<li>Add a switch to your buzzer circuit to turn it on and off.</li>
<li>Add LED’s to show when the speaker is “off”. (I have done this and will be posting a tutorial soon, complete with code, diagrams and pictures!)</li>
<li>Use the photocell to make the buzzer play sounds depending on the brightness of the room.</li>
</ul>
<p>You can find some simple examples like these online, or search for some code in the <a href="http://forums.netduino.com/">Netduino forums</a>. Of course, you can always ask for help too :D</p>
<h2 id="im-past-the-basics-now-what">I’m past the basics, now what?</h2>
<p>If you want something more advanced I would suggest attempting to tackle some other online tutorials:</p>
<ul>
<li>Check out the <a href="http://netduino.com/projects/">projects page</a> on the Netduino site.</li>
<li>Scott Hanselman has a very simple morse code application in his post about the .NET Micro Framework: <a href="http://www.hanselman.com/blog/TheNETMicroFrameworkHardwareForSoftwarePeople.aspx">The .NET Micro Framework - Hardware for Software People</a></li>
<li>Try and port some Arduino tutorials. Don’t worry it’s easier than it sounds! The arduino is pin-for-pin compatible with the Netduino. The only thing you have to worry about is the Arduino code, which is written in C, and some other small differences (See below).</li>
</ul>
<h2 id="some-last-words-of-advice">Some last words of advice</h2>
<p>If you’re circuit isn’t working correctly, make sure that the Netduino supports what you’re trying to do. For example, the <a href="http://www.netduino.com/netduino/specs.htm">technical specifications page</a> shows that some of the pins support different features. I was trying to use Pulse Width Modulation (sounds way more complicated than it actually is), but the pin I was using didn’t support it! It only works on pins 5, 6, 9, and 10.</p>
<p>Another thing that burned me was when I tried to read data from one of the analog pins. I was following a Arduino tutorial and didn’t realize that the analog pins on the Netduino needed to be hooked up to the Analog Reference pin in order to function correctly.</p>
<p>Hope this information helps someone out there!</p>
Using Kentico's Email Templates in Custom Code2010-07-18T06:08:07+00:00http://johnnycode.com/2010/07/18/using-kenticos-email-templates-in-custom-code<p>Kentico has an email template feature that is used in many areas of the CMS. When a user registers, posts to the forum, or places an order in the E-Commerce system, they are sent an email from a predefined template that has been filled with their information. I’ll show you how easy it is to leverage this feature in your own code.</p>
<p>First, let’s setup our email template. Go to the Site Manager -> Development -> Email Templates, and make a new one:</p>
<p><img src="/assets/images/2010-07-18-using-kenticos-email-templates-in-custom-code/Setting-up-a-New-Email-Template.png" alt="" title="Setting up a New Email Template" /></p>
<p>Piece of cake.</p>
<p>Now let’s create a helper method to making sending emails a little bit easier. The method below takes the name of an email template, the recipient of the email, the macros to replace, and an event name for loggging. Using those variables, the method gets the template, creates an email message from the template, performs replacements using the macros, and sends the email. If an exception is thrown, the event is logged in Kentico’s Event Log.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void SendEmailUsingTemplate(string emailTemplateName, string recipientEmail, string[,] replacements, string eventName)
{
// Set resolver
ContextResolver resolver = CMSContext.CurrentResolver;
resolver.SourceParameters = replacements;
// Get the email template
var template = EmailTemplateProvider.GetEmailTemplate(emailTemplateName, 0);
if (template != null)
{
// Email message
var emailMessage = new EmailMessage
{
EmailFormat = EmailFormatEnum.Default,
Recipients = recipientEmail,
From = EmailHelper.GetSender(template, SettingsKeyProvider.GetStringValue(CMSContext.CurrentSiteName + ".CMSNoreplyEmailAddress")),
CcRecipients = template.TemplateCc,
BccRecipients = template.TemplateBcc,
Subject = resolver.ResolveMacros(template.TemplateSubject),
PlainTextBody = resolver.ResolveMacros(template.TemplatePlainText)
};
// Enable macro encoding for body
resolver.EncodeResolvedValues = true;
emailMessage.Body = resolver.ResolveMacros(template.TemplateText);
// Disable macro encoding for plaintext body and subject
resolver.EncodeResolvedValues = false;
try
{
MetaFileInfoProvider.ResolveMetaFileImages(emailMessage, template.TemplateID, EmailObjectType.EMAILTEMPLATE, MetaFileInfoProvider.OBJECT_CATEGORY_TEMPLATE);
// Send the e-mail immediately
EmailSender.SendEmail(CMSContext.CurrentSiteName, emailMessage, true);
}
catch (Exception ex)
{
var eventLogProvider = new EventLogProvider();
eventLogProvider.LogEvent("E", eventName, ex);
throw;
}
}
}
</code></pre></div></div>
<p>Now that we have the helper method, we can send an email with just a few lines of code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>string emailTemplateName = "WeeklySummary";
string[,] replacements = new string[3, 2];
replacements[0, 0] = "WeeklySummaryTitle";
replacements[0, 1] = "Your Weekly Summary";
replacements[1, 0] = "UnreadMessageCount";
replacements[1, 1] = "5";
replacements[2, 0] = "PendingFriendRequestsCount";
replacements[2, 1] = "50";
SendEmailUsingTemplate(
emailTemplateName,
"enduser@example.com",
replacements,
"Weekly Summary - Sending Emails");
</code></pre></div></div>
<p>It couldn’t be easier! Just make sure the string array is the correct size, depending on the number of macros you are replacing. You could easily make the array dynamic if you didn’t know beforehand how many macros you might have.</p>
<p>One more thing. I made this email template at the Global scope, so I pass in 0 as the Current Site ID in the call to EmailTemplateProvider.GetEmailTemplate(). You can easily change this to use the current site if you setup the email templates per site. Just remember that 0 is for Global scope!</p>
<p>Thanks for listening!</p>
Adding Macro Expression support to Kentico Web Parts2010-07-16T13:00:35+00:00http://johnnycode.com/2010/07/16/adding-macro-support-to-kentico-web-parts<p>A coworker of mine had a BizForm in Kentico that needed a dynamic URL Redirection after the form was submitted. Based on the page with the BizForm, the user would be redirected to a different thank you page. There are many reasons you could want dynamic thank you pages for a single form. For starters, it’s a lot easier to manage one set of data. Then there are the SEO benefits of having separate thank you pages. Don’t forget you might simply want different content, or another page/template entirely! We can accomplish this using <a href="http://www.kentico.com/docs/devguide/index.html?appendix_a___macro_expressions.htm">Kentico’s Macro Expressions</a>.</p>
<p>A week ago I had been looking through some Kentico code and remembered seeing code that resolved Macro Expressions in the subject and body text of the email templates. I actually forgot where that code was, so I went ahead with intellisense, and found the MacroResolver class. That class contains the ContainsMacro and ResolveMacros methods which are self explanatory. It couldn’t be easier! Check out he code below:</p>
<p>Here is the code to register the event handler:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Put this at the end of the "protected void SetupControl()" method
viewBiz.OnAfterSave += new CMS.FormControls.BizForm.OnAfterSaveEventHandler(viewBiz_OnAfterSave);
</code></pre></div></div>
<p>And here is the event handler:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> protected void viewBiz_OnAfterSave()
{
var bizFormInfo = BizFormInfoProvider.GetBizFormInfo(viewBiz.FormName, CMSContext.CurrentSiteID);
if (!string.IsNullOrEmpty(bizFormInfo.FormRedirectToUrl) && MacroResolver.ContainsMacro(bizFormInfo.FormRedirectToUrl))
{
// Resolve macro expressions in the redirect URL
// So you can do something like: {<span></span>%cmscontext.currentdocument.documentname%<span></span>}
UrlHelper.Redirect(ContextResolver.ResolveMacros(bizFormInfo.FormRedirectToUrl));
}
}
</code></pre></div></div>
<p>By modifying the BizForm code, you can add this macro expression…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{<span></span>%cmscontext.currentdocument.documentname%<span></span>}
</code></pre></div></div>
<p>to your URL redirection value like this…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.example.com/thankyou.aspx?source={<span></span>%cmscontext.currentdocument.documentname%<span></span>}
</code></pre></div></div>
<p>and after filling out a BizForm on this page…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.example.com/form_page.aspx
</code></pre></div></div>
<p>you get redirected to here…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://www.example.com/thankyou.aspx?source=form_page
</code></pre></div></div>
<p>And that’s a wrap!</p>
My First Day Using Git On Windows 72010-07-09T13:00:51+00:00http://johnnycode.com/2010/07/09/my-first-day-using-git-on-windows-7<h2 id="background">Background</h2>
<p>I recently started a project for a client where I’ve been testing changes on my machines, then pushing bits of functionality to their QA server. To keep track of the changes I’m making to the system, and to be able to roll back to previous versions of my own code, I decided to try out Git as my source/version control system.</p>
<h2 id="installation">Installation</h2>
<p>The install of Git and Tortoise Git was simple. Git had a few “scary” looking options, but it seemed like the safe way to go was to use the defaults, so I did just that. FYI, I wasn’t thinking when I first started and tried to use TortoiseGit without Git actually installed locally. That didn’t work! Make sure you install Git in addition to TortoiseGit! The order in which they are installed does not seem to matter.</p>
<h2 id="usage">Usage</h2>
<p>For my first task, I ran a default install of Kentico CMS 5.5 and tried to check it in to my local repository. Since I’m not really a fan of the command line, I started with TortoiseGit. I used the explorer context menu to create a repository without problems. Super fast, super simple:</p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Creating-a-Git-Repository-from-the-Explorer-Context-Menu.png" alt="" title="Creating a Git Repository from the Explorer Context Menu" /></p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Creating-a-Git-Repository.png" alt="" title="Git Repository Successfully Created" /></p>
<p>Next, I used the explorer context menu to try and commit the whole website directory. No dice. TortoiseGit hung for a long time and I remember seeing some errors about line endings or something. <strong>(I later tried using TortoiseGit again, and while it took a LONG time, it did work)</strong></p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Initial-Commit-with-TortoiseGit-Not-Responding.png" alt="" title="Initial Commit with TortoiseGit Not Responding" /></p>
<p>At that point I fell back on the command line, and things went smoothly from there. I decided to start over with the command line so I deleted the “.git” directory. Since git stores _almost _everything in that directory, that removed any trace of Git from my project/website. To compare this process to SVN, you would have to do an export of the folder, or use some other method to remove all of the nested SVN folders.</p>
<p>With a clean slate, I opened the command line by bringing up the explorer context menu, and clicking “Git Bash Here”.</p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Starting-the-Git-Bash-from-the-Explorer-Context-Menu.png" alt="" title="Starting the Git Bash from the Explorer Context Menu" /></p>
<p>That brings up the Git Bash.</p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Git-Bash.png" alt="" title="The Git Bash" /></p>
<p>Now that I was in the Bash, I needed to (re) init the Git Repository, add the files to the staging area, and then commit the files to the local repository:</p>
<ul>
<li>git init</li>
<li>git add . (I think “git init *” works too)</li>
<li>git commit -m “Your commit message here”</li>
</ul>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Git-Bash-Init-Command.png" alt="" title="Git Bash - Init Command" /></p>
<p>I was going to post the “add” and “commit” screenshots here, but it didn’t make sense since the output is so long (13,000+ files). But it wasn’t anything that interesting. At that point I was ready to rock and roll and start modifying and adding source code! After changing a file, I ran the “git status” command to see what was changed. Then I ran the commit command with the “-am” flags to commit all previously added files so I didn’t have to add them again manually. I also specified another commit message.</p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Git-Bash-Committing-Changes.png" alt="" title="Git Bash - Committing Changes" /></p>
<p>Easy as can be! No surprises here, but again, I wasn’t doing anything fancy. Just committing some simple code changes into my local repository. In case you were wondering, I did go and try out TortoiseGit for making commits too, and didn’t have any problems.</p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Commiting-Changes-from-the-Explorer-Context-Menu.png" alt="" title="Commiting Changes from the Explorer Context Menu" /></p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Commiting-Changes-with-TortoiseGit.png" alt="" title="Commiting Changes with TortoiseGit" /></p>
<p><img src="/assets/images/2010-07-09-my-first-day-using-git-on-windows-7/Commiting-Changes-with-TortoiseGit-Success.png" alt="" title="Commiting Changes with TortoiseGit - Success" /></p>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Obviously I didn’t utilize any of the advanced or powerful features of Git (yet). All I did was get up and running with a repository, and start making simple commits. However, I am pleased with the similarities of Git to other version control systems. Hopefully, taking the next steps with Git will be just as easy. If I end up jumping into the more complex and useful features of Git, I’ll try and write another post! Thanks!</p>
Introducing the Custom Settings Module for Kentico CMS2010-07-08T13:00:01+00:00http://johnnycode.com/2010/07/08/introducing-the-custom-settings-module-for-kentico-cms<h2 id="background">Background</h2>
<p>Two weeks ago I was developing some custom functionality for <a href="http://www.kentico.com">Kentico CMS</a>. I realized that my custom code had a lot of configurable settings (configuration settings). In the past, we’ve used the appSettings section of the web.config, but I’ve never liked it. Mainly, the appSettings section is unmanageable by non-technical users, although there are other reasons. So I decided to develop a custom module to store custom configuration settings right inside Kentico!</p>
<p><strong><a href="/kentico-resources/kentico-cms-custom-settings-module/">Download the Custom Settings Module for Kentico CMS</a></strong></p>
<p>Right now the code is only on my blog but the plan is to put it on GitHub soon. The custom module is free to use, just don’t claim it as your own! Also, if you’re <em>really</em> appreciative, feel free to donate via the Paypal link at the bottom of the download page :) Also, don’t forget to give me feedback! If there are issues and bugs, let me know. If you have suggestions, let me know!</p>
<p><strong><a href="/kentico-resources/kentico-cms-custom-settings-module/">Download the Custom Settings Module for Kentico CMS</a></strong></p>
Using Kentico's API to Programmatically Create Forum Groups and Forums2010-06-24T13:00:42+00:00http://johnnycode.com/2010/06/24/using-kenticos-api-to-programmatically-create-forum-groups-and-forums<h2 id="introduction">Introduction</h2>
<p>Building off my last post about <a href="http://www.johnnycode.com/blog/2010/06/23/using-kenticos-api-to-programmatically-create-a-media-library/">Using Kentico’s API to Programmatically Create a Media Library</a>, our customer also needed to have Forum Groups and Forums automatically created when a Kentico Group was created.</p>
<p>A Forum Group in Kentico is the outer forum entity, and the Forums inside that Forum Group are the different areas where people actually post threads. It is a standard online forum configuration. Forum Groups can be stand alone, or belong to a Community Group. Using the API, we can create Forum Groups and Forums programmatically.</p>
<h2 id="the-code">The Code</h2>
<p>The code is very similar to creating Media Libraries. The main difference is that we’re using the ForumGroupInfo and ForumInfo classes. First we “new up” the ForumGroupInfo class, associate it with our group, and save it to the database. All we need is a code name, display name, and the group’s ID.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static ForumGroupInfo CreateForumGroup(string codeName, string displayName, int groupId)
{
var forumInfo = new ForumGroupInfo
{
GroupGroupID = groupId,
GroupName = codeName,
GroupDisplayName = displayName,
GroupSiteID = CMSContext.CurrentSiteID
};
forumInfo.Insert();
return forumInfo;
}
</code></pre></div></div>
<p>Now that we have the ForumGroupInfo object associated with our Group, we can go and create the individual forums that comprise the Forum Group. Again, very similar code, albeit it is a bit lengthier. The big things to note here are that we are “newing up” a ForumInfo object, configuring a bunch of settings (including forum permissions), and saving it to the database. The only slightly strange thing I found was that I was required to set ForumThreads and ForumPosts, which I think are simply counts, so I set them to 0.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private static ForumInfo CreateForum(ForumGroupInfo forumGroupInfo, string codeName, string displayName)
{
var forumInfo = new ForumInfo
{
ForumGroupID = forumGroupInfo.GroupID,
ForumName = codeName,
ForumDisplayName = displayName,
ForumSiteID = CMSContext.CurrentSiteID,
ForumOpen = true,
ForumIsLocked = false,
ForumModerated = true,
ForumThreads = 0,
ForumPosts = 0,
AllowAccess = SecurityAccessEnum.AllUsers,
AllowAttachFiles = SecurityAccessEnum.AllUsers,
AllowMarkAsAnswer = SecurityAccessEnum.AllUsers,
AllowPost = SecurityAccessEnum.AllUsers,
AllowReply = SecurityAccessEnum.AllUsers,
AllowSubscribe = SecurityAccessEnum.AllUsers,
};
// Inherit the discussion action permissions from the forum group
forumInfo.SetValue("ForumDiscussionActions", null);
forumInfo.Insert();
return forumInfo;
}
</code></pre></div></div>
<p>So that is the basic code for creating forums and forum groups. Not every one of those fields are required, but it definitely does include the required ones. Here is one additional setting you can use to have your forum inherit some of its settings from the forum group.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Inherit the discussion action permissions from the forum group
forumInfo.SetValue("ForumDiscussionActions", null);
</code></pre></div></div>
<p>Using that code above directly accesses the underlying data object for the ForumInfo class. The reason we do it this way is that the normal properties on the ForumInfo object are all bools! You can’t set a bool to null, unless it is nullable, which these are not. Setting it to null tells Kentico to inherit the value from the forum group. This also applies to some other settings on the ForumInfo object. If you want to know which ones you can inherit, just check out the actual Forum Configuration UI, and look for the settings that have a checkbox for “Inherit from parent”.</p>
<p>Now for a given Forum Group you can create as many Forums as you need. One little caveat: Be careful about the naming conventions of some of the properties on the ForumGroupInfo object. Properties whose name contains “Group” may be referencing the Forum Group, OR the Community Group. Just check the intellisense, or just remember that <strong>“GroupGroupID” stands for the ID of the Community Group</strong>, and <strong>“GroupID” stands for the Forum Group ID</strong>. Happy coding!</p>
Using Kentico's API to Programmatically Create a Media Library2010-06-23T13:00:32+00:00http://johnnycode.com/2010/06/23/using-kenticos-api-to-programmatically-create-a-media-library<h2 id="introduction">Introduction</h2>
<p>While Kentico has a really great API, their <a href="http://www.kentico.com/docs/devguide/index.html">developer manual</a>, <a href="http://devnet.kentico.com/Knowledge-Base.aspx">knowledge base</a> and other forms of documentation don’t always contain examples for every scenario. Luckily, figuring things out on your own is usually just a matter of taking a quick peak at some of Kentico’s own code and you’re off and running!</p>
<p>Recently a customer was creating a community site where their end users would be creating different groups on their site. Kentico’s community features new to 5.x are really cool and you should check them out if you haven’t already. The easiest way to experience the awesomeness is to simply install the <a href="http://devnet.kentico.com/docs/communitysiteguide/index.html">Community Site Template </a>when making a new site. That site template will already be setup with the specific community features.</p>
<p>While the community features of Kentico are good, there are some things that are lacking, one of which is a default group setup. So when an end user goes to your site and creates their own group, they have to manually create a Media Library. Our customer wanted the group to be fully configured upon creation, so I added some code to the group registration web part in order to do so.</p>
<h2 id="the-code">The Code</h2>
<p>The code is very straight forward. I have created a method that takes the code name, display name, folder name, a description, and the path to a teaser image. The description and teaser image path aren’t required, but I added them for the heck of it. The code simply “news up” an instance of the MediaLibraryInfo class, and calls it’s insert method! That is it!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private static MediaLibraryInfo CreateMediaLibrary(string codeName, string displayName, string folderName, string description, string teaserPath)
{
var mediaLibraryInfo = new MediaLibraryInfo
{
LibrarySiteID = CMSContext.CurrentSiteID,
LibraryName = codeName,
LibraryDisplayName = displayName,
LibraryFolder = folderName,
LibraryDescription = description,
LibraryTeaserPath = teaserPath,
FileCreate = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
FileDelete = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
FileModify = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
FolderCreate = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
FolderDelete = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
FolderModify = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
Access = CMS.SiteProvider.SecurityAccessEnum.AllUsers,
};
mediaLibraryInfo.Insert();
return mediaLibraryInfo;
}
</code></pre></div></div>
<p>Now the code above doesn’t actually associate the media library to a group, it only creates a “global” one. In order to associate it to a group, just add one line of code!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mediaLibraryInfo.LibraryGroupID = groupId;
</code></pre></div></div>
Python 3 + PyGame, SQLite, and Travian: Tracking Historical Data and Multiple Servers2010-06-09T12:38:10+00:00http://johnnycode.com/2010/06/09/python-3-pygame-sqlite-and-travian-tracking-historical-data-and-multiple-servers<p>So I’ve updated the script to add some useful features.</p>
<h3 id="update"><strong>UPDATE</strong></h3>
<p>I’ve updated the code with the new Travian server names and I incorporated a little bit of error handling in the case that unzipping doesn’t produce a file. I also changed the dictionary of servers to a list of tuples, which keeps the ordering of the servers correct during a loop. Other than that, the rest of the script is the same.</p>
<h2 id="historical-data">Historical Data</h2>
<p>Now I attach a date field (and new primary key) to each row in each data dump so the data doesn’t get overridden each day. This way the data is tracked over time and we will be able run reports that show the server’s progression. You can track how quickly players and alliances progress. One idea I have is to generate a movie of all the maps that are created. The possibilities are endless!</p>
<h2 id="multiple-servers">Multiple Servers</h2>
<p>This script wouldn’t be that great if it only did one server right? So now we setup a dictionary of servers in the beginning of the script and iterate over them calling all the methods for each one. During each iteration, we create a sub-directory in our current folder, and place the server-specific files there. The SQL files, images and database file for each server are separated from all the others so everything is organized.</p>
<h2 id="miscellaneous-changes">Miscellaneous Changes</h2>
<p>The script now references the gzipped map.sql files on the Travian servers (map.sql.gz). A minor change, but useful nonetheless. This might slow down the data processing a little, but the file downloads from the servers should be a lot faster. The map.sql files are simply text files full of SQL INSERT commands and text data compresses nicely. Looking at a gzipped data file from S1, the file size is 728KB which decompresses to 2,645KB!!! That is over 3.5 times smaller! If you’re downloading the data from ALL the servers, this will be a huge time/resource saver (I think there are 100’s of servers across all the different global domains).</p>
<h2 id="the-code">The Code</h2>
<p>The full code to the updated script is below. Next up, I’ll try and enhance the script to be used as a library. Currently the script can only be run straight through, but we can make it so that you can utilize individual pieces of the script like an API. This will allow us to make other scripts that call into our Travian script to track players or alliances.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/usr/bin/env python
import os # For working with the file system
import urllib.request # For getting data from web pages
import sqlite3 # for data persistence
import pygame
import pygame.image
import datetime
import gzip
# A dictionary of the server names along with the download URL
# Could be automated for now, but foreign servers have different filenames
server_infos = [
("ts1.travian.com", "http://ts1.travian.com/map.sql.gz"),
("ts2.travian.com", "http://ts2.travian.com/map.sql.gz"),
("ts3.travian.com", "http://ts3.travian.com/map.sql.gz"),
("ts4.travian.com", "http://ts4.travian.com/map.sql.gz"),
("ts5.travian.com", "http://ts5.travian.com/map.sql.gz"),
("ts6.travian.com", "http://ts6.travian.com/map.sql.gz"),
("ts7.travian.com", "http://ts7.travian.com/map.sql.gz"),
("ts8.travian.com", "http://ts8.travian.com/map.sql.gz")
]
today = datetime.date.today()
data_file_name_zipped = "{0}.sql.gz".format(today)
data_file_name = "{0}.sql".format(today)
image_file_name = "{0}.jpg".format(today)
# An extension isn't required but I feel we should have one
database_extension = ".sqlite"
# Size of the grid
size = 800
# Offset so we can draw the map correctly
offset = 400
base_directory = os.getcwd()
def main():
for server in server_infos:
# Setup server-specific names and paths
server_name, url = server
database_name = server_name + database_extension
print(server_name)
full_server_path = os.path.join(base_directory, "data", server_name)
# Make sure the directory tree exists
if(not os.path.exists(full_server_path)):
os.makedirs(full_server_path)
# Perform all server-specific operations from that directory
os.chdir(full_server_path)
print("\tDownloading data file from {0}".format(url))
download(url, data_file_name_zipped, data_file_name);
print("\tDone.")
print("\tCreating table in database " + database_name)
create_table(database_name)
print("\tDone.")
print("\tClearing old data if needed...")
clear_data(database_name, today)
print("\tDone.")
print("\tLoading data file into SQL Lite database " + database_name)
load_data(database_name, data_file_name, today)
print("\tDone.")
print("\tStatistics for {0}:".format(server_name))
statistics = get_statistics(database_name)
print("\t\tPopulation of Travian: {0}".format(statistics["population"]))
print("\t\tNumber of users in Travian: {0}".format(statistics["user_count"]))
print("\t\tNumber of villages in Travian: {0}".format(statistics["village_count"]))
print("\tGenerating world map for {0} to file {1}".format(server_name, generate_map_image(database_name, image_file_name, today)))
print("\tDone.")
print("\n")
# Originally from http://code.activestate.com/recipes/496685-downloading-a-file-from-the-web/
# Copy the contents of a file from a given URL to a local file.
def download(url, file_name_zipped, file_name):
if(not os.path.exists(file_name_zipped)):
# Download the gzipped file
urllib.request.urlretrieve(url, file_name_zipped)
# Open the gzipped file and write the contents to an uncompressed file
data_file_zipped = gzip.open(file_name_zipped, 'r')
data_file_unzipped = open(file_name, "wb")
data = data_file_zipped.read()
data_file_unzipped.write(data)
# Close the file handles
data_file_unzipped.close()
data_file_zipped.close()
# You could add code to delete the original gzipped file if you want
def create_table(database_name):
# This SQL originally from http://help.travian.com/index.php?type=faq&mod;=230
# But I made some minor modifications so it works with SQLite
table_sql = """CREATE TABLE x_world (
data_id integer PRIMARY KEY ASC AUTOINCREMENT NOT NULL,
id integer NOT NULL DEFAULT '0',
x integer NOT NULL default '0',
y integer NOT NULL default '0',
tid integer unsigned NOT NULL default '0',
vid integer unsigned NOT NULL default '0',
village text NOT NULL default '',
uid integer NOT NULL default '0',
player text NOT NULL default '',
aid integer unsigned NOT NULL default '0',
alliance text NOT NULL default '',
population integer unsigned NOT NULL default '0',
date_created text
);"""
# Try and create the table.
# If it fails it's probably because the table exists
# We should probably handle this better though
try:
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_cursor.execute(table_sql)
sql_connection.commit()
except:
pass
finally:
sql_connection.close()
def clear_data(database_name, date_to_delete):
sql_delete_current_data = """DELETE
FROM x_world
WHERE date_created = ?"""
# Delete all the existing data from the given date
try:
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_cursor.execute(sql_delete_current_data, [date_to_delete])
sql_connection.commit()
except:
print("Warning:", sys.exc_info()[0])
finally:
sql_connection.close()
def load_data(database_name, data_file_name, today):
try:
# Open the data file
data_file = open(data_file_name, mode='r', encoding="UTF8")
try:
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
# string.replace() to make the columns and data match up with our new schema
# And run each SQL statement from the data file
for line in data_file:
line = line.replace("VALUES", "(id, x, y, tid, vid, village, uid, player, aid, alliance, population) VALUES")
sql_cursor.execute(line)
# Update all the new data with today's date
sql_update_todays = """UPDATE x_world
SET date_created = ?
WHERE date_created IS NULL"""
sql_cursor.execute(sql_update_todays, [today])
sql_connection.commit()
except:
pass
finally:
sql_connection.close()
except:
pass
def get_statistics(database_name):
try:
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Population query
sql_population = """SELECT SUM(population) FROM x_world"""
sql_cursor.execute(sql_population)
population = sql_cursor.fetchone()[0]
#User count query
sql_count_users = """SELECT COUNT(DISTINCT(uid)) FROM x_world"""
sql_cursor.execute(sql_count_users)
user_count = sql_cursor.fetchone()[0]
#Village count query
sql_count_villages = """SELECT COUNT(*) FROM x_world"""
sql_cursor.execute(sql_count_villages)
village_count = sql_cursor.fetchone()[0]
return { "population" : population, "user_count" : user_count, "village_count" : village_count }
except:
pass
finally:
sql_connection.close()
def generate_map_image(database_name, image_file_name, date):
try:
sql_connection = sqlite3.connect(database_name)
sql_connection.row_factory = sqlite3.Row
sql_cursor = sql_connection.cursor()
# Locations query
sql_all = """SELECT x, y FROM x_world where date_created = ?"""
#Create a surface (like an image canvas)
surface = pygame.Surface((size, size))
#Paint the background white
back_color = pygame.Color(255, 255, 255, 255)
surface.fill(back_color)
#The color red for coloring the villages
color = pygame.Color(255, 0, 0, 255)
sql_cursor.execute(sql_all, [date])
#For each village, set the corresponding pixel to red
for row in sql_cursor.fetchall():
surface.set_at((row[0] + offset, row[1] + offset), color)
#Save the image to disk
#Will save as a PNG file because of the extension
pygame.image.save(surface, image_file_name)
sql_connection.commit()
except:
pass
finally:
sql_connection.close()
return image_file_name
#Run the main function
main()
</code></pre></div></div>
Firefox (3.6.3) Strictly Renders Closing Comment Tags2010-06-03T12:30:27+00:00http://johnnycode.com/2010/06/03/firefox-3-6-3-strictly-renders-closing-comment-tags<p>So a coworker of mine had an interesting problem where a content area was disappearing from a CMS we use. The issue happened in Firefox while Internet Explorer and Chrome were fine! How rare is that! It turns out that the issue was relating to a mistyped closing comment tag.</p>
<p>Apparently Firefox correctly renders the code, and doesn’t actually close the comment if one of the hyphens is missing. Instead, the rendering continues to hide the content until <em>another</em> (correct) closing comment tag is found!</p>
<p>Here is example. Below are 4 content tags, with separate comment tags in between them. If you’re viewing this page in Firefox, then you should see that 2nd comment tag actually visible on the page. If you’re in Internet Explorer or Chrome, you wont see anything weird:</p>
<p>Content 1</p>
<!-- Comment 1 -->
<p>Content 2</p>
<!-- Comment 2 -->
<p>Content 3</p>
<!-- Comment 3 -->
<p>Content 4</p>
<p>And here is a complete example HTML page:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>FireFox Comment Test</title>
</head>
<body>
<p>Content 1</p>
<!-- Comment 1 -->
<p>Content 2</p>
<!-- Comment 2 ->
<p>Content 3</p>
<!-- Comment 3 -->
<p>Content 4</p>
</body>
</html>
</code></pre></div></div>
Python 3 + PyGame, SQLite, and Travian: Generating the World Map2010-06-02T12:30:04+00:00http://johnnycode.com/2010/06/02/python-3-pygame-sqlite-and-travian-generating-the-world-map<h3 id="background">Background</h3>
<p>In the last post I showed you how you could get the Travian game data, load it into SQLite, and then run some simple queries. Now, I will show you how to take that one step further and use the data to generate a BMP, TGA, PNG, or JPEG image!</p>
<p>First, we need to get <a href="http://www.pygame.org/news.html">Pygame</a>. Pygame is actually a Python Game Development library, but we’re just going to be using it for generating images. It’s a small download, and easy install, just make sure you get the right version for your version of Python. There is a library out there called the <a href="http://www.pythonware.com/products/pil/">Python Imaging Library (PIL)</a>, but apparently they haven’t updated their code to be compatible with Python 3. Hopefully they do soon!</p>
<p>Now that we have PyGame, we start with the old script we had and add a new function for creating the PNG. I’m saving the image as a PNG, but according to the <a href="http://www.pygame.org/docs/ref/image.html#pygame.image.save">PyGame documentation</a>, you should be able to output your image as BMP, TGA, PNG, or JPEG, simply based on what your file’s extension is.</p>
<p><img src="/assets/images/2010-06-02-python-3-pygame-sqlite-and-travian-generating-the-world-map/Programmatically-Generated-Travian-World-Map-300x300.png" alt="" title="Programmatically Generated Travian World Map" /></p>
<h3 id="the-new-code">The New Code</h3>
<p>The function below is the new function that does the work. It:</p>
<ul>
<li>Creates an image surface to work with. (based on the map size)</li>
<li>Reads the data back from SQLite.</li>
<li>Sets each pixel that has a village to the color red.</li>
<li>
<p>Saves the image to disk.</p>
<p>def create_map(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> #Min/Max query for calculating how big the map is
sql_mins_maxes = """SELECT MIN(X), MIN(y), MAX(x), MAX(y)
FROM x_world"""
sql_cursor.execute(sql_mins_maxes)
row = sql_cursor.fetchone()
min_x = row[0]
min_y = row[1]
max_x = row[2]
max_y = row[3]
width = max_x - min_x
height = max_y - min_y
x_offset = width // 2
y_offset = height // 2
# Locations query
sql_all = """SELECT x, y
FROM x_world"""
#Current working directory
current_directory = os.getcwd()
#Create a surface (like an image canvas)
surface = pygame.Surface((width, height))
#Paint the background white
back_color = pygame.Color(255, 255, 255, 255)
surface.fill(back_color)
#The color red for coloring the villages
color = pygame.Color(255, 0, 0, 255)
sql_cursor.execute(sql_all)
#For each village, set the corresponding pixel to red
for row in sql_cursor.fetchall():
surface.set_at((row[0] + x_offset,row[1] + y_offset), color)
#Save the image to disk
#Will save as a PNG file because of the extension
pygame.image.save(surface, os.path.join(current_directory, "test.png"))
sql_connection.commit()
sql_connection.close()
</code></pre></div> </div>
</li>
</ul>
<h3 id="the-full-code">The Full Code</h3>
<p>And here is the complete updated code that runs great with my installation of Python 3.12 and PyGame 1.91. I hope you boys and girls enjoyed the update!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/usr/bin/env python
import os # For working with the file system
import urllib.request # For getting data from web pages
import sqlite3 # for data persistence
import pygame.surface
import pygame.image
def main():
script_url = "http://s1.travian.com/map.sql"
data_file_name = "map.sql"
database_name = "travian"
print("Downloading data file \nfrom:\t{0}\nto:\t{1}\n...".format(script_url , data_file_name))
download(script_url, data_file_name);
print("Done.\n")
print("Creating table if needed...")
create_table(database_name)
print("Done.\n")
print("Clearing old data if needed...")
clear_data(database_name)
print("Done.\n")
print("Loading data file into SQL Lite...")
load_data(database_name, data_file_name)
print("Done.\n")
print("Statistics:")
print_stats(database_name)
print("\n")
print("Generating world map...")
create_map(database_name)
print("Done.\n")
# Originally from http://code.activestate.com/recipes/496685-downloading-a-file-from-the-web/
# Copy the contents of a file from a given URL to a local file.
def download(url, file_name):
urllib.request.urlretrieve(url, file_name)
def create_table(database_name):
#Try and create the table.
#If it fails, it's probably because the table exists
try:
table_sql = """CREATE TABLE `x_world` (
id integer PRIMARY KEY ASC AUTOINCREMENT NOT NULL DEFAULT '0',
x integer NOT NULL default '0',
y integer NOT NULL default '0',
tid integer unsigned NOT NULL default '0',
vid integer unsigned NOT NULL default '0',
village text NOT NULL default '',
uid integer NOT NULL default '0',
player text NOT NULL default '',
aid integer unsigned NOT NULL default '0',
alliance text NOT NULL default '',
population integer unsigned NOT NULL default '0'
);"""
#Open a connection to the SQLite database and create the table
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_cursor.execute(table_sql)
sql_connection.commit()
sql_connection.close()
except:
pass
def clear_data(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_command = "DELETE FROM x_world"
#Delete all the existing data, if there is any
sql_cursor.execute(sql_command)
sql_connection.commit()
sql_connection.close()
def load_data(database_name, data_file_name):
#Open the data file
data_file = open(data_file_name, mode='r', encoding="UTF8")
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Run each SQL statement from the data file
for line in data_file:
sql_cursor.execute(line)
sql_connection.commit()
sql_connection.close()
def print_stats(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Population query
sql_population = """SELECT SUM(population)
FROM x_world"""
sql_cursor.execute(sql_population)
population = sql_cursor.fetchone()[0]
#User count query
sql_count_users = """SELECT COUNT(DISTINCT(uid))
FROM x_world"""
sql_cursor.execute(sql_count_users)
user_count = sql_cursor.fetchone()[0]
#Village count query
sql_count_villages = """SELECT COUNT(*)
FROM x_world"""
sql_cursor.execute(sql_count_villages)
village_count = sql_cursor.fetchone()[0]
#Print results
print("Population of Travian: {0}".format(population))
print("Number of users in Travian: {0}".format(user_count))
print("Number of villages in Travian: {0}".format(village_count))
sql_connection.commit()
sql_connection.close()
def create_map(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Min/Max query for calculating how big the map is
sql_mins_maxes = """SELECT MIN(X), MIN(y), MAX(x), MAX(y)
FROM x_world"""
sql_cursor.execute(sql_mins_maxes)
row = sql_cursor.fetchone()
min_x = row[0]
min_y = row[1]
max_x = row[2]
max_y = row[3]
width = max_x - min_x
height = max_y - min_y
x_offset = width // 2
y_offset = height // 2
# Locations query
sql_all = """SELECT x, y
FROM x_world"""
#Current working directory
current_directory = os.getcwd()
#Create a surface (like an image canvas)
surface = pygame.Surface((width, height))
#Paint the background white
back_color = pygame.Color(255, 255, 255, 255)
surface.fill(back_color)
#The color red for coloring the villages
color = pygame.Color(255, 0, 0, 255)
sql_cursor.execute(sql_all)
#For each village, set the corresponding pixel to red
for row in sql_cursor.fetchall():
surface.set_at((row[0] + x_offset,row[1] + y_offset), color)
#Save the image to disk
#Will save as a PNG file because of the extension
pygame.image.save(surface, os.path.join(current_directory, "test.png"))
sql_connection.commit()
sql_connection.close()
#Run the main function
main()
</code></pre></div></div>
Python 3, SQLite, and Travian: Working with Game Data2010-06-01T12:30:29+00:00http://johnnycode.com/2010/06/01/working-with-travian-game-data-with-python-and-sqlite<h3 id="update"><strong>Update</strong></h3>
<p>If there was actually out there who read this and tried the code, it may not have worked properly with Python 3. I’ve updated the code against my installation of 3.12 and now it should be working fine. Somehow, I had an older version of Python installed that was running the code! Sorry about that!</p>
<h3 id="background">Background</h3>
<p>There was a 40% off any item coupon at Borders this weekend that I probably should have <a href="https://twitter.com/JohnBubriski">tweeted</a> about. In any case, I didn’t have any books in mind when we actually went there, so on a whim, I saw a <a href="http://www.manning.com/">Manning Publications Co.</a> book about Python and grabbed it for $25. The book is <a href="http://www.amazon.com/gp/product/193518220X?ie=UTF8&tag=johcod-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=193518220X">The Quick Python Book, Second Edition</a><img src="http://www.assoc-amazon.com/e/ir?t=johcod-20&l=as2&o=1&a=193518220X" alt="" /> by <a href="http://learnpython.wordpress.com/">Vern Ceder</a>. By some act of God I found some time this weekend and managed to get through the first couple chapters. In order to let the knowledge really soak in, I decided that I would right a working script, and blog about it before getting back to work on Tuesday! So here we go!</p>
<p>Enter <a href="http://www.travian.com/">Travian</a>…</p>
<blockquote>
<p>Travian is a browser game featuring a world with thousands of other real players. One begins the game acting as a chief of a tiny village.</p>
</blockquote>
<p>From there, you build up your village and army, build more villages, form alliances, and attack other players (or be attacked). A fun game that is constantly in motion. There are no turns in the game, only waiting for resources to be collected, and troops to march.</p>
<p>One cool thing about the game is that they provide an export of their data, much like <a href="http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/">Stackoverflow does with their data</a>. The big difference is the export is daily, and that there isn’t really any content in the data. Just ID’s and numbers. I’m also not sure if the data is considered Creative Commons or not. Travian has their own tutorial on <a href="http://help.travian.com/index.php?type=faq&mod=230">creating world maps</a>. Long story short, they provide a map.sql file that you can most likely import into MySQL or SQLite, and work with from there.</p>
<p>So the script I wrote is pretty simple, but I’m proud that I did it so quickly, and on my own! All it does is:</p>
<ol>
<li>Download the map.sql data file.</li>
<li>Try create the table in SQLite if it doesn’t exist.</li>
<li>Try to clear the table if it already existed.</li>
<li>Load the data into the table.</li>
<li>Print some basic statistics about the data.</li>
</ol>
<p>So there you have it! The code is below and I hope someone actually finds this interesting! Just in case you’re wondering what else you can do with the data, check out this site called <a href="http://travian-com.ttool.info">Ttool</a>. They take the data from Travian and provide all sorts of impressive statistics about the game. Something I may do next is setup a scheduled job that runs this script, and add a date column to the data so that I can track the historical data. We’ll see if I have another free moment!</p>
<p>I almost forgot! In order to run it, you need to have Python 3.x installed. It is a very quick download and install from Python.org. After you install it, you can run it by saving the script with a .py extension, opening the command prompt, and typing this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python "C:\path\to\my\script.py"
</code></pre></div></div>
<h3 id="the-code">The Code</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/usr/bin/env python
import os # For working with the file system
import urllib.request # For getting data from web pages
import sqlite3 # for data persistence
def main():
script_url = "http://s1.travian.com/map.sql"
data_file_name = "map.sql"
database_name = "travian"
print("Downloading data file \nfrom:\t{0}\nto:\t{1}\n...".format(script_url , data_file_name))
download(script_url, data_file_name);
print("Done.\n")
print("Creating table if needed...")
create_table(database_name)
print("Done.\n")
print("Clearing old data if needed...")
clear_data(database_name)
print("Done.\n")
print("Loading data file into SQL Lite...")
load_data(database_name, data_file_name)
print("Done.\n")
print("Statistics:")
print_stats(database_name)
# Originally from http://code.activestate.com/recipes/496685-downloading-a-file-from-the-web/
# Copy the contents of a file from a given URL to a local file.
def download(url, file_name):
urllib.request.urlretrieve(url, file_name)
def create_table(database_name):
#Try and create the table.
#If it fails, it's probably because the table exists
try:
table_sql = """CREATE TABLE `x_world` (
id integer PRIMARY KEY ASC AUTOINCREMENT NOT NULL DEFAULT '0',
x integer NOT NULL default '0',
y integer NOT NULL default '0',
tid integer unsigned NOT NULL default '0',
vid integer unsigned NOT NULL default '0',
village text NOT NULL default '',
uid integer NOT NULL default '0',
player text NOT NULL default '',
aid integer unsigned NOT NULL default '0',
alliance text NOT NULL default '',
population integer unsigned NOT NULL default '0'
);"""
#Open a connection to the SQLite database and create the table
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_cursor.execute(table_sql)
sql_connection.commit()
sql_connection.close()
except:
pass
def clear_data(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
sql_command = "DELETE FROM x_world"
#Delete all the existing data, if there is any
sql_cursor.execute(sql_command)
sql_connection.commit()
sql_connection.close()
def load_data(database_name, data_file_name):
#Open the data file
data_file = open(data_file_name, mode='r', encoding="UTF8")
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Run each SQL statement from the data file
for line in data_file:
sql_cursor.execute(line)
sql_connection.commit()
sql_connection.close()
def print_stats(database_name):
sql_connection = sqlite3.connect(database_name)
sql_cursor = sql_connection.cursor()
#Population query
sql_population = """SELECT SUM(population)
FROM x_world"""
sql_cursor.execute(sql_population)
population = sql_cursor.fetchone()[0]
#User count query
sql_count_users = """SELECT COUNT(DISTINCT(uid))
FROM x_world"""
sql_cursor.execute(sql_count_users)
user_count = sql_cursor.fetchone()[0]
#Village count query
sql_count_villages = """SELECT COUNT(*)
FROM x_world"""
sql_cursor.execute(sql_count_villages)
village_count = sql_cursor.fetchone()[0]
#Print results
print("Population of Travian: {0}".format(population))
print("Number of users in Travian: {0}".format(user_count))
print("Number of villages in Travian: {0}".format(village_count))
sql_connection.commit()
sql_connection.close()
#Run the main function
main()
</code></pre></div></div>
jQuery form.serialize() doesn't post "submit" and "button" values (duh)2010-04-08T02:19:49+00:00http://johnnycode.com/2010/04/08/jquery-form-serialize-doesnt-post-submit-and-button-values-duh<p>So I was having this issue where certain values in my AJAX form were not being posted to my ASP.NET MVC back end. I figured something was just wrong with my HTML, but everything looked good. I’m no MVC expert, so I thought there might be a conflict with the way MVC was handling the form data. Maybe I was using bad characters? Nope! After some quick googling, it became obvious what the problem was. The call to jQuery’s serialize() method does not post “submit” and “button” values!!!</p>
<p>In case you haven’t figured it out (it took me a minute too), the form submission event and the form.serialize() call have nothing to do with each other! Let’s take a look at a typical usage scenario:</p>
<p>You have a site like StackOverflow, and you have a vote form like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><form method="post" id="vote_form" action="jquery serialize test.html">
Enter the question you want to vote for:
<input type="text" name="question_id" id="question_id" />
<input type="submit" name="vote_up" id="vote_up" value="up" />
<input type="submit" name="vote_down" id="vote_down" value="down" />
</form>
</code></pre></div></div>
<p>You hook it up to jQuery like this (this is just one way):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><script type="text/JavaScript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js">
</script>
<script type="text/JavaScript">
$().ready(function(){
var vote_form = $('#vote_form');
vote_form.submit(function() {
alert("Posting data...");
$.post(vote_form.attr('action'), vote_form.serialize(), function(data) {
if (data)
{
alert("It worked.");
vote_form.replaceWith("voted");
}
else
{
vote_form.replaceWith("not voted");
alert("It worked.");
}
});
return false;
});
});
</script>
</code></pre></div></div>
<p>So what is wrong with this picture? Look at it again. Now back to me. Back to the form. <em>Now back to me</em>. See how the form.serialize() is just another part of the event handler? It really has nothing to do with the event handler it is in. <em><strong>Although you would probably never do this</strong></em>, you could even wire up the AJAX like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$("#question_id").hover(function() {
// submit the form data via Ajax
});
</code></pre></div></div>
<p>So when the user moves their mouse over the textbox, the form will automatically be submitted via AJAX (kinda neat)!</p>
<p>So now that we know that the serialize call is unrelated to the actual trigger of the form submission, it should all make sense. <strong>Since the serialize() call has no way of knowing what actually submitted the form, it doesn’t submit the “trigger’s” value with the form data!</strong> Well shit. Now what!? One solution I saw somewhere on the net was this:</p>
<p>Wire up your event handler to the click events of the buttons in the form, instead of the form submit event. This will allow you to figure out which element triggered the form submission, and subsequently, you can send that element’s value along with the rest of the post data. Here is an example that will work off the same HTML as above:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><script type="text/JavaScript">
$().ready(function(){
var vote_form = $('#vote_form');
var buttons = $('#vote_form input');
buttons.click(function() {
alert("Posting data...");
var post = $(this).attr("name") + "=" + $(this).val();
var form_data = $(vote_form).serialize() + "&" + post;
$.post(vote_form.attr('action'), form_data, function(data) {
if (data)
{
alert("It worked.");
vote_form.replaceWith("voted");
}
else
{
vote_form.replaceWith("not voted");
alert("It worked.");
}
});
return false;
});
});
</script>
</code></pre></div></div>
<p>Hope this explanation helps someone out there. Here are some of the links that helped me figure this out:</p>
<ul>
<li><a href="http://groups.google.com/group/jquery-en/browse_thread/thread/8f99996a3e15ca6b?pli=1">Google Groups Discussion</a></li>
<li><a href="http://stackoverflow.com/questions/2083419/jquery-not-intercepting-a-form-submition-asp-net-mvc-fancybox">jQuery Not Intercepting A Form Submission-ASP.NET MVC Fancybox</a></li>
<li><a href="http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx">ASP.NET MVC Multiple Button in the Same Form</a></li>
</ul>
ASP.NET C# DataBinding requires properties, not fields.2010-03-13T08:00:31+00:00http://johnnycode.com/2010/03/13/asp-net-c-databinding-requires-properties-not-fields<p>As the title of his post states, you can’t reference fields when using ASP.NET’s data binding syntax. If you try it, you will get a runtime exception that looks something like this:</p>
<blockquote>
<p>DataBinding: <strong>‘MyDataClass</strong>’ does not contain a property with the name ‘<strong>MyProperty</strong>’.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.</p>
</blockquote>
<p>Exception Details: System.Web.HttpException: DataBinding: ‘<strong>MyDataClass</strong>’ does not contain a property with the name ‘<strong>MyProperty</strong>’.</p>
<p>I’ve seen his before, but I had forgotten about it, and I didn’t realize that the data objects I was working with were using fields instead of properties. To be more specific, the data objects were structs, but I don’t think that mattered here. Well I did a little investigation into this “issue” and it turns out that some people feel this shouldn’t throw an exception. I found <a href="http://www.nikhilk.net/DataBindingToPublicFields.aspx">an old post by Nikhil Kothari</a> on the subject and it looks like his only issue was that C# didn’t support auto properties! He must be a prophet :)</p>
Batch Delete with the Entity Framework2010-03-12T18:30:37+00:00http://johnnycode.com/2010/03/12/batch-delete-with-the-entity-framework<p>There is a minor problem with the Entity Framework in that it doesn’t support certain batch operations. You can, of course, retrieve multiple rows at a time, and updates to tracked objects on a given data context can all be pushed back to the data store in a single SaveChanges() call. But what about adding and deleting?</p>
<p><strong><em>**UPDATED**</em></strong></p>
<p><strong>Below is Solution/Project that I threw together to show how a batch delete works with EF. It doesn’t actually use the extension method, but the code is the same. As you can see, you’re are NOT modifying the collection, so it works fine. The example uses .NET 4 and SQL Compact 4.</strong></p>
<p><strong><a href="http://www.johnnycode.com/blog/wp-content/uploads/2010/03/EntityFrameworkTest.zip">EntityFrameworkTest</a></strong></p>
<p>Normally you would delete items like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>foreach(var entity in entities)
{
context.DeleteObject(entity);
}
</code></pre></div></div>
<p>So everywhere you have to batch delete a set of objects, you need a foreach loop. Instead of that, a nice workaround for this problem is to use a partial class method. Here is one for deleting a set of objects:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public partial class TargetEntities
{
public void DeleteObjects(IEnumerable entities)
{
foreach (var entity in entities)
{
this.DeleteObject(entity);
}
}
}
</code></pre></div></div>
<p>In this case, the method needs to be generic so that it supports the generic version of IEnumerable. If you try to make the method take “IEnumerable<object>” it wont work because of the way covariance is in this version of .NET (I heard 4.0 might solve part of this problem).</p>
<p>So now if you’re deleting a few sets of objects, your code <strong>WONT</strong> look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>foreach (var entity1 in entities1)
{
context.DeleteObject(entity1);
}
foreach (var entity2 in entities2)
{
context.DeleteObject(entity2);
}
foreach (var entity3 in entities3)
{
context.DeleteObject(entity3);
}
</code></pre></div></div>
<p>And will instead look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>context.DeleteObjects(entities1);
context.DeleteObjects(entities2);
context.DeleteObjects(entities3);
</code></pre></div></div>
<p>Or you can directly delete data with a more direct approach like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>context.DeleteObjects(context.Products.Where(p => p.CategoryID == "Cell Phones"));
</code></pre></div></div>
<p>Or even delete all the data in a table:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>context.DeleteObjects(context.Products);
</code></pre></div></div>
Using a template to programmatically create PDFs with C# and iTextSharp2010-03-05T00:21:34+00:00http://johnnycode.com/2010/03/05/using-a-template-to-programmatically-create-pdfs-with-c-and-itextsharp<p>Recently we upgraded a client’s e-commerce solution from a home grown Ruby app to a .NET e-commerce application. Part of the whole upgrade was that I needed to replicate a product personalization process that they had. Basically, a customer enters information during checkout and a custom PDF document is generated for them including the information they had previously entered. This is a fairly popular feature and you see it on websites that make stationary or party favors and decorations.</p>
<p>There are a lot of commercial products out there for creating PDF’s, but free is better! In order to recreate this functionality (for free), I needed to figure out how to create some sort of PDF template. With a template in place I would need to programmatically do replacements to generate custom documents. The rest of the project would be cake.</p>
<p>In order to create the template, I simply followed this tutorial: <a href="http://danilop.wordpress.com/2008/07/02/how-to-create-pdf-forms-with-openoffice/">How-to: Create PDF forms with OpenOffice</a>. It is as simple as creating a new document in Open Office, dropping in some text field controls, and exporting it to PDF. Part 1 done. You could probably use another document editor program like Microsoft Word, but this happened to work fine and it’s Free and Open Source (FOSS).</p>
<p>For part 2, I used iTextSharp to programmatically load the template PDF, perform the replacements, and save out that new PDF. It was surprisingly easy, and I’ve created some sample code below, based on a <a href="http://itextpdf.com/examples/index.php?page=example&id=122">Java example I found</a> (iTextSharp is a port of the Java project iText). One additional thing I’ve done at the end is to “flatten” the form, which makes it so that the fields wont be editable on the new PDF. You can flatten the entire form, or specify fields to flatten so the rest of the form will be usable. For example, you could flatten a person’s name and address, and then let them fill out the rest of the form.</p>
<p>Check out the code below:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System.IO;
using iTextSharp.text.pdf;
namespace PDFTest
{
public class PdfTest
{
public static void ReplacePdfForm()
{
string fileNameExisting = @"C:\path\to\existing.pdf";
string fileNameNew = @"C:\path\to\new.pdf";
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
form.SetField(fieldKey, "REPLACED!");
}
// "Flatten" the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
// You can also specify fields to be flattened, which
// leaves the rest of the form still be editable/usable
stamper.PartialFormFlattening("field1");
stamper.Close();
pdfReader.Close();
}
}
}
}
</code></pre></div></div>
<p>You can find more information about the iTextSharp project on the <a href="http://itextsharp.sourceforge.net/">iTextSharp Homepage on SourceForge</a>. Just keep in mind that you may stumble upon Java Examples, but fret not! Java is very similar to C# so you can easily port the samples as I did. Just use intellisense to help you find subtle differences in the syntax.</p>
Is your API stuck in the 90's?2010-03-01T18:04:09+00:00http://johnnycode.com/2010/03/01/is-your-api-stuck-in-the-90s<p>If your company develops a product that is utilized by other developers listen up! Does your API empower developers, or does it get in their way? Is it well documented, and can it be easily consumed? Better yet, how does the rest of your code stack up? Would you be ashamed if other people looked at it? As a developer, these are questions you should be asking yourself, especially if other people are “using” your code or working with it. You owe it to your fellow developers to do things the right way, especially if they paid money for your product!</p>
<h3 id="the-culprit">The culprit</h3>
<p>Let me give you a great example of an API that could use a little work. I’ve recently worked on two projects using <strong>ASPDotNetStorefront **and frankly, **their code is atrocious</strong>. But for the purpose of this article, I’ll focus on their “API”, called <a href="http://manual.aspdotnetstorefront.com/wsi/">“Web Service Automation Interface” (WSI)</a>. Before I get into how WSI works, let me present you with this lovely paragraph I found on the <a href="http://manual.aspdotnetstorefront.com/wsi/Intro_InstallingWSI.htm">Installation page</a> from their documentation, which I found while initially researching WSI:</p>
<blockquote>
<p><em>NOTE: WHILE FULLY FUNCTIONAL, THIS FEATURE IS STILL CONSIDERED BETA DUE TO THE SCOPE OF THE IMPLEMENTATION</em>. IF YOU RECEIVE ANY ERRORS, PLEASE SUBMIT THEM VIA OUR ONLINE HELPDESK AT https://support.aspdotnetstorefront.com. A sample of the XML document you are passing to the interface is always helpful. Please submit it as an attachment as our support system will strip out any inline HTML or XML for security reasons.</p>
</blockquote>
<p>I think I did a double take when I read that. It really instills confidence doesn’t it? Well maybe they’re a new company and haven’t had time to refine their API…</p>
<blockquote>
<p>Our e-commerce platform has been in production since 1997, so it’s field tested on a wide range of stores, and a wide range of store types.</p>
</blockquote>
<p>So they’ve been in business for 13+ years, and they still haven’t brought their API to a release status? I guess they’re still stuck in 1997, or at least their API certainly is. Other than that one short paragraph in italics, not <strong>bold bright red letters</strong>, I couldn’t find any evidence that this is a beta feature of their product. That is a pretty important tidbit of information isn’t it? Let’s pretend we didn’t know about that for a few minutes…</p>
<p>Looking through the rest of their documentation you’ll find it’s riddled with incomplete sections and placeholders for future content. For example, the whole shopping cart section is “<em>TBD (Not Implemented Yet)</em>”. Their sample code is mediocre as well. I spotted a few missing “using” statements, useless variables, and extra code. When I say extra code, I mean key down event handlers for a textbox control looking for “ctrl + a”. Isn’t that whole “select all” thing built in? I can understand if your internal code isn’t beautiful, but an exmaple for your customers is meant to be just that! <strong>An example!</strong> A short demonstration which your customers can follow! I’m not saying it has to be perfect. You don’t have to fill out all the “catch” statements or anything like that; developers should know to deal with that themselves; but I feel the code should be solid and straightforward.</p>
<p>One last gripe before we move on; their API is supported in version 7.0.2.1 and higher, but there is only a single set of documentation for all the versions! There are few things that make me more furious than when I discover a feature is not supported by my version <strong>after trying to use it.</strong> How much would you be willing to bet that the feature set for each version is not well documented? They should have separate sets for each version they release and ensure that they match what is currently implemented.</p>
<h3 id="using-the-api">Using the API</h3>
<p>Now on to the good stuff! Here is a quick rundown of how their API works. It accepts XML data to perform various operations against their data structure using a .NET .asmx web service. Sounds pretty standard right? Well, let’s take a look at the .NET web service…</p>
<p><img src="/assets/images/2010-03-01-is-your-api-stuck-in-the-90s/AspDotNetStorefront-WSI-ASMX.png" alt="" title="The AspDotNetStorefront WSI .asmx page" /></p>
<p>Forget the stupid method names, where are all the other methods? Unfortunately, this is all the web service provides. In order to actually perform calls against the underlying API, you pass in XML. <strong>Yep, you have to hand craft all your XML calls</strong>. While <a href="http://msdn.microsoft.com/en-us/library/bb387061.aspx">LINQ to XML</a> makes this a heck of a lot easier, <strong>we shouldn’t have to do this!!!</strong> Why make more work for everyone, yourself included? Isn’t that part of the greatness that is .NET web services? The ability to have the framework generate proxy classes for you? Even if you chose to use another format, at least use a protocol that is standardized so you can take the human element out of the mapping equation!</p>
<p>I’m just a regular developer, but I love being able to program against an application. Actually, I’ve used many an API in my day including ones from <a href="http://www.rightnow.com/">RightNow</a>, <a href="http://www.salesforce.com/">SalesForce</a>, and <a href="https://www.paypal.com/">PayPal</a>, among others. Sure, AspDotNetStorefront is a smaller company, but that doesn’t make their API any less important to the customers who purchase their product. If they improve their API it might even help them grow! A good API is critical for application vendors and is an awesome selling point. I’m not an expert on the subject, but I definitely know a bad API when I see one, and <strong>the AspDotNetStorefront WSI API is a bad API</strong>.</p>
<h3 id="update">UPDATE</h3>
<p>I just so happened to find this interesting article about <a href="http://aspnet.4guysfromrolla.com/articles/022410-1.aspx">Comparing the Performance of Visual Studio’s Web Reference to a Custom Class</a>. I don’t think the results are completely scientific, but it definitely sheds some light on whether you really want to make your own web service calling code. The short answer is no. You want to use the .NET “Add Web Reference” proxy classes because it saves you a significant amount of time and work, probably cuts down bugs in the long run, and the performance out of the box is very good.</p>
5 Visual Studio Productivity Tips Every Developer Should Know2009-12-07T10:30:53+00:00http://johnnycode.com/2009/12/07/5-visual-studio-productivity-tips-every-developer-should-know<p>Looking to be a little more productive in Visual Studio!? Take a gander at these great tips I’ve compiled over my years of working in Visual Studio. I might have some more specialized tips coming up, but these ones should apply to anyone using Visual Studio and I’m guessing more than a few people don’t know these.</p>
<h3 id="auto-formatting-code">Auto formatting code</h3>
<p>Hate how when you copy/paste code the indentation is all wrong? Or how about when you hand write some code or markup, but little things are out of sync, even with intellisense? Like the spacing between statements, the position of curly braces, etc. Just use these shortcuts! They automagically reformat code and markup to be consistent. It even works on markup pages. The only times it doesn’t work is if there are some errors in the code/markup. You can also access these shotrcuts directly from the Edit menu.</p>
<blockquote>
<p>Format Document: ctrl + k, ctrl + d</p>
</blockquote>
<blockquote>
<p>Format Selection: ctrl + k , ctrl + f</p>
</blockquote>
<h3 id="context-menu">Context menu</h3>
<p>Sometimes you know the name of a class, but don’t have the appropriate <em>using</em> statement added to the page. Take <em>StringBuilder</em> for example. Just type the class name, correctly cases, and then use this shortcut! It will bring up the context menu that is usually hard to see (it’s a thin red outline until you mouse over it). Then you can select the using statement you want (usually the first) and hit enter! That’s it! No more scrolling to the top of the page to add using statements! This also works in other situations where the context menu would normally be used, like when you rename a variable.</p>
<blockquote>
<p>Bring up the context menu: ctrl + .</p>
</blockquote>
<h3 id="quick-keyboard-commenting">Quick keyboard commenting</h3>
<p>Hate adding comments to each line individually, or moving your cursor around to add a block comment? Just use these shortcuts! The first one comments out any lines selected. You don’t even have to select the whole line! Just select a portion and the comment will be added to the beginning of the line! Alternatively, use the second shortcut to remove any comments.</p>
<blockquote>
<p>ctrl + k, ctrl + c</p>
</blockquote>
<blockquote>
<p>ctrl + k, ctrl + u</p>
</blockquote>
<h3 id="cycle-through-your-past-clipboard-items">Cycle through your past clipboard items</h3>
<p>Ever cut/copy something, only to accidentally cut/copy over the clipboard? Say no more! Just hold down shift while using the standard paste shortcut to cycle through all of the items that you have cut or copied in Visual Studio. Only works inside Visual Studio though.</p>
<blockquote>
<p>Cycle through the clipboard buffer: ctrl + shift + v</p>
</blockquote>
<h3 id="collapse-your-code-to-get-a-birds-eye-view">Collapse your code to get a birds eye view</h3>
<p>Ever need to quickly take stock of how your code is layed out? Just use the first shortcut, to collapse all the code into method stubs and code regions! Then you can easily reorganize your methods and properties. When you’re done, feel free to use the second shortcut to expand everything again.</p>
<blockquote>
<p>Collapse all code regions: ctrl + m, ctrl + o</p>
</blockquote>
<blockquote>
<p>Expand all code regions: ctrl + m, ctrl + p</p>
</blockquote>
Can't use the same parameter list when creating Extension Methods2009-11-11T17:17:10+00:00http://johnnycode.com/2009/11/11/cant-use-the-same-parameter-list-when-creating-extension-methods<p>Everyone knows that you can’t create an extension method that uses the same name and parameter list as an existing method of the type your extending. So for example, this method would be perfectly valid:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string IsNullOrEmpty(this string text)
{
return string.IsNullOrEmpty(text);
}
</code></pre></div></div>
<p>Why? Well, for one, the method parameters are different. The existing IsNullOrEmpty method takes a string as an argument, and my extension method does not. Also, the existing IsNullOrEmpty method is static…</p>
<p>WAIT! That doesn’t matter! Check this out:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string Format(this string me, params object[] args)
{
return string.Format(me, args);
}
</code></pre></div></div>
<p><strong>This doesn’t work!</strong> That’s right! If there is an existing <strong>static</strong> method with the same name and parameter list, you will get a compile time error! When you attempt to use the extension method like so:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"My name is {0}".Format(person.Name);
</code></pre></div></div>
<p>This is the error that ensues:</p>
<blockquote>
<p>Member ‘string.Format(string, object)’ cannot be accessed with an instance reference; qualify it with a type name instead</p>
</blockquote>
<p>Yep. This may seem obvious to some, but not me! Why would it matter that there is a static version of the method, when clearly we’re not using it! I’m guessing it has something to do with the way the compiler looks up methods.</p>
<p>So how do you get around this? Rename your extension method.</p>
<p>One thing I’m also not sure about now, is whether or not you can have 2 methods with the same signature, but have one be static and another be instance-level. Anyone know the answer to that one?</p>
<h4 id="update"><strong>UPDATE</strong></h4>
<p>Jared, my coworker pointed out something. It looks like having an extension method with the same parameter list is valid. However, for some reason, you can’t <em>use</em> the extension method under certain situations? For example, when creating a String Format() extension method, you can’t actually pass in a string a parameter.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int aNumber = 0;
string aString = string.Empty;
var s1 = "{0}".F(aNumber); // Good, different method name
var s2 = "{0}".F(aString); // Good, different method name
var s3 = "{0}".Format(aNumber); // Good, passing a number as the parameter
var s4 = "{0}".Format(aNumber.ToString()); // compile time error
var s5 = "{0}".Format(aString); // compile time error
</code></pre></div></div>
<p>Does anyone know why this matters? The method signature for string.Format() is this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string Format(this string me, params object[] args)
</code></pre></div></div>
<p>So it shouldn’t really matter what you pass in as “args”. Each argument should be boxed as an object, right?</p>
Simple C# Extension Method to truncate a string, preserving the last word.2009-11-11T16:21:48+00:00http://johnnycode.com/2009/11/11/simple-c-extension-method-to-truncate-a-string-preserving-the-last-word<p>We needed to truncate a summary down to n number of characters to provide a uniform look and feel. So I whipped up this extension method to take the current string and truncate to n characters, attach an ellipsis to the end, and optionally keep the last word of the string preserved. In other words, don’t chop the last word in half.</p>
<p>However, this is a <strong>very</strong> simple implementation. There are a lot of things that we don’t consider here. For example, we don’t consider the type of text. If the text is HTML, we may leave it in a non-compliant state. Or, if the initial truncated text ends in a period, we don’t leave it as is. So there is a lot of room for improvement here.</p>
<p>Lastly, one thing <strong>I’m</strong> not doing is highlighting my code… the below sample code probably looks like crap inside this page. I do have a syntax highlighter installed, but I don’t remember how to use it right now. So I’ll fix that later if I remember.</p>
<p>Here is the code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static string Truncate(this string text, int length, string ellipsis, bool keepFullWordAtEnd)
{
if (text.IsNullOrEmpty()) return string.Empty;
if (text.Length < length) return text;
text = text.Substring(0, length);
if (keepFullWordAtEnd)
{
text = text.Substring(0, text.LastIndexOf(' '));
}
return text + ellipsis;
}
</code></pre></div></div>
Defy All Challenges?2009-11-02T01:47:29+00:00http://johnnycode.com/2009/11/02/defy-all-challenges<p>Microsoft’s Marketing is a bit strange at times, as seen in this video:</p>
<p>But overall, I think they usually have the right message, however obscured it may be.</p>
<p>Personally, I love their slogan for Visual Studio:</p>
<blockquote>
<p>Defy All Challenges</p>
</blockquote>
<p>And really, that is what being a programmer is all about! We face challenges of all magnitudes every single day. If you didn’t like challenges, you probably wouldn’t have chosen your current profession, or at least you wouldn’t like it!</p>
<p>As much as we may wish for easy days, challenges are what make our jobs interesting.</p>
Kudos to WordPress!2009-11-02T01:02:46+00:00http://johnnycode.com/2009/11/02/kudos-to-wordpress<p>Back in May I installed <a href="http://wordpress.org/">WordPress</a> on my shared PHP hosting. I remember it being a fairly simple setup, and I configured it and started posting without issues. Eventually, a notice started popping up that I needed to upgrade. I assumed it meant I needed to:</p>
<ol>
<li>Download the package</li>
<li>Unzip the package</li>
<li>Upload/replace files</li>
<li>Run a script</li>
</ol>
<p>What the upgrade process really entailed was to:</p>
<ol>
<li><strong>Click a button!</strong></li>
</ol>
<p>Yes really, it was that easy! I’m guessing that some people might run into issues if their hosting permissions aren’t setup correctly, but my experience was perfect! Never in a million years did I think using a web-based app would be so easy, at least from the admin side. I’ve dealt with many a web application, and frankly, have yet to see a good upgrade process until now. It didn’t matter if a product was hosted or not, big or small, people don’t always build their applications with upgrades in mind. Take Adobe Acrobat, now known as Adobe Reader, which isn’t even a web app. I’m guessing they changed the name because people hated Acrobat so much! I for one hated Acrobat because anytime I tried to install their “automatic” updates, it failed. Maybe I’m just a skeptical programmer, but I was thinking that upgrading WordPress would be an arduous process. Boy was I wrong!</p>
<p>So next, I started thinking if the upgrade was that easy, what about the plugins? One of my coworkers who also uses WordPress mentioned that the plugin system was good, and that there were some very useful plugins. So I went to the plugins tab and was able to install a few plugins without issue. Here is what I’m currently using (in no particular order):</p>
<ul>
<li>Google XML Sitemaps</li>
<li>Ultimate Google Analytics</li>
<li>GZIP Output</li>
<li>Blog in Blog</li>
<li>SI Captcha Anti-Spam</li>
<li>WP CSS</li>
</ul>
<p>I think they are all pretty self-explanatory, with the exception of the Blog In Blog. That plugin allows me to designate a content page as a mini-blog for posts from a specific category! I was a little disappointed that WordPress didn’t have something like that built-in, but this plugin seems to do the trick! Also, the category that is displayed on the content page is removed the homepage, which is perfect for me! Just in case you want to know, I’m setting up a mini-blog on said <a href="http://www.bubriski.com/blog/the-baby-blog/">content page that will be dedicated to our baby</a>! There probably isn’t anything there if you’re reading this, but feel free to make a mental note and check back later. The link for it is on the top of the sidebar ;)</p>
<p>Now back to the plugins. Again, their purpose is self-explanatory, but I really want to reiterate their simplicity and usefulness. WordPress by itself is a decent blog engine, but with all of those plugins it’s practically a CMS. I’m sure there are some more robust plugins out there, I just haven’t had the time to look! But using only the plugins I mentioned above, my site:</p>
<ul>
<li>Is ultra-fast (check FireBug, Y-Slow or Chrome if you don’t believe me)</li>
<li>Is indexed by all the major search engines</li>
<li>Supports “multiple” blogs</li>
<li>Is tracked by a top-notch analytics package.</li>
<li>Is protected by a captcha.</li>
</ul>
<p>That last point is an especially important one for me. I get emails everyday about people posting comments or registering for my blog. Every time I see those emails, I get excited that somewhere in the world, someone is trying to communicate with me about one of my personal passions, programming. Unfortunately many of these emails are from blog spam, and like 99.99% of the people on Earth, I hate Spam. So hopefully starting today I will no longer get my hopes up when I see an email from my Blog :)</p>
<p>So that is all for now! Hopefully this inspired someone to go and try out WordPress, especially if they already have some PHP hosting. If you want to know more about the blog platform, visit the <a href="http://wordpress.org/">WordPress site</a>, do some googling, or post a comment here! If I end up finding some time to checkout more plugins or customize WordPress more, I’ll let you know!</p>
Just got back from Code Camp 12 in Waltham, MA!2009-10-17T21:51:47+00:00http://johnnycode.com/2009/10/17/just-got-back-from-code-camp-12-in-waltham-ma<p>It was great! This was my first code camp, and I LOVED IT! It was at the Microsoft office in Waltham, MA, just outside the Boston area.</p>
<p>A big thanks to all who presented, and to those who organized!</p>
<p>Here are the sessions I attended:</p>
<ol>
<li>John Bowen: Visual Studio 2010 features</li>
<li>Joseph Hill: Mono and .NET developers</li>
<li><strong>Phil Denoncourt</strong>: Localization and Globalization</li>
<li><strong>Julia Lerman</strong>: Entity Framework POCO</li>
<li>Michael Cummings: ASP.NET MVC Better Practices</li>
<li>Milan Negovan: The Microsoft AJAX JavaScript library</li>
<li>Joseph Anderson: E-Commerce with .NET</li>
</ol>
<p>All the presentations were great, but I bolded the two speakers whose presentations were particularly enlightening for me.</p>
<p>Julie’s presentation was great because I personally and professionally use the Entity Framework, and find it to be a good fit for most of my needs. I usually use it for rapid application development and I find it useful because it’s free, it’s integrated into Visual Studio and it’s fairly simple.</p>
<p>People say the current version of the Entity Framework does have shortcomings, but I personally haven’t run into any of the problem scenarios. However, the new version, Entity Framework 4, is going to be released with .NET 4 and is supposed to add a lot of features that people have been asking for! One of those features is the ability to use POCO’s with the Entity Framework.</p>
<p>Currently, the classes that are generated by the Entity Framework’s designer are coupled with the API. This has a number of implications, one of which is limited testability. This is where POCO comes in. POCO stands for Plain Old CLR Object. Basically, a POCO is an object that does not have external dependencies. So when you are able to use POCO’s with the Entity Framework, you will be decoupling your classes. There are also some other great features in Entity Framework 4, so go check it out!</p>
<p>Phil’s presentation on Localization was great because I am about to completely localize a web application for a friend. To be honest, I didn’t know a whole lot about how localization works in .NET. As I’ve worked with many CMS’ before, I vaguely knew about resource files and about the Thread.CurrentThread.CurrentUICulture property. However, I didn’t know about all the built-in localization features that the .NET framework has. Think about it! With localization in .NET you have to worry about localized content in Master pages, pages, user controls, databases, JavaScript, and more! There are also some gotchas that are good to know before even starting the localization process. Maybe I will talk to Phil and see if I can re-post or re-link the slides he used for his presentation!</p>
<p>I’ll try update this post later with more detail about the sessions if I have more time. Maybe I can link some of the content too.</p>
Who needs time lines and deadlines? Just get coding!2009-07-23T13:18:33+00:00http://johnnycode.com/2009/07/23/who-needs-time-lines-and-deadlines-just-get-coding<p>Kirk Knoernschild has an interesting article on <a href="http://techdistrict.kirkk.com/2009/07/21/the-project-date-revisited/">his blog</a> about not having a set target date.</p>
<p>Wouldn’t that be grand? Screw the requirements! Screw the time line! Just get to work and start coding. It’s definitely a thought provoking piece, as that’s why I’m writing about it right now!</p>
<p>It has some great ideas. The customer gets what they want, when they want it (more or less). Also, the project team isn’t bothered with time lines and deadlines so most of the pressure is off. Sounds great!</p>
<p>But then reality kicks in. Let’s do a little QA:</p>
<p>Why do we need requirements? To put it plainly, requirements are what is required of the system. The features, as well as the limitations. As soon as you remove the requirements, its like trying to hold a bottle of shampoo in your hand… <em>without the bottle</em>. The Developers would lose site of their goal, and the customer would keep trying to move the goal!</p>
<p>A better approach than “<em>screw the requirements</em>” would be to constantly get feedback from the customer, and consider what they <em>want _and what they _need</em>. In a perfect world, a customer knows what he wants, and the developer knows exactly how to implement it. Unfortunately that isn’t always the case!</p>
<p>More on this later if I have time!</p>
First code snippet: How to uninstall and reinstall ASP.NET2009-05-27T14:21:34+00:00http://johnnycode.com/2009/05/27/first-code-snippet-how-to-uninstall-and-reinstall-aspnet<p>So I decided to try and use this as a storage mechanism for my snippets of code. Here is the first one! How to uninstall and reinstall ASP.NET! You might need to do this if you start having issues with ASP.NET.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\>cd windows\Microsoft.NET\Framework\v2.0.50727
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -u
Start uninstalling ASP.NET (2.0.50727).
..................................
Finished uninstalling ASP.NET (2.0.50727).
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -i
Start installing ASP.NET (2.0.50727).
.......
Finished installing ASP.NET (2.0.50727).
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>
</code></pre></div></div>
Alternative to letting the exceptions fly?2009-05-11T21:36:39+00:00http://johnnycode.com/2009/05/11/alternative-to-letting-the-exceptions-fly<p>So I was creating a class to do handle the CRUD operations for a type when I was trying to figure out how to return the results. I could…</p>
<ol>
<li>Return a bool, and just assume that the problem was with the database. But then I don’t have the actual cause, and any detailed information.</li>
<li>Return a bool, and use out parameters to store the error. Then check the out parameters in the case that the return value is false. But that requires me to create a variable to pass in as the out parameter.</li>
<li>Let the exceptions be thrown, and use a try catch in the calling code.</li>
<li>Do something completely different! How about create a new generic type to use as the return value? All I need is a bool for the outcome of the operation, a string for error codes, and whatever else we want!</li>
</ol>
<p>I like option 4 :)</p>
<p>While this doesn’t seem like a big deal for my code, since I know what my other code is doing, I feel like this has potential. What about using this code in an actual API fashion? That way, the user of the API doesn’t need to know what type of exceptions are going to be thrown. The only direct advantage I see is that the exceptions are defined types. But I really haven’t thought about it that much…</p>
<p>I will try and post some code if I ever getting around to actually implementing this.</p>
Visual Studio New File Templates2009-05-11T09:41:28+00:00http://johnnycode.com/2009/05/11/visual-studio-new-file-templates<p>Per <a href="http://forums.asp.net/p/1247808/2358210.aspx#2358210">jberkhei’s reply on this forum post</a>, here are the locations of the Visual Studio new file templates:</p>
<p>Visual Studio 9</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplatesCache\CSharp\Web\1033
</code></pre></div></div>
<p>Visual Studio 8</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplatesCache\Web\CSharp\1033
</code></pre></div></div>
<p>Editing these can easily allow you to setup little things that will save you time.</p>
<ol>
<li>Always change autoeventwireup to false? (FYI, you can also change this in the machine.config, or the web.config)</li>
<li>Always remove the default method, and replace it with an overload of the OnLoad?</li>
<li>Always need to add using directives for certain namespaces?</li>
</ol>
<p>Then change the template!</p>
The beginning of the end!2009-05-10T23:04:44+00:00http://johnnycode.com/2009/05/10/hello-world-2<p>So here is my first post.</p>
<p>The why? Because I often have many thoughts about programming, but I don’t feel that my old blog (which is still active) is cutting it. For starters, I didn’t really post on it. Other than that, it was homegrown and to basic to really be useful to anyone, even myself!</p>
<p>The how? WordPress! The why of WordPress? Not really sure. I’ve seen WordPress around, I enjoy the default color scheme and layout, and its the firs tthing that popped into my head for a blog solution.</p>
<p>The future? Hopefully a bright one! I don’t think I”ll post regularly on this, but hopefully I can crank out some useful information that is in a nice publicly available format, in the hopes that I can influence others. For better or for worse ;)</p>