I am developing the UI for a .NET MVC application that will require international localization of all content in the near future.   I am very familiar with .NET in general but have never had a project that required such a significant focus on international accessibility.  

The projected is initially being done in English.  What measures should I take at this point to make it easier to implement localization in the future? 

You are developing ASP.Net MVC application, are you? Other answers seem to be specific to desktop applications. Let me capture common things:

Locale detection

It is quite important that your application detect user's locale correctly. In desktop application, CultureInfo.CurrentCulture holds preferred formatting locale (the one that should be used to format numbers, dates, currencies, etc.) whereas CultureInfo.CurrentUICulture holds preferred User Interface locale (the one that should be used to display localized messages). For web applications, you should set both cultures to auto (to automatically detect locale from AcceptLanguage header) unless you want to implement some fancy locale detection workflow (i.e. want to support changing language on demand).

Externalize strings

All strings should come from resources, that is Resx files. In Winforms App it is easily achievable by setting form Localizable property to true. You would also need to manually (unfortunately) externalize strings that come from your models. It is also relatively simple. In Asp.Net you would need to externalize everything manually...

Layouts

You definitely need to allow for string expansion. In Winforms world it is achievable via TableLayoutPanel which should be used to make sure that layout will adjust automatically to accommodate longer text. In web world, you are a bit out of luck. You might need to implement CSS Localization Mechanism - a way to modify (override) CSS definitions. This would allow Localization folks to modify style issues on demand. Make sure that each HTML element in rendered page has unique id - it will allow to target it precisely.

Culture specific issues

Avoid using graphics, colors and sounds that might be specific for western culture. If you really need it, please provide means of Localization. Avoid direction-sensitive graphics (as this would be a problem when you try to localize to say Arabic or Hebrew). Also, do not assume that whole world is using the same numbers (i.e. not true for Arabic).

ToString() and Parse()

Be sure to always pass CultureInfo when calling ToString() unless it is not supported. That way you are commenting your intents. For example: if you are using some number internally and for some reason need to convert it to string use: 

int i = 42;
var s = i.ToString(CultureInfo.InvariantCulture);


For numbers that are going to be displayed to user use:

var s = i.ToString(CultureInfo.CurrentCulture); // formatting culture used


The same applies to Parse(), TryParse() and even ParseExact() - some nasty bugs could be introduced without proper use of CultureInfo. That is because some poor soul in Microsoft, full of good intentions decided that it is a good idea to treat CultureInfo.CurrentCulture as default one (it would be used if you don't pass anything) - after all when somebody is using ToString() he/she want to display it to user, right? Turn out it is not always the case - for example try to store your application version number in database and then convert it to instance of Version class. Good luck.

Dates and time zones

Be sure to always store and instantiate DateTime in UTC (use DateTime.UtcNow instead DateTime.Now). Convert it to local time in local format upon displaying:

DateTime now = DateTime.UtcNow;
var s = now.ToLocalTime().ToString(CultureInfo.CurrentCulture);


If you need to send emails with time reference in body, be sure to include time zone information - include both UTC offset and list of cities:

DateTime someDate; // i.e. from database
var formattedDate = String.Format("{0} {1}", 
             someDate.ToLocaleTime().ToString(CultureInfo.CurrentCulture),
             TimeZoneInfo.Local.DisplayName);


Compound messages

You already have been warned not to concatenate strings. Instead you would probably use String.Format() as shown above. However, I must state that you should minimize use of compound messages. That is just because target grammar rules are quite commonly different, so translators might need not only to re-order the sentence (this would be resolved by using placeholders and String.Format()), but translate the whole sentence in different way based on what will be substituted. Let me give you some examples:

// Multiple plural forms
English: 4 viruses found.
Polish: Znaleziono 4 wirusy. **OR** Znaleziono 5 wirusów.

// Conjugation
English: Program encountered incorrect character | Application encountered incorrect character.
Polish: Program napotkał nieznaną literę | Aplikacja napotkała nieznaną literę.


Other concatenation issues

Concatenation is not restricted to strings. Avoid laying out controls together, say:

Remind me again in [text box with number] days.

This should be re-designed to something like: Remind me again in this number of days: [text box].

Character encoding and fonts

Always save, transfer, whatever text in Unicode (i.e. in UTF-8). Do not hard-code fonts - Localization might need to modify them and it will turn off default font fall-back mechanism (in case of Winforms).
Remember to allow "strange" characters in most fields (i.e. user name).

Test

You will probably need to implement so called pseudo translation, that is create resources for say German culture and copy your English strings adding prefix and suffix. You may also wrap placeholders to easily detect compound strings. The purpose of pseudo translation is to detect Localizability issues like hard-coded strings, layout issues and excessive use of compound messages.
