18

In my view I would like to access resource strings from the specific local resource on that file.. Just as you know it from web-forms:

(string)GetLocalResource("Title");

Painless and smooth. The framework handles which .resx file to get from the culture info code extension (.en-EN.resx).

Is that possible in MVC4 with Razore view? And how?

Iv'e noticed that i can set the Custom Tool property on the .resx file to PublicResXFileCodeGenerator. That way I can access it from the view. Example: I've created 2 resource files for index.cshtml in danish and english. Just as I would in web-forms. Here's what I wish i could write (Custom Tool Name property set to 'ViewResource'):

@ViewResource.Title

Bam. If current culture is danish, title will be "Forside", and if english it would be "Home". But instead the only options I am given is choosing a specific file. And from that choose the desired string:

@ViewResource.Index_cshtml_en-EN_resx.Title

Thats not dynamic. So I thought I could make an extension class that would replace the en-EN/da-DK somehow. But that really seems like relatively alot of work for something so "simple" and already well and easy intergrated into web-forms. There has to be another way. Surely the mvc team has some smart mechanism for us like everything else :)

Kasper Skov
  • 1,954
  • 10
  • 32
  • 53

6 Answers6

42

I used the special .NET folder App_LocalResources.

Here are the steps

Add the .resx files to that folder (i.e.: Resource.resx, Resource.es-ES.resx)

Right click on each .resx file and select properties and make sure the following are selected

Build Action: Embedded Resource 
Custom Tool: PublicResXFileCodeGenerator
Custom Tool Namespace: Resources

Then in your view you can use the Resources name space to access the text in your .resx file

<h2>@Resources.Resource.Global_Title<h2>

@Resources because that is the name that you gave in the Custom Tool Namespace and .Resource because that is the name of the .resx file

Also make sure that the resources are set to Public

To access the resources from any model just add a single line

using Resources;  //<<-- This line

namespace Concordia_CRM.Models
{
    public class SolicitudDemo
    {
        [Required]
        [Display(Name = "SD_NombreEmpresa", ResourceType = typeof(Resource))]
        public string NombreEmpresa { get; set; }

...
}

More details can be found on this post.

Stacked
  • 6,892
  • 7
  • 57
  • 73
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
  • 3
    I realize this is old but this page helped me in my dev and i wanted to add that if you want to have html tags in your values, it helps to place the @Resources.Resource.PropertyName inside @Html.Raw(). This way, if your value has tags (for example ) it will render the html accordingly and not just the text. Another point to note is that if you want to place these values inside a data-foo attribute, and the value has spaces, you should enclose the entire line in quotation marks so it reads as: data-foo="@Html.Raw(Resources.Resource.PropertyName)" – prismeyez83 Jun 01 '17 at 09:30
10

In Resources Designer in Visual Studio on the top we have a Combo Box with a label : Access Modifier, usually it is set to : internal, to make it work set it to : Public.

phykas
  • 101
  • 1
  • 3
7

If you create a folder called f.ex. "Resources" and add 2 files Index.resx and Index.da-DK.resx you should be able to accesses them like this in your razor view.

@Resources.Index.Title

Then depending on the current thread culture it will choose the text from the correct file

terjetyl
  • 9,497
  • 4
  • 54
  • 72
  • 4
    Nope. I can't access them. Do I need to import something in the view? – Kasper Skov Feb 24 '13 at 17:59
  • 2
    Maybe you need the use the full namespace path MyApp.Resources.Index.Title. I have my resource files in a separate project and by setting the resource accessors to public I can access them directly from my razor views – terjetyl Feb 24 '13 at 18:16
  • Nope, I still can't. What Build Action is your resources files set to? – Kasper Skov Feb 24 '13 at 19:20
  • They are set to "Embedded Resource" – terjetyl Feb 24 '13 at 19:25
  • Alright. Mine too. But I really cant access them. I tried importing all kinds of stuff and adding shit the webconfig. Still cant reach them. Wtf? Do you have a custom tool name set? – Kasper Skov Feb 24 '13 at 19:50
  • No. I have "PublicResXFileCodeGenerator". – terjetyl Feb 24 '13 at 19:59
  • Not really. It should not be that hard. Have you tried this in an app created from scratch. It could be there is something fishy with your web app – terjetyl Feb 24 '13 at 20:21
  • 1
    I needed to add `@using System.Web.Razor.Resources;` to the top of my Razor file, then I could do `@Resources.MyResource.Foo` – Dunc Mar 27 '15 at 16:01
3

terjetyl put me on the right path, but I had to do some "coding" (ah nuts) to get it working. My setup is Visual Studio 2013, MVC 5, Razor.

  1. Right-click on you view's containing folder, select Add > Add ASP.NET folder > App_LocalResources

  2. Add two Resource Files into here: Index.cshtml.resx and Index.cshtml.fr-FR.resx (assuming your view is called "Index" and you want French translations). Check the file properties, and make sure they are set to Build Action=Content and Custom Tool=(blank)

  3. Double-click the resx files and populate with key/values

  4. Create a HtmlHelper extension method.


public static class HtmlExtensions
{
    public static MvcHtmlString Translate(this HtmlHelper htmlHelper, string key)
    {
        var viewPath = ((System.Web.Mvc.RazorView)htmlHelper.ViewContext.View).ViewPath;
        var culture = System.Threading.Thread.CurrentThread.CurrentCulture;

        var httpContext = htmlHelper.ViewContext.HttpContext;
        var val = (string)httpContext.GetLocalResourceObject(viewPath, key, culture);

        return MvcHtmlString.Create(val);
    }
}

  1. Use extension in your view:

    <p>@Html.Translate("MyKey")</p>

To explain, the helper gets the virtual path of your view and passes it to HttpContext.GetLocalResourceObject(), which decides what resource file to use (and degrades gracefully).

One last thing, make sure this is in your web.config:

<system.web>
    <globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true" />
    ...

I've tried to kept this as simple as possible. However, be aware that by using this example, French cultures other than fr-FR (e.g. fr-CA) will default to the base resx. If you want it to be cleverer than this, more code is needed - I can include on request.

Dunc
  • 18,404
  • 6
  • 86
  • 103
2

I never got it to work. I ended up using .net folders "App_LocalResources".

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
Kasper Skov
  • 1,954
  • 10
  • 32
  • 53
1

I got it workint using @MyApp.Resources.Resources.Title.

tonjo
  • 1,394
  • 1
  • 14
  • 27