This is a migrated thread and some comments may be shown as answers.

[Solved] Custom LocalizationService for Grid?

11 Answers 247 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Cassandra
Top achievements
Rank 1
Cassandra asked on 09 Mar 2011, 10:34 PM
According to http://www.telerik.com/help/aspnet-mvc/telerik-ui-components-grid-localization.html, in order to localize my grid I must include the GridLocalization resx files in my App_GlobalResources folder. And when implemented, this works as expected.

However, I would like to keep all my localization files in a separate assembly used embedded resources as these are shared with all projects in the solution. After looking through the source code, it appears there is an interface ILocalizationService that provides methods to retrieve resources. There is one implementation that depends on the App_GlobalResources folder and files, but I would like to add another implementation for our needs (accessing resources in a different assembly). Is there a standard way to do this, or is the only option to edit the LocalizationService class and recompile the Telerik MVC source code?

11 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 10 Mar 2011, 10:01 AM
Hi Cassandra,

 Implementing a custom localization service would not be an easy task. We don't have any documentation and frankly have not done it before. 

 Adding embedded localization files to the source however should work. Check the attached screenshot. You can add as many resource files as you want and make them "Embedded resource". The current localization service should pick them up. However they must be part of the Telerik.Web.Mvc.dll assembly.

Regards,
Atanas Korchev
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Cassandra
Top achievements
Rank 1
answered on 14 Mar 2011, 02:33 PM
Hi Atanas,

Unfortunately this does not seem to work. I am able to access the strings directly if I use the PublicResXFileCodeGeneratorResX custom tool for resource files in the Telerik solution and then in my project use the syntax Telerik.Web.Mvc.Resources.GridLocalization.DeleteConfirmation. However, the code that goes through the LocalizationService does not get localized (the entire grid stays in English).

For now I will just put them in my MVC project since that seems to be the only solution other than writing a custom localization service.

Cassandra
0
Andreas
Top achievements
Rank 1
answered on 27 Sep 2011, 10:21 AM
Hello,

I have implemented my own version of the ILocalizationService and replaced the Telerik implementation in my Global.asax:
DI.Current.Register<ILocalizationServiceFactory>(() => new B4LocalizationServiceFactory()); 

In my case I read resources from the database.  It works just fine when looking at the HTML generated for the Grid (the HTML returned from the server for the initial page load).  When binding the Grid via Ajax the translations are overwritten by the HTML generated at runtime.  My debugging shows that the ILocalizationService is completely ignored in Ajax mode.

I entered a ticket with number '467602' but got no answer so far.

Maybe someone from Telerik can shade some light on this.

Regards,
Andreas

0
Andreas
Top achievements
Rank 1
answered on 27 Sep 2011, 01:42 PM
Ok, now I found the problem and I got it to work.  Implementing a custom ILocalizationService is at the end quite trivial.  Here is how I have done it.
First the documented interfaces to implement (please correct doc if incorrect)
namespace Telerik.Web.Mvc.Infrastructure
{
    /// <summary>
    /// A factory to create instances of ILocalizationService.
    /// </summary>
    public interface ILocalizationServiceFactory
    {
        /// <summary>Create a new instance of a localization service for a component.</summary>
        /// <param name="resourceName">The name of the component for which to create the localization service.
        ///                            (currently "GridLocalization", "EditorLocalization" or "UploadLocalization")</param>
        /// <param name="culture">The culture for which to create the localization service.</param>
        /// <returns>An instance of <code>ILocalizationService</code></returns>
        ILocalizationService Create(string resourceName, CultureInfo culture);
    }
}
namespace Telerik.Web.Mvc.Infrastructure
{
    using System.Collections.Generic;
 
    /// <summary>
    /// A Localization Service on a per component basis.
    /// </summary>
    public interface ILocalizationService
    {
        /// <summary>Returns the translated resource with the given key for the current UICulture.</summary>
        /// <param name="key">The key of the resource to translate.</param>
        /// <returns>The translated resource.</returns>
        string One(string key);
 
        /// <summary>Returns a dictionary of all resources for the current UICulture.</summary>
        /// <remarks>Dictionary kes is the resource key, dictionary value is the translated resource.</remarks>
        /// <returns>The dictionary of all resources for the current UICulture.</returns>
        IDictionary<string, string> All();
 
        /// <summary>
        /// Return <code>true</code> if resources need to be embedded in JavaScript.
        /// </summary>
        bool IsDefault
        {
            get;
        }
    }
}

