latest posts

Continuing my work on my Cobalt Qube 2, I had some time tonight to re-install NetBSD on a Corsair NOVA 30GB SSD.

A fairly trivial hardware installation with a PATA<->SATA adapter:
Gateway Qube 2 - PATA<->SATA Adapter

Gateway Qube 2 - Corsair NOVA SSD

After installation I ran jcDBench after running it with the "stock" Seagate Barracuda ATA IV PATA drive expecting a huge boost in performance, I was disappointed to see these results: [bash] $ ./jcDBench Running with no arguments... #----------------------------------------------- # jcDBench mips/NetBSD ( # (C)2013 Jarred Capellman # # Test Date : 3-13-2014 18:48:14 # Starting Size : 4096 # Maximum Size : 4194304 # Iterations : 100 # Filename : testfile #----------------------------------------------- # test size write read # (bytes) (MB/s) (MB/s) #----------------------------------------------- 4096 1.83MB/s 6.17MB/s 8192 3.01MB/s 10.3MB/s 16384 6.77MB/s 13.2MB/s 32768 8.5MB/s 11.4MB/s 65536 3.55MB/s 10.9MB/s 131072 3.83MB/s 11.6MB/s 262144 3.78MB/s 12.1MB/s 524288 3.87MB/s 12.4MB/s 1048576 3.9MB/s 7.47MB/s 2097152 3.91MB/s 7.56MB/s 4194304 3.93MB/s 7.58MB/s Benchmark Results Uploaded [/bash] The "stock" drive performed reads very similarly and the writes it performed considerably better than the theoretically much faster SSD. Not convinced something else was wrong, I went through the dmesg. Low and behold:
[bash] wd0 at atabus0 drive 0: wd0: drive supports 16-sector PIO transfers, LBA48 addressing wd0: 28626 MB, 58161 cyl, 16 head, 63 sec, 512 bytes/sect x 58626288 sectors wd0: 32-bit data port wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133) wd0(viaide0:0:0): using PIO mode 4, Ultra-DMA mode 2 (Ultra/33) (using DMA) Kernelized RAIDframe activated boot device: wd0 root on wd0a dumps on wd0b root file system type: ffs viaide0:0:0: lost interrupt type: ata tc_bcount: 16384 tc_skip: 0 viaide0:0:0: bus-master DMA error: missing interrupt, status=0x20 wd0: transfer error, downgrading to Ultra-DMA mode 1 wd0(viaide0:0:0): using PIO mode 4, Ultra-DMA mode 1 (using DMA) wd0a: DMA error reading fsbn 28640352 of 28640352-28640383 (wd0 bn 34144032; cn 33873 tn 0 sn 48), retrying wd0: soft error (corrected) viaide0:0:0: lost interrupt type: ata tc_bcount: 16384 tc_skip: 0 viaide0:0:0: bus-master DMA error: missing interrupt, status=0x20 wd0: transfer error, downgrading to PIO mode 4 wd0(viaide0:0:0): using PIO mode 4 wd0a: DMA error reading fsbn 31656736 of 31656736-31656767 (wd0 bn 37160416; cn 36865 tn 7 sn 55), retrying wd0: soft error (corrected) [/bash] For whatever reason the drive got downgraded to PIO mode 4 - or 16.6mb/sec down from the 33mb/sec Ultra-DMA mode 1 offers. Doing some reasch on the issue, two suggestions came up: 1) the drive was failing (which is possible, but unlikely considering I just purchased it) and 2) the controller or adapter is faulty. Having never used this adapter in another system I am leaning towards later - I will have to pull out the adapter I am using for my DEC Personal Workstation 433a which I know works perfectly.

More to come on this issue...
In today's post I will be diving into adding Search Functionality, Custom Error Pages and MVC Optimizations. Links to previous parts: Part 1, Part 2, Part 3, Part 4, Part 5, Part 6 and Part 7.

Search Functionality

A few common approaches to adding search functionality to a Web Application:

Web App Search Approaches

  1. Pull down all of the data and then search on it using a for loop or LINQ - An approach I loathe because to me this is a waste of resources, especially if the content base you're pulling from is of a considerable amount. Just ask yourself, if you were at a library and you knew the topic you were looking for, would you pull out all of the books in the entire library and then filter down or simply find the topic's section and get the handful of books?
  2. Implement a Stored Procedure with a query argument and return the results - An approach I have used over the years, it is easy to implement and for me it leaves the querying where it should be - in the database.
  3. Creating a Search Class with a dynamic interface and customizable properties to search and a Stored Procedure backend like in Approach 2 - An approach I will be going down at a later date for site wide search of a very large/complex WebForms app.
