AllPaul

programming, tech, hobbies and grief

20. April 2013 07:05
by Paul Apostolos
0 Comments

Use a Custom DisplayModeProvider to Serve Crawler Friendly Content Pages

20. April 2013 07:05 by Paul Apostolos | 0 Comments

I have been working on a large website redesign. The site relies heavily on client-side rendering of html elements and leverages ajax to limit server postbacks.  For example, to display a list or grid of items, I am using the Kendo UI Web controls ListView or Grid. These controls don't render search-engine friendly content however. Thankfully, with just a few lines of code, I can create custom views for search engines that render the content in a more indexable way. But, that means I give up the benefits of these controls; namely the client side rendering, sorting and paging.

DisplayModeProviders to the rescue

In ASP.NET MVC 4 there is a new DisplayModeProvider class that allows application developers to tap into the pipeline of MVC view selection. It changes the selection process of the view and can be configured to automatically serve different views to mobile browsers by just changing the filename of a Razor view from (for example) Index.cshtml to Index.Mobile.cshtml. And, because the view is (or at least should be) responsible for rendering the output to the client, changing the view shouldn't require any changes to the underlying business logic. Or, more simply, to support alternative layouts of the same page, a developer could simply add a new view for that new layout without affecting the application logic.

Out of the box, MVC 4 supports "Mobile" as a display mode, but additional DisplayModes can easily be added to applications in the global.asax file. So I decided to add a simple DisplayMode to detect if the current request was from a search engine indexer and serve a custom view with all the ajax and client-side rendering removed.

To add my new DisplayMode, I added the following code to the Application_Start method of the global.asax file:

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Crawler")
{
       ContextCondition = (context => Utils.IsCrawler(context.Request))
});

And in my Utils class I have a static method to detect whether the request is a search engine indexer.

public static bool IsCrawler(HttpRequestBase request)
{
    bool isCrawler = request.Browser.Crawler;
            
    if (!isCrawler)
    {
        Regex regEx = new Regex(ConfigurationManager.AppSettings["CrawlerMatches"]);
        isCrawler = regEx.Match(request.UserAgent).Success;
    }
    return isCrawler;
}

This method is all over the Internet; the only interesting part of it is the Regex pattern is stored in the web.config so it can be easily modified.

So, what happens?

When a request comes into the site, the request is evaluated by the DisplayModeProvider and if it satisfies the condition of being a search engine indexer (evaluated by the method Utils.IsCrawler) then the view selection will first look for a view with the same name as the normally returned view but with a ".Crawler.cshtml" extension instead of just ".cshtml".

And for the requests that would normally include client-side rendering, I just add an additional version of the view with the ".Crawler.cshtml" extension and that page will get served automatically to search engine indexers.

Wrapping up 

Developing site that relies heavily on client-side content rendering can be detrimental to search engine visibility. In the past I would have just created all the rendering on the server and sacrificed the interaction speed of having script render the contents client side. With DisplayModeProviders, I'm able to supplement the client-side rendering view with a view that presents a more indexable interface.

It should be noted here, that I am not trying to trick the search engine spider at all. The page the spider will see is exactly the same as a person would see. I am merely changing the interaction of the navigation to be server side instead of client side.

Give it a try and let me know what you find.

Good luck to you!

30. March 2013 07:17
by Paul Apostolos
0 Comments

Set Session State to Read Only on AJAX-Called MVC Controllers

30. March 2013 07:17 by Paul Apostolos | 0 Comments

On a recent line-of-business browser-based application implementation I ran across a very interesting issue.  The application calls another back-end application through a specialized data provider to display customers, employees and invoices. Because this data doesn't change that often and the validity of the data isn't that important, I decided it was a perfect candidate for caching.  In addition to caching, I want to be sure not to block the current http request while the application fetches the data into the cache from the provider, so I planned to implement a JsonResult MVC controller to allow me to fetch the data in an asynchronous AJAX request. That all seemed pretty straight forward when I first thought about it.  However, in reality, it was a few months of wrestling with the caching story, trying different providers and even building a windows service to alleviate the long client requests.  In the end, I only needed to be better at Google/Bing and the whole thing could have been done in a day.

People still use QuickBooks?