And here my implementation:
public class B4LocalizationServiceFactory : ILocalizationServiceFactory
{
    public ILocalizationService Create(string resourceName, CultureInfo culture)
    {
        return new B4TelerikLocalizationService(MvcApplication.ApplicationName, resourceName, culture);
    }
}
class B4TelerikLocalizationService : ILocalizationService
{
    private readonly string      _appName;
    private readonly string      _componentName;  // "GridLocalization", "EditorLocalization" or "UploadLocalization"
    private readonly CultureInfo _culture;
 
    private readonly B4.DomainModels.Localization.ILocalizationService _b4GlobalLocalizationService;
 
 
    public B4TelerikLocalizationService(string appName, string resourceName, CultureInfo culture)
    {
        _appName                     = appName;
        _componentName               = resourceName;
        _culture                     = culture;
        _b4GlobalLocalizationService = DependencyResolver.Current.GetService<B4.DomainModels.Localization.ILocalizationService>();
    }
 
 
    public string One(string key)
    {
        string translation = _b4GlobalLocalizationService.Translate(_appName, _componentName + "." + key, _culture.Name);
        return translation;
    }
 
 
    public IDictionary<string, string> All()
    {
        return _b4GlobalLocalizationService.GetAll(_appName, _componentName, _culture.Name);
    }
 
 
    public bool IsDefault
    {
        get { return false; }
    }
}

Hope this helps.

Regards,
Andreas
0
Andreas
Top achievements
Rank 1
answered on 27 Sep 2011, 01:45 PM
And here is how to register the custom ILocalisationService:

DI.Current.Register<ILocalizationServiceFactory>(() => new B4LocalizationServiceFactory()); 

This is done in the corresponding Application Startup method in Global.asax.
0
Ed
Top achievements
Rank 1
answered on 07 Dec 2011, 12:30 AM
Thanks for the post.  Perhaps I overlooked this, could you explain the role of  B4.DomainModels.Localization.ILocalizationService which you didn't provide code for.  Is this propertiary stuff?  I'm not clear what I should be doing.

Thanks,

Ed
0
Matt
Top achievements
Rank 1
answered on 22 Feb 2012, 05:40 PM
@Andreas, Did you do anything special to resolve the issue you were having with your localization logic not working when the grid was being used with ajax binding? I'm having the same problem and I've implemented the localization factory the same way that you did. It works fine in server binding mode but as soon as soon as I use ajax binding mode you can see my value that comes from the database on-screen but it quickly reverts to the telerik default value.

@Ed, I'm sure you figured this out and moved on, but in case anyone else runs across this, it looks like the b4GlobalLocalizationService that you asked about is a service layer that performs the necessary functions to query the database (or whatever other method you'd want to use).
0
Andreas
Top achievements
Rank 1
answered on 24 Feb 2012, 09:12 AM
@Ed: B4.DomainModels.Localization.ILocalizationService is the repository.  It simply reads the translations from the database.  In my case beside the actual resource key I need to provide an application name and a customer id to select the corresponding translation. Customer ID is required because different customers can have different translations.  Other than that its quite simple and straight forward.

@Matt: For me it works great now.  When I remember right I had the trouble because I was mixing Server and Ajax binding.  The problem was that the Grid does a localization on the server side when you do server binding, but in mixed mode it does an additional localization with each Ajax refresh with the localization data provided in the jquery init of the Grid, which is the default stuff from Telerik.  When I remember right, this was a strange behavior of the Grid.  Once you do pure Ajax binding the problem is gone.  The jquery plugin config code of the Grid then uses the translation provided by you using the public IDictionary<stringstring> All() method.  Make sure "All()" returns all translations required by the Grid.

Hope this helps.
   
0
Matt
Top achievements
Rank 1
answered on 24 Feb 2012, 10:48 PM
Thanks a bunch Ed! I wasn't exactly sure what the All() function was for. I had it set to throw an exception if/when it got hit. I implemented the dictionary but it didn't change the fact that the All() function was still never being reached. I looked at the code you posted once more to see if there were any other differences i could find, and then I noticed the problem, which was that I had the IsDefault property returning true instead of false. I'm still not sure I understand the implications of that property, but once I switched it to false it began to behave as expected. Thanks for your help!
0
Andreas
Top achievements
Rank 1
answered on 26 Feb 2012, 03:17 PM
@Matt:  Glad you found the problem. BTW: It's ANDREAS, not ED! ;-)
0
Matt
Top achievements
Rank 1
answered on 27 Feb 2012, 01:34 PM
@Andreas: Haha too funny, apparently my brain-to-keyboard function was off last week, thanks again! xD
Tags
Grid
Asked by
Cassandra
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Cassandra
Top achievements
Rank 1
Andreas
Top achievements
Rank 1
Ed
Top achievements
Rank 1
Matt
Top achievements
Rank 1
Share this question
or