For the scope of this project I am going with Option #2 since the scope of the content I am searching for only spans the Posts objects. At a later date in Phase 2 I will probably expand this to fit Option #3. However since I will want to be able to search on various objects and return them all in a meaningful way, fast and efficiently. So let's dive into Option #2. Because the usage of virtually the same block of SQL is being utilized in many Stored Procedures at this point, I created a SQL View: [sql] CREATE VIEW dbo.ActivePosts AS SELECT dbo.Posts.ID, dbo.Posts.Created, dbo.Posts.Title, dbo.Posts.Body, dbo.Users.Username, dbo.Posts.URLSafename, dbo.getTagsByPostFUNC(dbo.Posts.ID) AS 'TagList', dbo.getSafeTagsByPostFUNC(dbo.Posts.ID) AS 'SafeTagList', (SELECT COUNT(*) FROM dbo.PostComments WHERE dbo.PostComments.PostID = dbo.Posts.ID AND dbo.PostComments.Active = 1) AS 'NumComments' FROM dbo.Posts INNER JOIN dbo.Users ON dbo.Users.ID = dbo.Posts.PostedByUserID WHERE dbo.Posts.Active = 1 [/sql] And then create a new Stored Procedures with the ability to search content and reference the new SQL View: [sql] CREATE PROCEDURE [dbo].[getSearchPostListingSP] (@searchQueryString VARCHAR(MAX)) AS SELECT dbo.ActivePosts.* FROM dbo.ActivePosts WHERE (dbo.ActivePosts.Title LIKE '%' + @searchQueryString + '%' OR dbo.ActivePosts.Body LIKE '%' + @searchQueryString + '%') ORDER BY dbo.ActivePosts.Created DESC [/sql] You may be asking why not simply add the ActivePosts SQL View to your Entity Model and do something like this in your C# code:
public List<ActivePosts> GetSearchPostResults(string searchQueryString) {
     using (var eFactory = new bbxp_jarredcapellmanEntities()) {
     return eFactory.ActivePosts.Where(a => a.Title.Contains(searchQueryString) || a.Body.Contains(searchQueryString)).ToList(); }
That's perfectly valid and I am not against doing it that, but I feel like code like that should be done at the Database level, thus the Stored Procedure. Granted Stored Procedures do add a level of maintenance over doing it via code. For one, anytime you update/add/remove columns you have to update the Complex Type in your Entity Model inside of Visual Studio and then update your C# code that makes reference to that Stored Procedure. For me it is worth it, but to each their own. I have not made performance comparisons on this particular scenario, however last summer I did do some aggregate performance comparisons between LINQ, PLINQ and Stored Procedures in my in C#">LINQ vs PLINQ vs Stored Procedure Row Count Performance in C#. You can't do a 1 to 1 comparison between varchar column searching and aggregate function performance, but my point, or better put, my lesson I want to convey is to definitely keep an open mind and explore all possible routes. You never want to find yourself in a situation of stagnation in your software development career simply doing something because you know it works. Things change almost daily it seems - near impossible as a polyglot programmer to keep up with every change, but when a new project comes around at work do your homework even if it means sacrificing your nights and weekends. The benefits will become apparent instantly and for me the most rewarding aspect - knowing when you laid down that first character in your code you did so with the knowledge of what you were doing was the best you could provide to your employer and/or clients. Back to implementing the Search functionality, I added the following function to my PostFactory class:
public List<Objects.Post> GetSearchResults(string searchQueryString) {
     using (var eFactory = new bbxp_jarredcapellmanEntities()) {
     return eFactory.getSearchPostListingSP(searchQueryString).Select(a => new Objects.Post(a.ID, a.Created, a.Title, a.Body, a.TagList, a.SafeTagList, a.NumComments.Value, a.URLSafename)).ToList(); }
You might see the similarity to other functions if you've been following this series. The function exposed in an Operation Contract inside the WCF Service:
[OperationContract] List<lib.Objects.Post> GetPostSearchResults(string searchQueryString); public List<Post> GetPostSearchResults(string searchQueryString) {
     using (var pFactory = new PostFactory()) {
     return pFactory.GetSearchResults(searchQueryString); }
Back in the MVC App I created a new route to handle searching:
routes.MapRoute("Search", "Search/{
", new {
     controller = "Home", action = "Search" }
); ]]>
So now I can enter values via the url like so: Would search all Posts that contained mvc in the title or body. Then in my Controller class:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Search(string searchQueryString) {
     ViewBag.Title = searchQueryString + " << Search Results << " + Common.Constants.SITE_NAME; var model = new Models.HomeModel(baseModel); using (var ws = new WCFServiceClient()) {
     model.Posts = ws.GetPostSearchResults(searchQueryString); }
ViewBag.Model = model; return View("Index", model); }
In my partial view:
<div class="Widget"> <div class="Title"> <h3>Search Post History</h3> </div> <div class="Content"> @using (Html.BeginForm("Search", "Home", new {
     searchQueryString = "searchQueryString"}
, FormMethod.Post)) {
     <input type="text" id="searchQueryString" name="searchQueryString" class="k-textbox" required placeholder="enter query here" /> <button class="k-button" type="submit">Search >></button> }
