.Net MVC Action Method for Downloading Files on Shared Network Drive

In a recent ASP.Net MVC3 project, I had a requirement to allow for uploading of any file to a shared network drive and then, on the flip side, downloading of that file directly through the browser (this was an intranet application).

I won’t get into the details of uploading a file to a network drive or the permission configuration required to do so. There are many resources available online that outline how to do that but in short this is the process:

  1. User clicks “Upload File” link and is presented with a form to select a file
  2. User selects file and clicks “Upload” button
  3. The file is Uploaded to a shared network drive
  4. A record of that file, including the original name and network path, is stored in the database in the Attachment table with a unique id (in my case, an integer)

The tricky part came when I needed to create a cross-browser html link to download that file via any browser. In Internet Explorer you can simply do something like this:

<a href="file:///ServerName//Folder/filename.ext">Download File</a>

see here

…and yes, that works beautifully in IE. However, no luck in Chrome or Firefox (and I suspect various other browsers) due to a security limitation.

The way around this is to create an MVC  action method that serves the entire contents of the file as a byte array. Below is the code that I used to do this (sparing any error handling):

public FileResult Download(int id) // id is the id of the file stored in the database
{
    //[1] get the filepath and file name from the database using Linq to Entities
    Attachment attachment = datacontext.Attachments.Where(x => x.attach_id == id).FirstOrDefault();
    string strFilePath = attachment.FilePathAndNameOnServer_Generated;
    string strFileName = attachment.file_name;
            
    //[2] read the file into a FielStream and return it as a byte array
    using (FileStream fileStream = System.IO.File.Open(strFilePath, FileMode.Open, FileAccess.Read))
    {
        byte[] returnBytes;
        returnBytes = new byte[fileStream.Length];
        fileStream.Read(returnBytes, 0, returnBytes.Length);      
        return File(returnBytes, System.Net.Mime.MediaTypeNames.Application.Octet, strFileName);
    }
}

And your html link (which should work in all browsers) would now look like this:

<a href="/Attachments/Download/123">Download File</a>

Force Password Change – Buddypress Plugin

Download from WordPress.org

What does this plugin do?

This plugin adds a checkbox option to the “edit user” screen in the WordPress admin that, when checked, will force a user to change their password the next time they log into their account. The end user’s “change of password” experience is very simple and clean. When they log in they will be immediately presented with a modal dialog that prompts them for a new password and MUST successfully change their password prior to continuing to use the site.

Instructions


Installation

  • Download the zipped folder from the link above and extract it.
  • Place the extracted bp-force-password-change folder in your wp-content/plugins directory. You should end up with up wp-content/plugins/bp-force-password-change/.
  • On the Plugin page in your WordPress Administration area, activate the BP Force Password Change plugin.

Forcing User to Change Password

Once the plugin is installed, navigate to a user’s account information within the WordPress Admin Panel and you will see a new ceckbox just beneath the text boxes within the “New Password” section. Check the box and update the user’s account to force the user to change their password the next time they visit the site.

Screen-shot-2013-03-12-at-2.32.50-AM

What the User Will See

Once any user with the “force password change” option turned on logs into the site they will immediately see a modal window requiring them to change their password. The user will not be able to navigate the site until they change their password.

Screen shot 2013-03-12 at 2.02.25 AM

Note that this plugin is strictly meant for Buddypress and does not function in WordPress.

Weather Spider – WordPress Plugin

Download from WordPress.org

What does this plugin do?

Use this plugin in your WordPress site to place a weather forecast for any US location in a Page, Post, or within a sidebar.

Instructions


Installation

  • Download and unarchive the plugin folder.
  • Place the uncompressed weatherspider folder in your wp-content/plugins directory. You should end up with up wp-content/plugins/weatherspider/.
  • On the Plugin page in your WordPress Administration area, activate the WeatherSpider plugin.

WeatherBug.com API Key

In order to use this plugin, you must first obtain an API key from WeatherBug.com.

  1. Go to: http://developer.weatherbug.com/
  2. Register for an account
  3. Apply for an API key (be sure to get the REST key – not the GEO key)
  4. Enter your API key in the field above and press the “Save Settings” button

Caching Weather Data

By default, the weather feed information for each zip code will be cached for 15 minutes. This prevents the widget from making uneccesary calls to WeatherBug.com for weather. You can turn caching off in the settings panel (though it is not recommended). You can also clear the cache manually by clicking the “Clear Cache” button.


