OK... well... turns out you have to do it yourself.
The following code tells you how to get the globalization scripts and install them. Plus it gives you a handy extension method that allows you to inject a reference to MS AJAX on your View or Master Page, with or without script globalization enabled.
Features:-
- inject MS AJAX onto View with minimal effort
- Debug or Release version chosen according to whether assembly is
compiled in Debug or Release mode
- optionally enable script globalization
- optionally inject call to the Sys.Application.initialize() function
- optionally inline the code to enable script globalization, like the
ScriptManager does (requires conditional compilation symbol); by default a reference to the globalization script file is injected.
Enjoy!
//
// Include Microsoft Ajax In Your ASP.NET MVC Projects, Optionally With Script Globalization Enabled
// -------------------------------------------------------------------------------------------------
//
// Written by Andrew Webb, 4th May 2009.
//
// Feel free to use in your ASP.NET MVC projects.
// Written for ASP.NET MVC 1.0 and .NET Framework 3.5 SP1.
//
// With thanks to Bertrand LeRoy and Steven Sanderson.
// http://weblogs.asp.net/bleroy/
// http://blog.codeville.net/
//
// Example usage of 'IncludeMicrosoftAjax':-
// <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" Culture="auto" UICulture="auto" %>
// <%@ Import Namespace="AspNetMvcHelper" %>
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
// <html xmlns="http://www.w3.org/1999/xhtml" >
// <head runat="server">
// <!-- Include Ms Ajax, with script globalization enabled -->
// <%= Html.IncludeMicrosoftAjax (true, false) %>
// <!-- other script references here, e.g. jQuery -->
// </head>
// etc.
//
// Note: for script globalization, the method in this file gets the current thread's current culture.
// The Culture="auto" setting in the Page directive (above) causes this to be set to the browser's
// preferred language. Alternatively you can set the current thread's current culture manually.
//
// NOTA BENE: for script globalization, the 205 globalization scripts from the MS AJAX Library must be
// obtained from Microsoft and added to your ASP.NET MVC project, as follows:
// 1) Download the Microsoft AJAX Library 3.5 from:
// http://www.asp.net/ajax/downloads/
//
// 2) Extract all files from the Zip, and locate the "Globalization" folder. It should have 205 script files
// in it, from "af-ZA.js" to "zu-ZA.js". Copy this folder inside your website/project, under the "Scripts"
// folder. Rename the folder to "MsAjaxGlobalization". The resulting structure should be:
// <project>\
// Scripts\
// MsAjaxGlobalization\
// <205 files>
// <jQuery, Ms Ajax and Ms Mvc Ajax files>
//
// Be sure to include the "MsAjaxGlobalization" folder in your web project. The easiest way is to click
// "Show All Files" button in the Solution Explorer's toolbar so that all files are shown, then right-click
// on "MsAjaxGlobalization" folder and select 'Include In Project' menu item. You can now unshow all files
// again.
//
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Text;
using System.IO;
using System.Threading;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
namespace AspNetMvcHelper
{
public static class ViewHelpers
{
/// <summary>
/// Includes Microsoft Ajax in a View, optionally with script globalization enabled.
/// </summary>
/// <param name="helper">
/// Unused. Included because this method is an extension method of System.Web.Mvc.HtmlHelper.
/// </param>
/// <param name="enableScriptGlobalization">
/// true to enable script globalization, else false. If true, be sure to include the 205 globalization
/// scripts in your project, in a subfolder called "MsAjaxGlobalization". This must be a direct sub-
/// folder of the "Scripts" folder, which in turn must live under the project root (which is the default
/// for MVC projects).
/// </param>
/// <param name="initializeSysApplication">
/// true to insert a call to 'Sys.Application.initialize', else false. (Note sure if this should be
/// done or not for MVC, so it's an option.)
/// </param>
/// <returns>
/// Include-text that contains "script" tags that a) set up variable '_cultureInfo' (optional), b)
/// cause the browser to load the Microsoft Ajax library (debug or release), and c) call function
/// 'Sys.Application.initialize' (optional).
/// </returns>
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId="helper")]
public static String IncludeMicrosoftAjax (this HtmlHelper helper, Boolean enableScriptGlobalization,
Boolean initializeSysApplication)
{
// Define INLINE_SETCULTUREINFO if you want to include the statement to set __cultureInfo in the HTML,
// like the ScriptManager does. Leave it undefined to have a script file reference instead (preferred).
#if INLINE_SETCULTUREINFO
String setCultureInfoText = null;
#endif
String globalizationScriptFileName = null;
// Text length without the inline statement to set __cultureInfo.
Int32 includeTextLength = 400;
// If script globalization is enabled, get the statement that sets __cultureInfo, and add the
// length of this statement to the overal length of the include-text.
if (enableScriptGlobalization)
{
// Get the current thread's current culture. Note: we could have a param that says whether to
// use this or the UICulture.
CultureInfo culture = Thread.CurrentThread.CurrentCulture;
// Form the name of the globalization script file, "en-US.js".
globalizationScriptFileName = culture.Name + ".js";
#if INLINE_SETCULTUREINFO
// Read in the contents of this file. Note that if this fails, the browser will be left with
// __cultureInfo set to "en-US" (see file "MicrosoftAjax.debug.js", lines 6432 and 6433).
try
{
setCultureInfoText = String.Empty;
String path = HttpContext.Current.Server.MapPath ("~/Scripts/MsAjaxGlobalization/" +
globalizationScriptFileName);
setCultureInfoText = File.ReadAllText (path);
includeTextLength += setCultureInfoText.Length;
}
catch (System.ArgumentNullException)
{
}
catch (System.ArgumentException)
{
}
catch (System.IO.PathTooLongException)
{
}
catch (System.IO.DirectoryNotFoundException)
{
}
catch (System.IO.FileNotFoundException)
{
}
catch (System.IO.IOException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.NotSupportedException)
{
}
catch (System.Security.SecurityException)
{
}
catch (System.Web.HttpException)
{
}
#endif
}
// Create and initialize the StringBuilder in which we'll build up the include-text.
StringBuilder sb = new StringBuilder (includeTextLength);
sb.AppendLine ();
// Get the application absolute path of the MS AJAX file (release or debug). As you can see,
// the folder and file names and locations are hardcoded. Convention... but er, no configuration!
#if DEBUG
String msAjaxScriptPath = VirtualPathUtility.ToAbsolute ("~/Scripts/MicrosoftAjax.debug.js");
#else
String msAjaxScriptPath = VirtualPathUtility.ToAbsolute ("~/Scripts/MicrosoftAjax.js");
#endif
// Add the globalization statement.
if (enableScriptGlobalization)
{
#if INLINE_SETCULTUREINFO
sb.AppendLine ("<script type=\"text/javascript\">");
sb.AppendLine ("//<![CDATA[");
sb.AppendLine (setCultureInfoText);
sb.AppendLine ("//]]>");
sb.AppendLine ("</script>");
#else
String path = VirtualPathUtility.ToAbsolute ("~/Scripts/MsAjaxGlobalization/" + globalizationScriptFileName);
sb.AppendLine ("<script src=\"" + path + "\" type=\"text/javascript\"></script>");
#endif
}
// Add the MS AJAX library reference.
sb.AppendLine ("<script src=\"" + msAjaxScriptPath + "\" type=\"text/javascript\"></script>");
// Add the call to initialize Sys.Application.
if (initializeSysApplication)
{
sb.AppendLine ("<script type=\"text/javascript\">");
sb.AppendLine ("//<![CDATA[");
sb.AppendLine ("if (typeof (Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');");
sb.AppendLine ("Sys.Application.initialize();");
sb.AppendLine ("//]]>");
sb.AppendLine ("</script>");
}
// Return the resulting include-text.
return (sb.ToString ());
}
}
}