0

Current Scenario:

  • I have a model class wich has Descriptions in diferent languages, like Description_en , Description_sp , Description_fr .

  • When a user selects his current language, I have a cookie 'culture' with that value.

***** The objective is to call a different Description, when a different language is selected. If user selects fr, Description_fr should be called, and so on...

My code:

In ModelClass I have a reflection (has seen here: How to call a property of an object with a variable in C# e.g. customer.&fieldName ):

public class Something
    {
        public string Description_en { get; set; } 
        public string Description_sp { get; set; } 
        public string Description_fr { get; set; } 

        //Reflection, makes it possible to select a property to call with a variable
            public string GetPropertyValue(string fieldName)
            {
                PropertyInfo prop = typeof(Something).GetProperty(fieldName);
                return prop.GetValue(this, null).ToString();
            }
    }

In a razor Template I have:

@model IEnumerable<baseTemplate.Models.Something>

<table class="table">
    <tr>
        <th data-lang=@culture>
        <!-- @culture is defined in current scope -->
            @Html.DisplayNameFor(model => model.GetPropertyValue("Description_" + @culture)) 
        </th>
    </tr>
</table>

When it runs to the property GetPropertyValue("...") the following error is displayed:

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

My question is: Is there is a way to do this?

P.S. The obvious (and correct) possibility of...

if(@culture == "en"){@Html.DisplayNameFor(model => model.Description_en") }

... Shouldn't be an answer because it would create a 'Hell' of code to maintain afterwards :)

Thank you for the possible help

3
  • 1
    In your razor code, drop the @ from @culture in your GetPropertyValue call: @Html.DisplayNameFor(model => model.GetPropertyValue("Description_" + culture)) Commented Aug 7, 2015 at 1:05
  • That does not seem as a good solution, what happens if you add another language? you will need to add a new property to your model? Than would create a Hell of code to maintain afterwards Commented Aug 7, 2015 at 1:06
  • @jmelosegui, not really in this case, the code as more abstraction than that. It was just an example to reach to the answer... but thank you anyway :) Commented Aug 7, 2015 at 2:21

3 Answers 3

2

The problem is with DisplayNameFor which do not accept an expression that executed a method as parameter. It will work if you get rid of it and use just @Model.GetPropertyValue("Description_" + @culture)

Sign up to request clarification or add additional context in comments.

1 Comment

Despite @Model.GetPropertyValue("Description_" + @culture) rised an error, this led me to an pretty close answer :) thank you!
0

Resources! Specifically localized resources. You can have the file names in resources, or have the files themselves stored in resources and access them through the resource manager.

The resource manager will resolve the current culture for a particular value and default to a base language if the localized resource does not exist.

This is pretty old school functionality, but it still works and .Net provides facilities to automagically resolve the resources. Also localized resources are the way applications have been internationalized for at least three decades.

2 Comments

i use resources through resource manager. When you say "You can have the file names in resources" what do you mean? thank you
@DiogoAlmeida Use the actual file name... Presuming en is your reference language the string "Description_en" would be in Resources.resx, "Description_sp" would be in Resources.sp.resx, "Description_fr" would be in Resources.fr.resx, and so on... just add a new resx for each new language with no changes in code! Give the filename the same string for a tag. Use this string to query the resource manager and the file name is return as a text string
0

Yes, Steve is right. Your task is completely about using resources. You shouldn't place description fields for every culture in your model. It is completely wrong. You can find more about ASP.NET MVC app internationalization there: http://afana.me/post/aspnet-mvc-internationalization.aspx.

3 Comments

I use resources to static content, I know the code of afana's blog. The content where i use this method isnt static. The description_xx in various languages is necessary because it is diferent for every line of every entry in DB and it is fetch with an ID (example: class 5, of course ABC, as ID 2354kk, so it will get that content in DB). I would have to have one resource entry for every language, for every entry of DB. And despite being faster to fetch little amount of content, the resources XML when gets large is less efficient then DB :) I can still be doing it wrong ^_^
@DiogoAlmeida Well... Maybe in your case model should have something that looks like IDictionary<string, string> LocalizedDescriptions where key is culture name and value is localized description? It is more flexible than hardcoded fields. But anyway your problem was solved as I see =).
I'm Always looking for better solutions X-) so I will check your hint :) thank you very much... it kinda sounds good ^_^

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.