I am converting a localized WebForms application to MVC5. Most of the examples I have seen for MVC have a single resource - resx - file (per language) for the entire application.
Is it possible, to have a separate file for each view? If so, is there an example of how to reference the said file?
UPDATE: I would like to leave the resource files uncompiled if possible. This would allow us to edit the RESX files on the fly without having to recompile the site everytime.
Below is the procedure I had in WebForms. I am essentially trying to reproduce this in MVC5.
public string LocalizeText(Page CurrentPage, string resourceKey)
{
string localizedText = string.Empty;
// LOOK FOR LOCALIZED TEXT
String filePath = string.Empty;
if (!String.IsNullOrEmpty(CurrentPage.Request.GetFriendlyUrlFileVirtualPath()))
{
filePath = CurrentPage.Request.GetFriendlyUrlFileVirtualPath(); // FOR FRIENDLY URLS
}
else
{
filePath = CurrentPage.Request.CurrentExecutionFilePath; // FOR "UNFRIENDLY" URLS (THOSE WITH A FILE EXTENSION VISIBLE)
}
try
{
localizedText = Convert.ToString(HttpContext.GetLocalResourceObject(filePath, resourceKey, System.Globalization.CultureInfo.CurrentCulture)).Trim();
}
catch (Exception ex)
{
HttpContext.Current.Response.Write(ex.ToString() + "<br />" + filePath);
}
return localizedText;
}
The resource files would be located in the App_LocalResources folder.
Yes, it is possible to have a separate resource file for a view. As a really simple, and pretty dull example (sorry about that :-)), consider the following view model:
using _31662592.Resources;
using System.ComponentModel.DataAnnotations;
public class HomeViewModel
{
[Display(Name = "WelcomeHeader", ResourceType = typeof(HomeResources))]
public string WelcomeHeader { get; set; }
[Display(Name = "WelcomeMessage", ResourceType = typeof(HomeResources))]
public string WelcomeMessage { get; set; }
}
Here, I'm making use of the Display
attribute, which has support for localisation. So in my case, the resource file I created looks like this:
As you can see, the ResourceType
property corresponds with the type of your resource file (i.e. HomeResources
in my case), and the Name
property corresponds with the name of the string in the resource file which you wish to bind the property to.
Nothing fancy in the action:
public ActionResult Index()
{
return View(new HomeViewModel());
}
The view is very simple too:
@model _31662592.Models.HomeViewModel
<h1>@Html.DisplayNameFor(m => m.WelcomeHeader)</h1>
<p>@Html.DisplayNameFor(m => m.WelcomeMessage)</p>
You can even use the resources inline in your views, such as:
@using _31662592.Resources
<h1>@HomeResources.WelcomeHeader</h1>
<p>@HomeResources.WelcomeMessage</p>
In case you have any problems, you should make sure that:
Both of these options can be set by right-clicking on the resource file and selecting Properties
. Those options will then be shown in the properties dockable window. Finally, if you wish to reference the resource file from another project, make sure it's set to Public
rather than internal, which you can set by double-clicking the resource file to open it as normal, then changing its access modifier from internal
to public
.