</div> </div> ]]>
When all was done: [caption id="attachment_2078" align="aligncenter" width="252"]Search box <span classin MVC App" width="252" height="171" class="size-full wp-image-2078" /> Search box in MVC App[/caption] Now you might be asking, what if there are no results? Your get an empty view: [caption id="attachment_2079" align="aligncenter" width="300"]Empty Result - Wrong way to handle it Empty Result - Wrong way to handle it[/caption] This leads me to my next topic:

Custom Error Pages

We have all been on sites where we go some place we either don't have access to, doesn't exist anymore or we misspelled. WordPress had a fairly good handler for this scenario: [caption id="attachment_2081" align="aligncenter" width="300"]WordPress Content not found Handler WordPress Content not found Handler[/caption] As seen above when no results are found, we want to let the user know, but also create a generic handler for other error events. To get started let's add a Route to the Global.asax.cs:
routes.MapRoute("Error", "Error", new {
     controller = "Error", action = "Index" }
); ]]>
This will map to /Error with a tie to an ErrorController and a Views/Error/Index.cshtml. And my ErrorController:
public class ErrorController : BaseController {
     public ActionResult Index() {
     var model = new Models.ErrorModel(baseModel); return View(model); }
And my View:
@model bbxp.mvc.Models.ErrorModel <div class="errorPage"> <h2>Not Found</h2> <div class="content"> Sorry, but you are looking for something that isn't here. </div> </div> ]]>
Now you maybe asking why isn't the actual error going to be passed into the Controller to be displayed? For me I personally feel a generic error message to the end user while logging/reporting the errors to administrators and maintainers of a site is the best approach. In addition, a generic message protects you somewhat from exposing sensitive information to a potential hacker such as "No users match the query" or worse off database connection information. That being said I added a wrapper in my BaseController:
public ActionResult ThrowError(string exceptionString) {
     // TODO: Log errors either to the database or email powers that be return RedirectToAction("Index", "Error"); }
This wrapper will down the road record the error to the database and then email users with alerts turned on. Since I haven't started on the "admin" section I am leaving it as is for the time being. The reason for the argument being there currently is that so when that does happen all of my existing front end code is already good to go as far as logging. Now that I've got my base function implemented, let's revisit the Search function mentioned earlier:
public ActionResult Search(string searchQueryString) {
     ViewBag.Title = searchQueryString + " << Search Results << " + Common.Constants.SITE_NAME; var model = new Models.HomeModel(baseModel); using (var ws = new WCFServiceClient()) {
     model.Posts = ws.GetPostSearchResults(searchQueryString); }
if (model.Posts.Count == 0) {
     ThrowError(searchQueryString + " returned 0 results"); }
ViewBag.Model = model; return View("Index", model); }
Note the If conditional and the call to the ThrowError, no other work is necessary. As implemented: [caption id="attachment_2083" align="aligncenter" width="300"]Not Found Error Handler Page <span classin the MVC App" width="300" height="81" class="size-medium wp-image-2083" /> Not Found Error Handler Page in the MVC App[/caption] Where does this leave us? The final phase in development: Optimization.


You might be wondering why I left optimization for last? I feel as though premature optimization leads to not only a longer debugging period when nailing down initial functionality, but also if you do things right as you go on your optimizations are really just tweaking. I've done both approaches in my career and definitely have had more success with doing it last. If you've had the opposite experience please comment below, I would very much like to hear your story. So where do I want to begin?

YSlow and MVC Bundling

For me it makes sense to do the more trivial checks that provide the most bang for the buck. A key tool to assist in this manner is YSlow. I personally use the Firefox Add-on version available here. As with any optimization, you need to do a baseline check to give yourself a basis from which to improve. In this case I am going from a fully featured PHP based CMS, WordPress to a custom MVC4 Web App so I was very intrigued by the initial results below. [caption id="attachment_2088" align="aligncenter" width="300"]WordPress YSlow Ratings WordPress YSlow Ratings[/caption] [caption id="attachment_2089" align="aligncenter" width="300"]Custom MVC 4 App YSlow Results Custom MVC 4 App YSlow Ratings[/caption] Only scoring 1 point less than the battle tested WordPress version with no optimizations I feel is pretty neat. Let's now look into what YSlow marked the MVC 4 App down on. In the first line item, it found that the site is using 13 JavaScript files and 8 CSS files. One of the neat MVC features is the idea of bundling multiple CSS and JavaScript files into one. This not only cuts down on the number of HTTP Requests, but also speeds up the initial page load where most of your content is subsequently cached on future page requests. If you recall going back to an earlier post our _Layout.cshtml we included quite a few CSS and JavaScript files:
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.common.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.default.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.default.min.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/kendo/2013.1.319/jquery.min.js")"></script> <script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.all.min.js")"></script> <script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.aspnetmvc.min.js")"></script> <script src="@Url.Content("~/Scripts/kendo.modernizr.custom.js")"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shCore.js")" type="text/javascript"></script> <link href="@Url.Content("~/Content/syntaxhighlighter/shCore.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/syntaxhighlighter/shThemeRDark.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushCSharp.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushPhp.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushXml.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushCpp.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushBash.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/syntaxhighlighter/shBrushSql.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/lightbox/jquery-1.7.2.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/lightbox/lightbox.js")" type="text/javascript"></script> <link href="@Url.Content("~/Content/lightbox/lightbox.css")" rel="stylesheet" type="text/css" /> ]]>
Let's dive into Bundling all of our JavaScript files. First off create a new class, I called it BundleConfig and inside this class add the following static function:
public static void RegisterBundles(BundleCollection bundles) {
     // JavaScript Files bundles.Add(new ScriptBundle("~/Bundles/kendoBundle") .Include("~/Scripts/kendo/2013.1.319/jquery.min.js") .Include("~/Scripts/kendo/2013.1.319/kendo.all.min.js") .Include("~/Scripts/kendo/2013.1.319/kendo.aspnetmvc.min.js") .Include("~/Scripts/kendo.modernizr.custom.js") ); bundles.Add(new ScriptBundle("~/Bundles/syntaxBundle") .Include("~/Scripts/syntaxhighlighter/shCore.js") .Include("~/Scripts/syntaxhighlighter/shBrushCSharp.js") .Include("~/Scripts/syntaxhighlighter/shBrushPhp.js") .Include("~/Scripts/syntaxhighlighter/shBrushXml.js") .Include("~/Scripts/syntaxhighlighter/shBrushCpp.js") .Include("~/Scripts/syntaxhighlighter/shBrushBash.js") .Include("~/Scripts/syntaxhighlighter/shBrushSql.js") ); bundles.Add(new ScriptBundle("~/Bundles/lightboxBundle") .Include("~/Scripts/lightbox/jquery-1.7.2.min.js") .Include("~/Scripts/lightbox/lightbox.js") ); }
Then in your _Layout.cshtml replace all of the original JavaScript tags with the following 4 lines:
@Scripts.Render("~/Bundles/kendoBundle") @Scripts.Render("~/Bundles/syntaxBundle") @Scripts.Render("~/Bundles/lightboxBundle") ]]>
So afterwards that block of code should look like:
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.common.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.default.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.default.min.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/syntaxhighlighter/shCore.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/syntaxhighlighter/shThemeRDark.css")" rel="stylesheet" type="text/css" /> <link href="@Url.Content("~/Content/lightbox/lightbox.css")" rel="stylesheet" type="text/css" /> @Scripts.Render("~/Bundles/kendoBundle") @Scripts.Render("~/Bundles/syntaxBundle") @Scripts.Render("~/Bundles/lightboxBundle") ]]>
Finally go to your Global.asax.cs file and inside your Application_Start function add the following line:
BundleConfig.RegisterBundles(BundleTable.Bundles); ]]>
So in the end your Application_Start function should look like:
protected void Application_Start() {
     AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
Now after re-running the YSlow test: [caption id="attachment_2092" align="aligncenter" width="300"]YSlow Ratings after Bundling of JavaScript Files <span classin the MVC App" width="300" height="190" class="size-medium wp-image-2092" /> YSlow Ratings after Bundling of JavaScript Files in the MVC App[/caption] Much improved, now we're rated better than WordPress itself. Now onto the bundling of the CSS styles. Add the following below the previously added ScriptBundles in your BundleConfig class:
// CSS Stylesheets bundles.Add(new StyleBundle("~/Bundles/stylesheetBundle") .Include("~/Content/Site.css") .Include("~/Content/lightbox/lightbox.css") .Include("~/Content/syntaxhighlighter/shCore.css") .Include("~/Content/syntaxhighlighter/shThemeRDark.css") .Include("~/Content/kendo/2013.1.319/kendo.common.min.css") .Include("~/Content/kendo/2013.1.319/kendo.dataviz.min.css") .Include("~/Content/kendo/2013.1.319/kendo.default.min.css") .Include("~/Content/kendo/2013.1.319/kendo.dataviz.default.min.css") ); ]]>
And then in your _Layout.cshtml add the following in place of all of your CSS includes:
@Styles.Render("~/Bundles/stylesheetBundle") ]]>
So when you're done, that whole block should look like the following:
@Styles.Render("~/Bundles/stylesheetBundle") @Scripts.Render("~/Bundles/kendoBundle") @Scripts.Render("~/Bundles/syntaxBundle") @Scripts.Render("~/Bundles/lightboxBundle") ]]>
One thing that I should note is if your Bundling isn't working check your Routes. Because of my Routes, after deployment (and making sure the is set to false), I was getting 404 errors on my JavaScript and CSS Bundles. My solution was to use the IgnoreRoutes method in my Global.asax.cs file:
routes.IgnoreRoute("Bundles/*"); ]]>
For completeness here is my complete RegisterRoutes:
"); routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{
", defaults: new {
     id = RouteParameter.Optional }
); routes.IgnoreRoute("Bundles/*"); routes.MapRoute("Error", "Error/", new {
     controller = "Error", action = "Index" }
); routes.MapRoute("Search", "Search/{
", new {
     controller = "Home", action = "Search" }
); routes.MapRoute("Feed", "Feed", new {
    controller = "Home", action = "Feed"}
); routes.MapRoute("Tags", "tag/{
", new {
    controller = "Home", action = "Tags"}
); routes.MapRoute("PostsRoute", "{
", new {
     controller = "Home", action = "Posts" }