Displaying in Pages and Posts

To display a weather forecast in a page or a post, you can use the [weatherspider] shortcode. The shortcode has four options, listed below.

  • zip: The zip code of the location you want to show the forecasft for (default=90210).
  • size:The size of the forecast display. Options are:
    • sm: 3 Day forecast, 200px wide (default)
    • med: 4 Day forecast, 250px wide
    • lg: 5 Day forecast, 300px wide
  • showCurrent: Show the current temperature in the display. Options are: true, false (default=true)
  • showForecast: Show the forecast in the display. Options are: true, false (default=true)

Example:

[weatherspider zip=”02842″ size=”lg” showCurrent=”false” showForecast=”true”]

The Widget

If your theme is widget-enabled, you can add the WeatherSpider widget to any sidebar. Configuration is self-explanatory. Note that you can add multiple instances of the widget in your sidebar.

Download from WordPress.org

Charlie Sheen Quotes – WordPress Plugin

Download from WordPress.org

What does this plugin do?

Winning.

Install this plugin and four things will happen:

  1. You will replace the boring Hello Dolly quote in the admin section of WordPress with a much less boring random quote from Charlie Sheen.
  2. You will have a widget that you can add to any sidebar that displays a quote from charlie sheen.
  3. You will have the ability to add a random quote from Charlie Sheen to any post by using the short code [charlie sheen]
  4. Your blog will have Tiger blood and Adonis DNA.

Adding a Custom Directory to Razor View Engine’s Partial View Locations in ASP.Net MVC3

This article describes how to add a sub directory to the list of locations the ASP.Net MVC3 Razor view engine checks when searching for a partial view. Why would you want to do this? The answer is simply for the sake of organizing your file structure within the default “Views” directory that ASP.Net MVC3 creates for you.

The way you render a partial view in Razor is by making the following call:

@Html.Partial("{ViewName}")

When you make this call, MVC3’s default Razor view engine looks for the view you specified in the following default locations:

~/Views/{1}/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.cshtml
~/Views/Shared/{0}.vbhtml

Note that {0} is the view name you specified and {1} is the Controller name (if specified).

If it does not find a view matching the name you specified in any of those directories, guess what? Yup, Yellow Screen of Death.

Well what if you wanted to store all of your partial views in a “Partials” directory within the “Views/Shared” folder? You could do this without a problem as long as you called your partial views from now on by prepending the view name with “Partials/”, like so:

@Html.Partial("Partials/{ViewName}")

This is of course perfectly OK, but what if you move your partial views in the future? You would then have to do a search and replace of code throughout your application.

A Better solution:

First, create your own view engine as a class in your Models directory, inheriting from the “RazorViewEngine” base class, store your view locations in a string array, and add your locations to the base PartialViewLocationFormats in your constructor like so:

public class MyViewEngine : RazorViewEngine
{

    private static string[] NewPartialViewFormats = new[] {
        "~/Views/{1}/Partials/{0}.cshtml",
        "~/Views/Shared/Partials/{0}.cshtml"
    };

    public MyViewEngine ()
    {
        base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(NewPartialViewFormats).ToArray();
    }

}

Then, in your global.asax file, in you Application_Start() method, add your view engine to the applications ViewEngines collection like so:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ViewEngines.Engines.Add(new MyViewEngine());
}

Now, when you call a partial view in Razor with @Html.Partial(…), the locations you designated will be searched in addition to the default locations.

Standards Compliant, Accessible Tabs Using HTML, CSS, and 4 Tiny Images

Download Source Code

View a Demo

Horizontal navigation menus are one of the (if not THE) most common user interface elements used across the web. They provide an easy way for a user to both navigate a web site as well as quickly determine, at a glance, what section of the web site they are currently on.

My Requirements

  • Must degrade gracefully when style sheets are turned off
  • Must be fully accessible
  • Must validate to W3C standard
  • Must be light-weight and simple
  • Must provide ability to change colors without having to modify images
  • Must be able to turn a tab on by simply adding a class

The code below generates a customizable horizontal, tabbed menu with a set height of 75 pixels. If you want to change the height of the menu you will have to create new images and also modify the height settings in the CSS code. With that in mind, I have included the Photoshop file I used to create the menu in the zipped archive for you to reference.

I have tested this in Firefox (2,3,3.5), IE7, IE8, Safari, Opera, and Chrome and it looks good across all of them (if you experience an issue in another browser, please let me know by commenting on this post).