This project was a employee time tracking/job costing/inventory management application for a construction company.  One of the big selling points of the new application to the account stakeholders was the integration with QuickBooks.  I reviewed a few QuickBooks data providers before the project began and it seemed fairly straight forward. The two main players in the QB data provider market are QODBC and RssBus. Neither of them are very fast or easy to implement.  In the end, I decided on RssBus because they offered an install-as-a-service remote connector (to allow my application to connect to QuickBooks even if QuickBooks isn't open on the server) and they offer an EntityFramework provider.

I installed and configured RssBus and built a model with just a few entities: employees, customers and invoices. Then I created the rest of the data access repository and added that library to my solution. At this point, I was thinking I would be done in another hour or so...

The MVC and JavaScript story

I added a new MVC controller to application and called it QuickBooksDataController (it turns out that this is the one thing I did correctly from the start) and made a few methods to get the collections and return them as Json.

QBRepo repo = new QBRepo();
public JsonResult GetEmployeeNameAndID()
{
   var employees = repo.QBEmployeeNamesAndIDs.Select(c => new { ID = c.Key, Name = c.Value });
   return Json(new { result = true, data = employees }, JsonRequestBehavior.AllowGet);
}

Then I created a JavaScript AJAX method to get the data on a page after the page was done loading.

$(document).ready(function () {
     var ddl = $('#ddlQBEmployeeID');
     ddl.prepend($('<option></option>').html('Loading...'));
     $.getJSON("/api/QuickBooksData/GetEmployeeNameAndID", null,
          function (ret) {
              var selectedItem = '@Model.QBEmployeeID';
               $('#ddlQBEmployeeID').empty();
               $.each(ret.data, function () {
               $('#ddlQBEmployeeID')
                     .append($("<option />").val(this.ID).text(this.Name));
                });
                if (selectedItem.length > 0) {
                    $('#ddlQBEmployeeID').val(selectedItem);
               }
        });
 });

At this point I thought I was pretty much done. So I right clicked on project and chose View in browser....The page did exactly what I thought it would...It loaded everything and while the QuickBooks data was being fetched, the select list displayed "Loading...".  After 70 seconds, the select list populated.  I thought, obviously, I need some caching.

Time for some caching

Well, RssBus provides built in caching so I tried that.  I just needed to change the connection string and the provider would cache automatically;so I did that. I then refreshed the page and still 70 seconds on the first request...Ha, on the second request it was just a few seconds though. Now, I thought I was done...like really done. But, I hadn't really uncovered the problem.

So, where's the problem?

During some other testing I noticed that if I clicked on a page that had one of these AJAX requests to a long-running process (like repo.QBEmployeeNamesAndIDs) that the next time I clicked on a page I would still need to wait the full 70 seconds before a different page (without any AJAX requests on it) would be served by the server. And, what's worse is, the normal path of entry to the application is home page (with a few of these requests on it) to login page. By that I mean, the user will go to the application home page and click on the login link (or another link that will force them to log in).  The process from home to login was taking 70+ seconds. 

To allieviate the problem I tried literally every different type of asynchronous programming method: Background Worker, Async/Await, TaskFactory, and even a separate windows service. Nothing was simple and it seemed no matter what I did I still had the delay issue.

So, what fixed it? 

I was up late pulling my hair out when it dawned on me...The issue I was experiencing was not related to the caching of the data.  The issue I had was, IIS was blocking all requests (per user, but I didn't know that until I figured out the whole problem) until a single request finished. That was a sanity check...Why would it do that?  So instead of Google/Binging for caching strategies and asynchronous request methods, I changed my query to "long running ajax request blocks MVC". That was it.  I was on my way to the answer.  After several StackOverflow questions and answers I found it and it makes total sense.

Session state blocks on each request per user just in case something is changed in the user's session from one request to another.  So, basically, my AJAX requests were blocking other requests in order to modify the user's session if required. But, I didn't need session state modification during these requests, so I needed to figure out how to turn it off.

Remember when I said I created a controller just for the QuickBooks data and that was one of the only things I did right? Well, because there was just one controller with these methods in it I simply needed to decorate the controller with a data annotation to signify that it wouldn't be modifying session state:

[SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]
public class QuickBooksDataController : Controller
{
    QBCacheManager cm = new QBCacheManager();
    public JsonResult GetEmployeeNameAndID()
    {
        var employees = cm.QBEmployeeNamesAndIDs.Select(c => new { ID = c.Key, Name = c.Value });
        return Json(new { result = true, data = employees }, JsonRequestBehavior.AllowGet);
    }
}

Seriously, it was that easy. [SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)] is all I needed.

Wrapping up

So, I learned a lesson here...It's not supposed to be hard and if it is, I need to double and triple check that I am going down the right path. And, set session state to read only for AJAX request controller actions.

Good luck to you!

25. March 2013 05:36
by Paul Apostolos
0 Comments

AttachTo Visual Studio Extension

25. March 2013 05:36 by Paul Apostolos | 0 Comments

I spend around 80% of my day coding Web applications in Visual Studio 2012.  Typically, these applications are configured to run locally for testing using IIS Express and then (cross my fingers) are published to the server once all the bugs are ironed out.  This testing can be as simple as running the site and determining if everything looks right or as complicated as attaching to the IIS Express process and going through the code of the site step by step looking for a particular issue's cause. If you are anything like me, you do lots of viewing of the site you are developing...looking at every little CSS, HTML, route, action or JavaScript change.  In order to make my life a little easier, I use a relatively unknown Visual Studio extension called AttachTo.

AttachTo Installation

Seriously, this is one of my favorite Visual Studio extensions ever.  AttachTo allows me to attach to a running process of IIS Express, IIS, or NUnit with one click.  Previously, if I wanted to attach to a running process of IIS Express, I would have go to the TOOLS->Attach to process-> and then hunt for the process I wanted.  AttachTo makes it simple; click = attached.

To get AttachTo, go to TOOLS -> Extensions and Updates and search for "AttachTo" under the Online -> Visual Studio Gallery option.

Click the "Install" button (mine is already installed, so I have a green check mark where the install button would be), and that's it.  Well, sort of.  I also like to save clicks by moving the "Attach to IIS Express" menu item to the toolbar.  And that's totally easy too.

Adding AttachTo to the toolbar

To add the "Attach to IIS Express" menu item to the toolbar, go to TOOLS -> Customize. Then click on the Commands tab, choose the radio button for Toolbar and select Standard from the Toolbar dropdown menu.

Next click on the Add Command... button and under categories choose Tools. Then, from Commands, choose "cmdidWhutAttachToIISExpress".

From there I did two more things just to clean it up a bit.  I moved the item (using the Move Down button) to just before "Find in files".  Then I renamed it using the Modify Selection button. 

That was it.  Now anytime I want to attach to a running instance of IIS Express, I just click the little AttachTo icon on the toolbar and I'm all set.  No more hunting through a list of processes.  Time = saved.

Wrapping up

AttachTo saves me time every single day.  For more information about AttachTo, check out the details page in the Visual Studio Gallery or check out the project's repository on GitHub

Good luck to you!

28. February 2013 05:39
by Paul Apostolos
0 Comments

If you are not using Trello, you are doing it wrong

28. February 2013 05:39 by Paul Apostolos | 0 Comments

If I had a nickel for each todo or project management application I have tried...Well, let's just say, I'd have a crapload of nickels. Trello is the todo/task management application that is painfully easy and has just enough features to not be overwhelming but still be entirely useful.

Getting started with Trello

Trello makes it easy to get started by allowing you to either sign in with your Google account or sign up for a Trello account with only three required fields. From there you confirm your account with via a link sent to your email address and you are ready to start Trello(ing).

Creating your first Trello board

Trello uses the concept of a board (like a virtual bulletin board) as the home for any project (or task list). To create your first board, go to your Trello home screen where you should see a link to create a new board. Alternately, there is a "Boards" link in the top right corner that, when clicked, reveals a list of all your boards and from there you can choose the "New Board..." link.

The newly created board has three lists by default: To Do, Doing and Done.  A list is just a logical grouping of cards (tasks or whatever) and you are free to create, rename or delete any lists. 

The next step is to start adding items (Trello calls these cards) to the lists. In my example I am creating a website for a fictional ABC company (I probably should have gone all Wile E. Coyote and chosen Acme). I have added cards to the To Do list representing the tasks required to fulfill this project. 

As the tasks are in process I can move the to the Doing list and from there finally to the Done list.  But these lists could be defined in any way. For example, for this website, I could have created lists for: Planning, Design, Prototype, Coding, Testing and Go Live.

Lists and cards are meant to be flexible so flex them into your own personal style or workflow.

Sharing your Trello board

One of the coolest features of Trello boards is the ability to share them with other team members, family, friends or zombies. The only prerequsite is that the user have a Trello account. 

To add members to a Trello board, on the right side choose "Add members..." and just type the name (or email address) of the user you would like to add.

 

The user will receive an invitation to join the Trello board and that's it -> the collaboration magic will happen.

Accessing Trello from any device

Another thing that's great about Trello is it is accessible from (almost) any device. Trello should work in the browser of any recent smartphone or tablet.  And, Trello has Apps for Android, iOS and Windows Phone. I am using the iOS app and it just works.

Wrapping up

This post only scratches the surface of the features of Trello. Trello simple and useful for keeping track of projects and collaborating on task lists with teams, family members or friends.  So, whether you are planning a party for your daughter's sixteenth birthday and you don't want to let anything slip through the cracks, or building a website and need to collaborate with team members, Trello is a great choice. Form more information about Trello, visit the Trello site, or watch this video: 

Give it a try and let me know what you think.

Good luck to you!

19. February 2013 06:50
by Paul Apostolos
0 Comments

Don't live your life by default

19. February 2013 06:50 by Paul Apostolos | 0 Comments

On a recent podcast by Scott Hanselman, he said something very enlightening. I'm paraphrasing here, but essentially it was:

Teach your children to make life choices rather than just let life happen to them.

The phrase he used was, "Don't live your life by default." I know many people that have lived their life by default. In many instances I see unhappy folks that are stuck in dead-end jobs they don't enjoy but "it pays the bills". Letting life affect you instead of determining your own fate is a bad way to live.

In my early years, I was all about living my life by default. I took jobs that had little room for advancement and offered little enjoyment other than the minimal checks I received weekly. And, I believe, through high school, I lived my academic career by default; I only graduated because all my friends were smarties and being a dropout would have left me out of the group. But, when I started driving the car of life for myself things got much, much better. I made decisions that shaped my future instead of just letting things happen.  

Most people, me included, find change and life decisions difficult and avoid them for three prime reasons:

1. Fear - If you make the choice to change professions, you may fear that the money won't be there to support your family.  Or, you fear you may hate the new job and the current job is okay enough. To this I say, it's okay to be afraid, but don't let it cripple you.  There is an optimistic way to view everything. Just like the old joke - We have shit for dinner, but there is lots of it. So, even if the job doesn't work out, there will be a silver lining...The most obvious is, at least you gave it a shot.

2. Life disruption - Going back to school, for example, will likely be a huge life disruption. It was for me at least. Three days a week for four hours after work, plus homework and studying...And in my case for six years. But, you need to decide what is more important; making it home to watch Big Brother or changing your life for the better. It's your choice.

3. "I don't have the means" - I hear people give up before trying all the time and the excuse is often, "I don't have a..." What ever the ... is, (car, money, time, grades, skill...) they are all just excuses. If you REALLY wanted to go to MIT, complaining that you don't have the money is not going to get you there.  There is ALWAYS a way. That way may be tough, but there is a way.  Don't give up before you start.

So, the real question is, how do you teach someone to not live their life by default. My children are young, but I have already started instilling this edict into their tiny little brains. I have two overriding philosophies that I believe are leading them to a life != default.

1. Expect they can do something and help them when they can't - There is a first time for everything, making their own meals, cleaning up their toys, warming up the car, researching a school project, getting themselves dressed and taking care of their pets all seem simple, but if you start early, expecting these things can just be handled by your children, they will surprise you with how much they can actually accomplish on their own (without you even telling them what to do). This fosters confidence and builds character.  

2. Solicit feedback in the decisions you make about their lives - My boys play hockey, so I'll use that as an example...I ask them what they want to do for each season. Whether it is what team to tryout for, camps to go to or equipment to use...In my mind, that choice is ultimately theirs, and so I ask them to make those decisions.  Also, let's just say they are to be punished for something. It happens, right? Really, six and eleven are like oil and water in terms of brother ages. So if there is fighting or other disciplinary offenses, sometimes I'll ask what they would do if they were me. It allows them to have a say in the punishment, but it also teaches them not to just blanketly (<- might not be a word) accept others affecting their lives with out trying to have a say.

One more bit, we went video game free on those little guys more than a year ago and they have never been happier.

So, thanks Scott for putting a phrase to a philosophy I have been living for quite some time.

11. February 2013 06:11
by Paul Apostolos
2 Comments

Lenovo X1 Carbon Touch Review

11. February 2013 06:11 by Paul Apostolos | 2 Comments

I have been using my Lenovo X1 Carbon Touch for a few weeks now and I am loving it.  There were a few quirks but overall it is amazing.  So much so, that I have decided to replace my W530 (desktop replacement) laptop with the X1 Carbon Touch for my primary laptop. 

The road to replacement is not without speedbumps though.

Wireless driver

For some insane reason, the network driver for the Intel(R) Centrino(R) Advanced-N 6205 card is not close to the right version for the Carbon Touch. Mine, at least, came preinstalled with a version of the driver that was at least two versions out of date (I ordered it from Lenovo the day it came out but they shipped it with drivers that were two versions old...WTF?).  I did all the Windows updates and Lenovo system updates and nothing informed me that the driver was out of date.  I uncovered the issue when I was at a hotel working and the wireless would lose connection randomly to my (not the hotel's) wireless router. I figured there must be something wrong with my router, so I tried connecting directly to the hotel's wireless (I know that is bad idea from a security perspective, but I was just testing). After five minutes of a normal connection, the connection dropped with a yellow exclamation point and when I hovered over it, the tooltip read no access.  

Frustration ensued and I used my Google-Fu on my phone to find the answer.  After crawling the Lenovo forums, I found a few others who had similar problems and recommended I go directly to Intel to get the latest driver...So, I did.  On the Intel driver page, I chose Windows 8, 64 bit and  then "Intel® PROSet/Wireless Software and Drivers for IT Administrators" because, after all, I am an IT administrator. Then there was another gotcha...I chose the driver-only package (really I have never used the networking software they try to bundle with the drivers, I'm sure it's useful for someone, but not me) Wireless_15.5.7_De64.zip.  After unzipping and clicking on iProDifX.exe, I got a little spinning wheel then, nothing. However, when I checked the device manager, I saw the the driver had been updated to the new version.

Ever since, I haven't had a wireless problem; touch wood.

Storage

I detailed the hard drive space issues in a previous post (Reclaiming drive space on a Lenovo X1 Carbon Touch) but another storage tip is to buy the biggest and fastest SD card you can afford and insert that baby into the X1's SD slot. I added a 128 GB class 10 card and I use it to store my Dropbox folder. But, Dropbox will freak out if you try to assign its repository to a removable device. So, here's a trick.  

I downloaded and installed Dropbox.  I let it go through the installation and chose the default folder location for the Dropbox folder; C:\Users\paul\Dropbox. After the install is complete, I stopped the Dropbox service by right-clicking on the Dropbox icon in the system tray and choosing exit. After I stopped the service, I deleted the newly created Dropbox folder and made a new folder on the SD card called Dropbox. Since this was going to be the new destination for my Dropbox files, I made a symbolic link from the original Dropbox path to the SD Dropbox folder using this command (from an administrative command prompt):

mklink /d C:\Users\paul\Dropbox D:\Dropbox 

Then I restarted Dropbox and everything was kosher.  I have a 60GB in my Dropbox account, so I didn't want to load up the C:\ drive by just accepting the default location.

Docking and multiple monitors

No matter how amazing a laptop is, it is still a laptop. The last time I checked, laptop computers only have one monitor. I firmly believe the optimal number of monitors is seven, but so far I am getting by with just three.  Here's how. 

 

I use an HP 3005pr USB 3.0 Port Replicator and a an Accell DisplayPort to DualLink DVI adapter. The Accell adapter is to drive the Shimian 2560 X 1440 monitor I got on eBay for $350 (winning).  I know it is three plugs every day instead of the drop-in Mini-Dock of the Lenovo W530, but, it is a small price to pay to save my aching shoulders. The HP 3005 pr also drives a HP 2709m monitor via DisplayLink and so far it is just fine.  The photo above shows a video playing and I don't notice any issues with playback.

Keeping it real...clean

Anyone that knows me knows that I am a bit of a neat freak. And one of my major annoyances are fingerprints and smudges. The keyboard area and the case of the X1 Carbon Touch seem to collect smudges like those people on Hard Core Pawn collect gaudy jewelry. It's an epic struggle to keep the X1 clean, but I have found the the easiest way to handle it is to power down the machine and use a micro-fiber cloth. I just rub down the keyboard and case for a little bit and poof, it's totally clean.

Wrapping up

Like I said, I love my new laptop.  It has all the power I need and it only weighs 3.4 lbs.  If you get a X1 Carbon Touch and have any tips, leave them in the comments below.

Good luck to you!

1. February 2013 07:02
by Paul Apostolos
1 Comments

Reclaiming drive space on a Lenovo X1 Carbon Touch

1. February 2013 07:02 by Paul Apostolos | 1 Comments

The new Lenovo X1 Carbon Touch is really an amazing laptop.  However, I specified a 240 GB SSD as the hard drive when I customized it through the Lenovo website.  But here's the problem...

The first issue with advertised drive space has ALWAYS been an issue, but it is still worth mentioning.  Hard drives are measured in:

  • Megabyte (MB) = 1,024 kilobytes or 1,048,576 bytes (god help us if we are measuring drives in megabytes)
  • Gigabyte (GB) = 1,024 megabytes
  • Terabyte (TB) = 1,024 gigabytes

But here is the tricky part.  Because, apparently, our feeble minds can't grasp the base two numbering scheme of actual hard drive measurement, manufacturers  advertise hard drive sizes in common, easily decipherable base-ten notations so, for advertising purposes:

  • Megabyte = 1,000 kilobytes
  • Gigabyte = 1,000 megabytes
  • Terabyte = 1,000 gigabytes

That means for every gigabyte of advertised size, the consumer only realizes about 93%.  And it gets worse the larger the drive gets.  For one terabyte drives the difference between reported and usable is somewhere around 91%.

Back to my 240 GB SSD.  Using math...

240 GB = 240 * 1,000,000,000 = 240,000,000,000 bytes (in advertised base ten value)

240,000,000,000 / 1,024 = 234,375,000 kilobytes

234,375,000 / 1,024 = 228,881 megabytes

228,881 /1,024 = 223 gigabytes

So, right off the top I lost 17 gigabytes.  Dammit. However, that's not the real problem with the reported drive space.  

The real problem is that Lenovo decided to partition the drive and chew up space with reckless disregard for my precious, precious GBs. Check out this screenshot of the hard drive layout: 

So, wait, now my 240 GB drive is only 206 GB and somehow 30 GB of that is already used? I call bullshit on that.

Reclaiming the recovery drive space

All of these phantom partitions are there for recovery purposes.  That is, for those less than technical folks that need an easy way to pave their laptops to rid themselves of their monthly virus. So the decision I needed to make was, will I ever need these recovery partitions? I figured what's the harm...So I set out to create the recovery drive.  

I needed a USB drive of at least 16 GB to use for the new recovery drive target. I didn't want to use one of my good USB 3.0 drives though because this drive was basically just going to sit in a drawer forever, so I grabbed a crappy, slow drive I got as a give away at //Build two years ago.

I then hit the start button and typed "Recovery".  From there, I clicked on settings in the right side of the screen and chose Recovery.

After choosing recovery, I was taken to the Advanced recovery tools control panel applet. I then selected "Create a recovery drive".

I then stepped through the wizard to create my recovery drive. Which was like nearly every wizard I have ever seen in my life with the exception of this final screen:

Wait, a "link" to delete the recovery partition? Not a button?  Anyway, I clicked than and clicked yes to confirm the delete and voilà! 

Okay, so the "Recovery" partition is gone, now what about that "OEM" partition?  Normally, I would be able to right click on the partition and choose delete volume, BUT NO.  That's not available.  There's more than one way to skin this cat though.

Removing the OEM partition

To rip out that OEM partition and reclaim that precious 7 GB of space I had to go into (mildly) advanced mode.  I opened an administrative command prompt and typed DISKPART to access the Windows disk partition tool.

From there I entered the following commands: 

  • select disk 0
  • list partition
  • select partition 6   (the OEM partition)
  • delete partition override

Now when close the command window and look in disk management I see 7.00 GB Unallocated.  

I right clicked on the C: drive and chose "Extend Volume..."

I was then presented with the "Extend Volume Wizard".  I basically did my usual next, next, next thing through that wizard and the magic happened.

Now in disk management I have: 

Wrapping up

I'm still not happy with the 1 GB partition at the front of the drive but, because of the drive layout, I'm not sure how to reclaim that without using Acronis or some other disk imaging program.  And, frankly, I just want to start using my new machine.

Hopefully, if you find yourself in a similar situation this will help you pull through the drama that is reclaiming your drive space.

Good luck to you!

28. January 2013 04:51
by Paul Apostolos
0 Comments

Keeping up with technology through podcasts, videos, twitter and Instapaper

28. January 2013 04:51 by Paul Apostolos | 0 Comments

I am one of the luckiest guys in the world. My family is amazing, my children make me so proud and my job is not really a job at all; it's just what I would be doing in my spare time if I was forced to have a completely different occupation (for example botanist).

Honestly, I think the only reason people pay me to do my job is to set the priority of my projects and thereby prevent me from spending hours creating data analysis programs for the GPS data in my training watch or developing a way to control my Raspberry Pi XBMC using my iPhone.

To keep up on all of the many technology trends, I use a few different strategies.

Podcasts

No matter what technology knowledge thirst I have, there is usually a podcast to quench it.  I spend a lot of time running or in the car and it is usually the perfect amount of time for a podcast episode. Here are my favorites (in order of amazingness):

  • Hanselminutes - Scott Hanselman's weekly 30 - 50 minute podcast.  Scott usually covers programming languages and trends but he also discusses technology (such as 3-D printing), the plight of the remote worker and the work/life balance.
  • .NET Rocks! - Carl Franklin and Richard Campbell host a great podcast about all things .NET.  In addition, they occasionally do a "geek out" special about a topic outside of the .NET world.  My favorite of these has been the Nuclear Power Geek Out.
  • This Developer's Life - Scott Hanselman and Rob Conery put perspective on programmer's lives by having programmers share their stories on different topics such as workplace drama, hubris and success.
  • Run As Radio - Richard Campbell hosts this podcast about IT issues usually in the Microsoft stack. 
  • Herding Code - The Hearding Code guys (K. Scott Allen, Jon Galloway, Kevin Dente, Scott Koon) showcase programming technologies using a roundtable format where many hosts interview a guest (or guests).

Videos

Sometimes hearing about programming and technology is not enough to actually learn about programming and technology.  Thankfully, there are a bevy of video resources available.  Here is my can't-miss list (once again in order of awesomeness):

  • TekPub (paid subscription) - Rob Conery's screencast service covers topics such as Knockout, Backbone, C#, databases and Ruby.  The quality of these screencasts really separates TekPub from other screencasts.  They are fully produced, tightly edited and always educational.
  • Channel 9 - Microsoft's video channel covering all things Microsoft.  There is a lot of content on Channel 9 that doesn't interest me, but occasionally there are some real gems and for those, I keep coming back.
  • Windows Weekly - Every week Mary Jo Foley, Paul Thurrott and Leo Laporte rundown everything Microsoft.  (also available as an audio podcast)
  • This Week in Computer Hardware - Ryan Shrout and Patrick Norton dive deep into desktop computer hardware.  Motherboards, CPUs, memory and video cards are just the tip of the iceberg here. 
  • Tekzilla - Veronica Belmont, Patrick Norton and Robert Heron answer viewer questions and review new products twice a week.
  • Pluralsight (paid subscription) - Screencasts from experts on a variety of topics including .NET, iOS, JavaScript and a whole lot more.  Some of my favorite authors on Pluralsight include John Papa, Julie Lerman and K. Scott Allen.

Twitter

My following list on twitter reads like a who's who in programming. I find many pearls in my twitter stream from all of the folks I follow, but I never skip tweets from this list:

Instapaper

As I come across something on twitter, I save the link to Instapaper to read later.  Instapaper is a web application that stores all of my "I want to read this but I don't have time right now" pages.  Then when I have time (in an airport, the bathroom and right before bed usually) I go to my Instapaper app on my phone and plow through all the greatness.

Instapaper also has a feature to email your daily "read later" stories (full text) to your Kindle. Very cool.

What else?

I'd really like to hear about how you keep up with technology in your off hours.  Use the comments below to leave your suggestions.

Good luck to you!

25. January 2013 05:46
by Paul Apostolos
2 Comments

Migrate On-Premise TFS Solutions to TFS Service Online

25. January 2013 05:46 by Paul Apostolos | 2 Comments

In the past ten years I have used several different source control solutions including Visual Source Safe, Source Gear Vault, Subversion and finally Team Foundation Server (TFS). The issue with TFS, at least for me, is it is installed on premise. The problem with an on-premise installation is I need to be on the network with the TFS server in order to use it. And, by "on the network" I mean at the client location or attached remotely via VPN. I have yet to have a client willing to open up their firewall for direct TFS access, although I know that is an option too.  So, when I attended //BUILD this year I was excited to learn about new service from Microsoft that could help ease my TFS access woes.

The new TFS service is TFS 2012 but hosted on Azure. I love it and I could spend hours writing about how to implement, use and configure it; that's not what this post is about. I want to focus on how to get the source code in the current source control system (whatever it is) into the new TFS Service. 

Sample project

To help with the demo, I created a sample project.  It's simply an MVC site, a test project and a library. All of the projects and files are under the same solution folder and are currently hosted in an on-premise TFS 2010 server project collection. 

I always include a folder called "Referenced Assemblies" for DLL references that are essential to the solution and would be required by other developers on the team. This way, the dev only needs to get the entire solution and magically all the reference pointers are working.

So, now that the solution is in local source control, it needs to be prepped for moving it to TFS Service.  

Prepare for the migration

To begin the migration, I look through the solution projects and files to be sure no other team members have pending changes. Then, I do a "get latest" on the entire solution resolving any conflicts. From there, I navigate to the solution root. I think easiest way to do this is to click on the "Local Path" link in the Visual Studio Source Code Explorer:

 

I'm now all done with Visual Studio, so say I'll say my goodbyes for now and close it. 

Clean the solution

For this part I am going to use CleanProject (a Visual Studio extension). The CleanProject extension is really sweet, it takes a solution folder and cleans all the unneeded items such as bin, obj and ReSharper folders AND most importantly of all it removes all the source control bindings. Don't worry, it doesn't touch the original folder, instead it creates a copy and does all the magic on that copy.

To use CleanProject, I navigate to the folder one level above the solution root; the solution's parent folder. 

From there I just right click on the solution folder and choose "Clean, Remove Source Bindings and Zip Solution" which will do exactly that: 

When it finishes I have a zip file of all the cleaned contents of my original solution folder: 

There are many command line options for CleanProject. There's even one to just copy the files instead of creating a zip file, but, for simplicity, I am just using the context menu.  For more information on the command line options, visit the CleanProject site on CodePlex.

Move the solution to a new location

Now that the solution is cleaned and zipped into a nice little package, I need to find a new home for it on my hard drive.  I created a folder called CloudTFSService and I extracted the folder contents to that location. Here is a trick that I didn't see documented anywhere. Once I've extract the files, those files retain their attributes from the original location;namely, the Read-only attribute.  I need to remove those attributes before adding the solution to the new TFS Service.  To do this, I just right click on the new solution root, choose "Properties", uncheck the "Read-only" box and apply the changes to all subfolders and files. 

Okay, now I'm all set to open my solution and add it to the TFS Service.

Add the solution to TFS Service

Before I go any further, I'll need to sign into my TFS Service account and add a new team project to hold the new solution.

Once the new project is created, I open Visual Studio and choose "Connect to Team Foundation Server..." which is either on the start screen or under the TEAM menu item.

From here I can add a new TFS server and instead of pointing to a local instance, I'll point to my TFS Service instance.  

The connect dialog then asks me to provide my Windows Live ID credentials to connect and presents me with a list of projects. I then choose the project created in the previous step.

Next, I'll open the solution from the FILE menu by choosing Open -> Project/Solution. 

Okay, I'm almost done. Now that I have the solution open, I'd better make sure it still builds! When I get a successful build, I then, right on the solution in Solution Explorer and choose Add Solution to Source Control... 

Now here is another trick. For projects that only have one (and will only have one) solution, I delete the contents of the "Type the name for the solution folder" textbox.  This creates the solution directly under the project root instead of creating another subfolder to house the solution.  If in this case I was to leave the just how it is, my solution file would reside in  $/SampleProject/SampleProject/SampleProject.sln instead of, simply, $/SampleProject/SampleProject.sln. Don't get me wrong, that convention is nice for projects that will contain multiple versions or many solutions, but this one is more simple than that. 

Now, remember how I said I like to create a "ReferencedAssemblies" folder? Well, that folder has not been added to source control. I want to do that so all team members are working on the same versions of the references. It's pretty easy to do using the Source Code Explorer in Visual Studio.  

To add the folder, I open Source Code Explorer, right click in the solution folder pane and choose "Add Items to Folder..." 

Now I'll select the "ReferencedAssemblies" folder and choose Next (not finish). Then I make sure to INCLUDE any DLLs I want to be added to source control. 

Once I have included the DLLs, I'll be able to click finish and the ReferencedAssemblies folder will appear in the list of solution folders. 

So, what's left? Oh, yeah, I need to actually check in the solution to upload the files to source control. To check in the solution I right click on the solution in Solution Explorer and choose Check In... 

That's it! I'm done.

Wrapping up

In this post I demonstrated how to migrate an exiting source-controlled solution to the new TFS Service.  Hopefully you will find a few useful tidbits in here to help you migrate your solutions.

Good luck and let me know how it all works out for you!

23. January 2013 05:56
by Paul Apostolos
0 Comments

Synchronize Visual Studio Settings Across Machines with Dropbox

23. January 2013 05:56 by Paul Apostolos | 0 Comments

I live in Visual Studio 2012 (VS2012)...Well, not literally, but I do spend lots of my waking moments in front of a computer and that computer always has at least one instance of Visual Studio running. The important thing to note from the last sentence is not that I am a huge nerd and I need to make time for more popular forms of fun, but that I said "a computer." That's the rub, it's not always the same computer. However, the experience of Visual Studio, and for that matter SQL Server Management Studio 2012 (after all it's just Visual Studio 2010 really), are the same across all of my many, many machines thanks to this technique.

The first question I always get (usually from my wife) is "why do you have many, many machines?" Let rundown the machines and reasons:

  1. Home office desktop computer -  Four monitors, great audio system, six cores and 24GB of ram all in a place where I can just plop my but down at any point and start working. No docking, no connectors, no wrestling with display adapters that are limited to just three displays (I'm looking at you Lenovo W530). Seriously, for any significant programming session, a minimum of four monitors are required.  Actually, seven is probably the magic number, but four is a good first step.
  2. Everyday laptop -  Lenovo W530 with three SSDs, 20GB of ram and the best laptop keyboard ever built. The main issue with this monster is weight.  I think my right shoulder is now 1.2 inches lower than my left from carrying the W530 in my backpack on one shoulder for a year.
  3. Travel laptop -  Macbook Air 13" running Windows 8 in BootCamp.  It only weighs three pounds and is nearly as effective as the W530 at less than half the weight. And, I get a strange satisfaction when people say, "Oh, you are using a Mac." and I reply, "Yeah, I can go both ways."
  4. 12 virtual machines - For every client I have, if needed, I create a virtual machine development environment to mimic their production environment as closely as possible.  This way if I need to test an integration for example with MAS90 or QuickBooks, I'm all set.

With all of these different "machines" I used to go crazy trying to set things up exactly the same for both Visual Studio 2012 and SQL Server Management Studio 2012.  Then I would get frustrated when I would decide to change a setting on my W530 in the middle of the day, only to go home and have to make the same change again. Thankfully, this use case did not go without notice by the members of the Visual Studio team. Now I can synchronize all my settings for both programs across all my machines and it's really easy. So, let's get started:

In order to use this option effectively, I suggest (if you don't already have) you get yourself an account with Dropbox, SkyDrive, Google Drive or some other online storage service.  They all offer a free plan that would be more than enough to implement this project.  However, as my grandmother always says, "If you aren't signed up for at least 50GB of online storage, you are just doing it wrong." Once your shared storage is all set up, you can proceed to the next step. And, if you have at least 50GB, you can rest easy at night knowing my grandmother thinks you are doing it right.

To begin sharing your settings to all of your machines, you'll need to export your favorite machine's settings to a folder under your online storage root. To export your settings open VS2012 and go to TOOLS (Ha! all caps) -> Import and Export Settings... 

From there choose Export selected environment settings. 

Next, you will see a list of settings so you can choose exactly which settings you want to include in this master settings file. I just accepted the default (all) and clicked Next. 

The next screen is where you select the folder to save your settings file.  Be sure to choose a folder that is accessible by all of your machines. For mine, I created a folder under my Dropbox root called VisualStudioSettings (remember when we couldn't have spaces in file names? me too and I can't shake that habit). Don't forget to click Finish. 

Done! Well, not really, but done with the export at least.  The next step will be to tell Visual Studio on all your machines (including the one you used to do the export) to always use the settings from that file.  To do this go to TOOLS -> Options

Under the Environment section, click on the Import and Export Settings link. Then in the right pane, check the box "Use team settings file:" and browse to the path of the file you just exported. It is important to use your online storage service so changes to the file on one computer are shared to the others. 

That's it! Just repeat the last step for all your computers and all of your Visual Studio settings will be shared across all of your machines. Now, here's the bonus...The same exact procedure works for Visual Studio 2010 and SQL Server Management Studio 2012. 

I'm still looking for the holy grail, which for me would include a way to also synchronize extensions, such as (some of my favorites) AttachTo, Indent Guides, Visual Studio 2012 Color Theme Editor, Productivity Power Tools, and the AMAZING, AMAZING, AMAZING Web Essentials 2012.  

Good luck and let me know how it all works out for you!