, new {
     year = @"\d+" }
); routes.MapRoute("ContentPageRoute", "{
", new {
    controller = "Home", action = "ContentPage"}
); routes.MapRoute("PostRoute", "{
", new {
     controller = "Home", action = "SinglePost" }
, new {
     year = @"\d+", month = @"\d+", day = @"\d+" }
); routes.MapRoute("Default", "{
", new {
     controller = "Home", action = "Index" }
); ]]>
Afterwards everything was set properly and if you check your source code you'll notice how MVC generates the HTML:
<link href="/Bundles/stylesheetBundle?v=l3WYXmrN_hnNspLLaGDUm95yFLXPFiLx613TTF4zSKY1" rel="stylesheet"/> <script src="/Bundles/kendoBundle?v=-KrP5sDXLpezNwcL3Evn9ASyJPShvE5al3knHAy2MOs1"></script> <script src="/Bundles/syntaxBundle?v=NQ1oIC63jgzh75C-QCK5d0B22diL-20L4v96HctNaPo1"></script> <script src="/Bundles/lightboxBundle?v=lOBITxhp8sGs5ExYzV1hgOS1oN3p1VUnMKCjnAbhO6Y1"></script> ]]>
After re-running YSlow: [caption id="attachment_2095" align="aligncenter" width="300"]YSlow after all bundling <span classin MVC" width="300" height="215" class="size-medium wp-image-2095" /> YSlow after all bundling in MVC[/caption] Now we received a score of 96. What's next? Caching.