The Plan

The HTML Code

<ul id="LATabs">
	<li class="current_page_item"><a href="" title="Home"><span class="tLeft"></span><span class="tMid">Home</span><span class="tRight"></span></a></li>
	<li><a href="" title="Menu Item 1"><span class="tLeft"></span><span class="tMid">Menu Item 1</span><span class="tRight"></span></a></li>
	<li><a href="" title="Menu Item 2"><span class="tLeft"></span><span class="tMid">Menu Item 2</span><span class="tRight"></span></a></li>
</ul>

The CSS Code

ul#LATabs{
	float:left;
	margin: 0;
	padding:0;
	list-style-type: none;
	width:100%;
	height:75px;
	background: #b71e1a url(bg.gif) center center repeat-x;
	font: 24px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
	color: #fff;
	}

ul#LATabs li{
	float:left;
	padding: 0;
	height: 75px;
	margin: 0 10px;
	}

ul#LATabs a{color:#fff;text-decoration: none;cursor: pointer;}
ul#LATabs a:hover{color: #e3e3e3;}

ul#LATabs .current_page_item a{color: #b71e1a;}
ul#LATabs .current_page_item a:hover{color: #b71e1a;}

ul#LATabs span{float:left;height: 75px;}
ul#LATabs .tLeft, ul#LATabs .tRight{width:8px;}
ul#LATabs .tMid{padding: 23px 15px 0px 15px;}


ul#LATabs .current_page_item .tLeft{
	background-image: url(tab_01.png);
	background-position: top left;
	background-repeat: no-repeat;
}
ul#LATabs .current_page_item .tMid{
	background-image: url(tab_02.png);
	background-position: top left;
	background-repeat: repeat-x;
}
ul#LATabs .current_page_item .tRight{
	background-image: url(tab_03.png);
	background-position: top left;
	background-repeat: no-repeat;
}

The 4 Tiny Images

bg.gif bg.gif bg.gif bg.gif

The End Result

Download Source Code

View a Demo

Burning a DVD on an iMac

This one drove me absolutely nuts….

I recently needed to backup a folder on my iMac onto a DVD-R disc. The problem was, every time I inserted a blank DVD-R disc into my iMac Super Drive, the Disk Utility application would pop up and only give me options to burn ISO images onto the disc. No option to just burn regular files. When I opened up my Finder window, the drive wouldn’t show up there either.

Well after about 2 hours of digging I found the solution…and it’s about as dumb as it gets.

1) Click the little apple icon at the top left of your screen
2) Click “System Preferences”
3) In the “Hardware” section, click “CDs & DVDs
4) Set the “When you insert a blank DVD:” option to “Ask What to Do”

Now eject your disc (if you are having trouble ejecting your disc…don’t worry…I did too…go into your applications folder in your Finder window, click “Utilities”, open up “Disk Utility”, and eject the disc from there).

When you re-insert your disc, your Mac will ask you what you want to do. Click “Open Finder”. At this point, my Finder window did NOT automatically open. If yours doesn’t either, just open Finder the old fashioned way. Once you open your Finder window you will now see your blank DVD listed in the “Places” section. Once it’s there, simply drag the files you want to burn right onto the drive.

When you’re done selecting your files, click on the little Danger symbol next to the DVD-R drive in the Finder window, follow the prompts to burn your disc, and your done!

Google Charts

Need a quick way to add a line, bar, pie, venn, scatter, or radar chart or even a world map, meter, or QR code to your web page without having to do anything messy like installing a third party app on your server or including a javascript library?

Check out Google Charts.

This very easy to use and powerful API allows you to include an assortment of charts on your web site. All you need to do is set the src of an <img> tag to the URL for the Google Chart API and then add a few parameters to the URL string. Once everything is set, voila, the chart appears.

Sample Code

States I Have Visited

<div style="text-align:center;"><img src="http://chart.apis.google.com/chart?chs=440x220&amp;chd=s:_&amp;cht=t&amp;chtm=usa&amp;chf=bg,s,EAF7FE&amp;chco=FFFFFF,0000FF&amp;chld=RIMACTNYVTNHMEILCAFLPAGAALNVLASD&amp;chd=t:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" border="1" alt="" width="440" alt="States I Have Visited" /></div>
<div style="text-align:center;"><img src="http://chart.apis.google.com/chart?chs=440x200&amp;cht=p3&amp;chco=0000FF&amp;chd=t:16,24&amp;chl=Visited|Remaining&amp;chdlp=t" border="1" alt="" width="440" align="center" alt="Percentage of States I Have Visited" /></div></blockquote>