MVC Caching

Now that we've reduced the amount of data being pushed out to the client and optimized the number of http requests, lets switch gears to reducing the load on the server and enhance the performance of your site. Without diving into all of the intricacies of caching, I am going to turn on server side caching, specifically Output Caching. At a later date I will dive into other approaches of caching including the new HTML5 client side caching that I recently dove into. That being said, turning on Output Caching in your MVC application is really easy, simply put the OutputCache Attribute above your ActionResults like so:
[OutputCache(Duration = 3600, VaryByParam = "*")] public ActionResult SinglePost(int year, int month, int day, string postname) {
     ----- }
In this example, the ActionResult will be cached for one hour (3600 seconds = 1 hour) and by setting the VaryByParam to * that means each combination of arguments passed into the function is cached versus caching one argument combination and displaying the one result. I've seen developers simply turn on caching and not thinking about dynamic content - suffice it to say, think about what could be cached and what can't. Common items that don't change often like your header or sidebar can be cached without much thought, but think about User/Role specific content and how bad it would be for a "Guest" user to see content as a Admin because an Admin had accessed the page within the cache time before a Guest user had.


In this post I went through the last big three items left in my migration from WordPress to MVC: Search Handling, Custom Error Pages and Caching. That being said I have a few "polish" items to accomplish before switching over the site to all of the new code, namely additional testing and adding a basic admin section. After those items I will consider Phase 1 completed and go back to my Windows Phone projects. Stay tuned for Post 9 tomorrow night with the polish items.
As mentioned yesterday I began diving back into a large project at work that involves Windows Workflow. At this point it had been almost six months to the day when I last touched the initial code I did, so today involved a lot of getting back into the mindset I had then and what I was trying to accomplish. This digging unfortunately left me figuring out I had left the code in a non-functional state, to the point that the Workflow Service was not connecting to the AppFabric databases properly. Long story short, three hours later I was able to get everything where I thought I had left it. Lesson learned here is that before jumping projects, always make sure you leave it in a usable state or at least document what isn't working properly. In my defense, the original sidetracking project was to be only three weeks. Back to the Windows Workflow development - one issue I was having today with my xamlx/Code Activity was my InArgument variables defined at a global level in my xamlx file I was not able to retrieve or set using the more proper method of:
InArgument<decimal> SomeID {
     get; set; protected override Guid Execute(CodeActivityContext context) {
     SomeID.Get(context); // To get the value SomeID.Set(context, 1234); // Set it to 1234 }
No matter what, the value was always 0 when getting the variable's value even though it had been set on the entry point of the Workflow. After trying virtually just about everything I could I came up with a work around that does work. Do note I highly doubt this is the way Microsoft intended for it to be accomplished, but for the time being this is the only way I could get my xamlx defined variables updated/set in the custom CodeActivity. What I did was create as generic set/get functions as possible below:
private T getValue<T>(CodeActivityContext context, string name) {
     var properties = context.DataContext.GetProperties()[name]; if (properties == null) {
     return default(T); }
return (T) properties.GetValue(context.DataContext); }
private void setValue(CodeActivityContext context, string name, object value) {
     context.DataContext.GetProperties()[name].SetValue(context.DataContext, value); }
And then to use the functionality in your CodeActivity:
protected override Guid Execute(CodeActivityContext context) {
     var SomeID = getValue<decimal>(context, "SomeID"); // Get the SomeID variable setValue(context, "SomeID", 1234); // Set SomeID to 1234 }
Hopefully that gets someone on the right track and if you do eventually find the "correct" way please let me know. Otherwise I will definitely be asking the Windows Workflow experts at TechED North America in June.
If you've been following my blog posts over the last couple of years you'll know I have a profound love of using XML files for reading and writing for various purposes. The files are small and because of things like Typed Datasets in C# you can have clean interfaces to read and write XML files. In Windows Phone however, you do not have Typed Datasets so you're stuck utilizing the XmlSerializer to read and write. To make it a little easier going back to last Thanksgiving I wrote some helper classes in my NuGet library jcWPLIBRARY. The end result within a few lines you can read and write List Collections of Class Objects of your choosing. So why continue down this path? Simple answer: I wanted it better. Tonight I embarked on a "Version 2" of this functionality that really makes it easy to keep with your existing Entity Framework knowledge, but provide the functionality of a database on a Windows Phone 8 device that currently doesn't exist in the same vain it can in a MVC, WinForm, WebForm or Console app. To make this even more of a learning experience, I plan to blog the entire process, the first part of the project: reading all of the objects from an existing file. To begin, I am going to utilize the existing XmlHandler class in my existing Library. This code has been battle tested and I feel no need to write something from scratch especially since I am going to leave the existing classes in the library to not break anyone's apps or my own. First thoughts, what does a XmlSerializer file actually look like when written to? Let's assume you have the following class, a pretty basic class:
public class Test : jcDB.jObject {
     public int ID {
     get; set; }
public bool Active {
     get; set; }
public string Name {
     get; set; }
public DateTime Created {
     get; set; }
The output of the file is like so: [xml] <?xml version="1.0" encoding="utf-8"?> <ArrayOfTest xmlns:xsi="" xmlns:xsd=""> <Test> <ID>1</ID> <Active>true</Active> <Name>Testing Name</Name> <Created>2013-04-03T20:47:09.8491958-04:00</Created> </Test> </ArrayOfTest> [/xml] I often forget the XmlSerializer uses the "ArrayOf" prefix on the name of the root object so when testing with sample data when writing a new Windows Phone 8 app I have to refer back - hopefully that helps someone out. Going back to the task at hand - reading data from an XML file and providing an "Entity Framework" like experience - that requires a custom LINQ Provider and another day of programming it. Stay tuned for Part 2 where I go over creating a custom LINQ Provider bound to an XML File.
For the last 2.5 years I've been using the default MonoDevelop Web Reference in my MonoTouch applications for work, but it's come to the point where I really need and want to make use of the WCF features that I do in my Windows Phone applications. Even with the newly released iOS Integration in Visual Studio 2012, you still have to generate the proxy class with the slsvcutil included with the Silverlight 3.0 SDK. If you're like me, you probably don't have Version 3.0 of the Silverlight SDK, you can get it from Microsoft here. When running the tool you might get the following error: Error: An error occurred in the tool. Error: Could not load file or assembly 'C:\Program Files (x86)\Microsoft Silverl ight\5.1.10411.0\System.Runtime.Serialization.dll' or one of its dependencies. T his assembly is built by a runtime newer than the currently loaded runtime and c annot be loaded. Basically the tool is incorrectly trying to pull the newer 4.0 or 5.0 Silverlight Assemblies, to make it easy, I created a config file to simply drop into your c:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Tools folder, you can download it here. From a command line (remember the shortcut to hold shift down and right click in the folder to open a command prompt): [caption id="attachment_1853" align="aligncenter" width="593"]Silverlight 3 WCF Proxy Generation Silverlight 3 WCF Proxy Generation[/caption] Enter the following, assuming you want to create a proxy for a localhost WCF Service to your c:\tmp folder: SlSvcUtil.exe http://localhost/Service.svc?wsdl /noconfig /d:c:\tmp Though I should note, this will generate Array collections and not List or ObservableCollection collections. If you want to generate your Operation Contracts with return types of those collections simply add for List Collections: /collectionType:System.Collections.Generic.List`1 or ObservableCollection: /collectionType:System.Collections.ObjectModel.ObservableCollection`1
Came into a frustrating issue this morning with an app using MVMM in Windows Phone 7. I had a couple of textboxes, 2 with multi-line support and an Application Bar with a Save Icon. The idea being if you wanted to save your changes in the textboxes, tap the Save Icon and everything would save. Little did I know, the Textboxes only trigger an update to your binding when losing focus. So if the end user left the textbox focused, the trigger wouldn't occur and your save functionality in your View Model would not have the newly entered text. A clean work around for this problem is to create a generic OnTextChanged event handler function to trigger the update and then map that function to each of your textboxes. Here's some sample code in my XAML file:
<telerikPrimitives:RadTextBox TextChanged="Rtb_OnTextChanged" Text="{
    Binding Option.Title, Mode=TwoWay}
" x:Name="rtbTitle" Watermark="enter your title here" Header="cover page title" HideWatermarkOnFocus="True" /> <telerikPrimitives:RadTextBox TextChanged="Rtb_OnTextChanged" TextWrapping="Wrap" Text="{
    Binding Option.CoverPageText, Mode=TwoWay}
" x:Name="rtbCoverPage" Height="200" Watermark="enter your cover page text here" Header="cover page text" HideWatermarkOnFocus="True" /> <telerikPrimitives:RadTextBox TextChanged="Rtb_OnTextChanged" TextWrapping="Wrap" Text="{
    Binding Option.SummaryPageText, Mode=TwoWay}
" x:Name="rtbSummaryPage" Height="200" Watermark="enter your summary page text here" Header="summary page text" HideWatermarkOnFocus="True" /> ]]>
And then in your code behind:
private void Rtb_OnTextChanged(object sender, TextChangedEventArgs e) {
     var bindingExpression = ((TextBox) sender).GetBindingExpression(TextBox.TextProperty); if (bindingExpression != null) {
     bindingExpression.UpdateSource(); }
Working on a XNA/XAML game tonight I wanted to have a consistent UI experience between the XAML and XNA views. A key part of that was matching the Photoshop graphics and the in-game font. Having never used a TrueType Font (TTF) in Windows Phone 7.x I was curious how hard it would be to do in Windows Phone 8 where I have found many tasks to be streamlined. Unsurprisingly the process is pretty straight forward:
  1. Copy your TrueType Font to your solution folder
  2. Make sure the Build Action is set to Content and Copy to Output Directory to Copy if newer
In your XAML then reference the TrueType Font in your XAML with the file path#font name like so:
<TextBlock HorizontalAlignment="Center" FontFamily=".\Data\OCRAExt.ttf#OCR A Extended" FontSize="80" Text="TTFS ROCK" /> ]]>
Note you need to keep any spaces found in the font, if you aren't sure, double click on the font and make sure your XAML matches the what I've circled in red: [caption id="attachment_1810" align="aligncenter" width="572"]TrueType Font Name <span classin Windows 8" width="572" height="339" class="size-full wp-image-1810" /> TrueType Font Name in Windows 8[/caption] Something weird I did find with a couple of TrueType Fonts I tried was some font creators put a space at the end. If you're like me that'll drive you nuts, especially when referencing the custom font multiple times in your XAML. If you find a case like that, download TTFEdit from source forge and trim the space off the end and save it. If you follow those steps properly, you'll have your TTF in your Windows Phone 8 App: [caption id="attachment_1805" align="aligncenter" width="480"]TTF <span classin Windows Phone 8" width="480" height="800" class="size-full wp-image-1805" /> TTF in Windows Phone 8[/caption]
Something I never understood why it wasn't part of the base TextBox control is the ability to override the GotFocus colors with an easy to use property, like FocusForeground or FocusBackground. You could do something like this:
private void txtBxPlayerName_GotFocus(object sender, RoutedEventArgs e) {
     Foreground = new SolidColorBrush(Colors.Black); }
By default, the Background on a Focus event of a Windows Phone TextBox control sets it to White, so if you had White Text previously, upon entering Text, your Text would be invisible. The workaround above isn't pretty, nor handles the LostFocus property (ie to revert back to your normal colors after entering Text. If you have 2,3,4 or more TextBox controls, this could get tedious/clutter up your code. My "fix", extending the TextBox Control:
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace WPGame {
     public class jcTextBox : TextBox {
     #region New Background and Foreground Properties public static readonly DependencyProperty FocusForegroundProperty = DependencyProperty.Register("FocusForeground", typeof(Brush), typeof(jcTextBox), null); public Brush FocusForeground {
     get {
     return base.GetValue(FocusForegroundProperty) as Brush; }
set {
     base.SetValue(FocusForegroundProperty, value); }
public static readonly DependencyProperty FocusBackgroundProperty = DependencyProperty.Register("FocusBackground", typeof(Brush), typeof(jcTextBox), null); public Brush FocusBackground {
     get {
     return base.GetValue(FocusBackgroundProperty) as Brush; }
set {
     base.SetValue(FocusBackgroundProperty, value); }
public static readonly DependencyProperty BaseForegroundProperty = DependencyProperty.Register("BaseForeground", typeof(Brush), typeof(jcTextBox), null); public Brush BaseForeground {
     get {
     return base.GetValue(BaseForegroundProperty) as Brush; }
set {
     base.SetValue(BaseForegroundProperty, value); }
public static readonly DependencyProperty BaseBackgroundProperty = DependencyProperty.Register("BaseBackground", typeof(Brush), typeof(jcTextBox), null); public Brush BaseBackground {
     get {
     return base.GetValue(BaseBackgroundProperty) as Brush; }
set {
     base.SetValue(BaseBackgroundProperty, value); }
#endregion public jcTextBox() {
     BaseForeground = Foreground; BaseBackground = Background; }
#region Focus Event Overrides protected override void OnGotFocus(RoutedEventArgs e) {
     Foreground = FocusForeground; Background = FocusBackground; base.OnGotFocus(e); }
protected override void OnLostFocus(RoutedEventArgs e) {
     Foreground = BaseForeground; Background = BaseBackground; base.OnLostFocus(e); }
#endregion }
To use it, add it to your project and then you can just drag and drop the control from the Toolbox and use it like so:
<my:jcTextBox x:Name="txtBxPlayerName" Background="#1e1e1e" Foreground="White" BaseBackground="#1e1e1e" BaseForeground="White" FocusForeground="Black" FocusBackground="#2e2e2e" AcceptsReturn="False" /> ]]>
The output: [caption id="attachment_1354" align="aligncenter" width="180"] Unfocused jcTextBox Controls[/caption] [caption id="attachment_1355" align="aligncenter" width="180"] Visible Text with jcTextBox on Focus[/caption] [caption id="attachment_1356" align="aligncenter" width="180"] LostFocus jcTextBox Text with original colors[/caption] So there you have it, a "fix" for a common problem (at least in my experience). Feel free to use, rewrite, whatever with the jcTextBox class.
After having used PLINQ and the Concurrent collections for nearly 2 months now, I can say without a doubt, it is definitely the way of the future. This last week I used it extensively in writing a WCF Service that manipulated a lot of data and needed to return it to an ASP.NET client very quickly. And on the flip side it needed to execute a lot of SQL Insertions based on business logic pretty quickly. As of February 25th, 2012, I think the best approach to writing a data layer is:
  1. Expose all Data Layer access through a WCF Service, ensuring a clear separation between UI and Data Layers
  2. Use of ADO.NET Entity Models tied to SQL Stored Procedures that return Complex Types for objects rather doing a .Where(a => a.Active).ToList()
  3. Process larger result sets with PLINQ, using Concurrent Collections (ie ConcurrentQueue or ConcurrentDictionary) and returning them to the Client (ASP.NET, WP7 etc)
Next step in my opinion would be to add in intelligent App Fabric caching like what Smarty Template Engine did for PHP. Just a clean way to cache pages, while providing flexible ways to invalidate the cache. I am so glad I found that back in 2006 when I was still doing a lot of PHP work.
Finally got around to replacing the 4 80mm 40 decibel fans in my Origin 300 this morning. The noise from this one server was enough to travel from the basement inside a rack all the way to the 3rd floor Master Bedroom. Suffice it to say, I definitely couldn't run the server 24/7. Hunting around on Amazon, I found these 80mm Cooler Master fans, not too bad price wise and still put out decent air flow. [caption id="attachment_963" align="aligncenter" width="225" caption="New Cooler Master 80mm replacement fans for my SGI Origin 300"][/caption] Prep for the swap: [caption id="attachment_964" align="aligncenter" width="225" caption="My Quad R14k SGI Origin 300"][/caption] The original fan in case someone needed a part number: [caption id="attachment_965" align="aligncenter" width="225" caption="SGI Origin 300 Stock Fan"][/caption] As I was swapping in the new fans, I realized the fan connector was not the standard ATX style. Stock Connector: [caption id="attachment_966" align="aligncenter" width="300" caption="Stock SGI Origin 300 Fan Connector"][/caption] Versus the standard ATX connector: [caption id="attachment_967" align="aligncenter" width="300" caption="Repacement Cooler Master Fan ATX Connector"][/caption] Luckily the standard 4 pin Molex power connector for the 2 Ultra 160 drives is right next to the fans, so a little wiring job and voila: [caption id="attachment_968" align="aligncenter" width="300" caption="SGI Origin 300 with replacement fans installed"][/caption] Note, doing it this way will throw an error in the L1 Console and will shut your machine down. A way around it is to simply connect to the Origin 300 over a console connection and type: env off. This is dangerous though as the server will not shutdown automatically if a fan fails or the server overheats. Having said that, it came to my attention that IRIX does not install a Serial/Terminal client by default. The common cu is on the IRIX 6.5 Foundation CD 1 disk. Turn on the Subsystems Only in the IRIX Software Manager and scroll down until you see it. Chances are you're not running a base 6.5 install so you'll also need the first disk of your overlays (6.5.30 Overlay CD 1 in my case) in order to install it to resolve the package conflicts. After installing you may receive a "CONNECT FAILURE: NO DEVICES AVAILABLE". Open up vi or your favorite text editor and open up /etc/uucp/Devices Add in a line: Direct ttyd2 - 38400 direct Make sure the spaces are there. You can also try setting it up via the Serial Manager under the System Manager application. Afterwards, simply running: cu -l /dev/ttyd2 -s38400 Allowed me into my L1 console to turn off environment monitoring. Then hit Control + D to get back into the PROM Monitor and hit "1" to start IRIX.