Web Site Project Life Cycle – Diagram and Supporting Documents

Web Project Life Cycle

Web Project Process Diagram

Working on different web teams within various organizations throughout the years, a common issue that I’ve often encountered was the lack of process when it came to designing and developing web sites. Virtually everywhere that I have worked there has not been a standard, documented method or strategy that the “web team” could use to guide a project from start to completion. Thankfully, in one of my most recent roles, my team and I were tasked with doing just that, creating a process that made sense and that we could all use collectively to get our work done.

We called our process “The 4 D’s”

  1. Definition
  2. Design
  3. Development
  4. Deployment
  5. Support (OK…not a D…but you get the picture)

The documents attached to this post are what we ultimately ended up with. A lot of what we created is based on common methods and best practices in project management and software development….so don’t expect any of this to be ground breaking stuff. We found that having a process like this in place kept projects well organized, kept all team members fully informed of client expectations, and minimized common issues like scope-creep, missed deadlines, blown budgets, and dissatisfied clients. Every member of the web team as well as our external clients were involved in creating this process, so at the end of the day everyone was comfortable with working within it.

Note that it is crucial to work very closely with your clients in the beginning stages of the development process (Definition/Design). The client should expect to deliver and sign off on clear business requirements (a member of the web team would work with the client to create the necessary documents) and also be readily available to answer any questions and sign off on milestones throughout the process. As development of the web site/application progresses, the client should be given periodic status updates. The bottom line is to keep an open line of communication between the web team and the client. In doing so, the chances of delivering a successful product will be greatly improved.

This process is intended as a general guideline in developing web sites and applications and is not meant to be followed rigidly. The scope and complexity of every project is different and as is the case, the degree of process/documentation required should vary depending on the project. Also, some clients require more visibility into projects than others so the level of detail in documentation  may vary as well.

In short, don’t box yourself in with too much process, do what makes sense for your projects, your clients, and your organization.

Adding a Flickr Feed to your Site with jQuery

Introduction

This post outlines a quick and easy way to display your Flickr photostream on your personal web site using javascript (no server-side programming necessary). We will use JQuery as the vehicle for making the javascript call to Flickr. The feed will be returned in JSON (JavaScript Object Notation) format and then displayed on the site using simple javascript.

Don’t understand all of this? Don’t worry…just copy and paste the stuff below and everything will be just fine.

Step 1: Find Your Feed

Log into your Flickr account, click on your Photostream main page, and click on the RSS Feed button at the bottom of the page (orange icon). The url that you get to should look like this:

http://api.flickr.com/services/feeds/photos_public.gne?id=xxxxxxxx@N08&lang=en-us&format=rss_200

Important: You must change the format of the feed to JSON. Simply change the end of the link from “=rss_200″ to “=json&jsoncallback=?”. Your new link will now look like this:

http://api.flickr.com/services/feeds/photos_public.gne?id=xxxxxxxx@N08&lang=en-us&format=json&jsoncallback=?

Step 2: Add the Javascript

Add this code between the <HEAD> tags in your site. Be sure to download JQuery first and put it in your /js/ file directory! Also, be sure to replace  “—YOUR FEED URL HERE—” with your own personal feed link that you obtained in Step 1.

$(document).ready(function() {
	//Flickr Integration
	$.getJSON("---YOUR FEED URL HERE---", function(data){
		$.each(data.items, function(i,item){
			if(i<=5){
				$("<img/>").attr("src", item.media.m).appendTo("#FlickrImages ul")
				.wrap("<li><a href='" + item.link + "' target='_blank' title='Flickr'></a></li>");
			}
		});
	});
						
});

Step 3: Add the Feed to your Page

Add this between the <BODY> tags of your document where you would like your Flickr Images to Reside:

<div id="FlickrImages"><ul></ul></div>

Step 4: Add some CSS

Add this code between the <HEAD> tags of your document.

<style type="text/css">
	#FlickrImages{
		margin-bottom:1em;
		float:left;
	}

	#FlickrImages li{
		float:left;
		padding:8px;
		background-color: #eee;
		margin: 0 5px 5px 0;
	}

	#FlickrImages img{
		width:120px;
		height:80px;
	}
</style>

That’s It!

To see a demo of this, just look at the footer of this web site. The images at the bottom right are from my Flickr account.