4

I want to run the Sitecore command Translate.Text inside a controller, which doesn't seem to translate (at that time). I've tried debugging and also run different Translate commands (like Translate.TextByDomain) in VS2015's Immediate window. When I continue the debugger after returning the View, the Immediate window can translate text. Does this mean that Translate.Text() only works after a certain point? Does it need some Context? The translation fails at Documenthelper class while returning value from method MakeNameForMonthlyReports.

Controller (stripped):

public ActionResult Index()
{
    var viewmodel = new DocumentsViewModel(); 
    //attention, there's Documents~ and Document~ ViewModel in this code sample.
    var val = "ABC";
    Parallel.Invoke(
            () => { viewmodel.MonthlyDocuments = DocumentHelper.GetMonthlyReports(val, Items.Fields.Reporting, _service); },
            () => { viewmodel.QuarterlyDocuments = DocumentHelper.GetQuarterlyReports(val, Items.Fields.Reporting, _service); }
            //stripped 4 more calls
    );
    return View("~/Views/Index.cshtml", viewmodel);
}

Documenthelper class (stripped) :

public static List<DocumentViewModel> GetMonthlyReports(string val, string category, IService _service) //IService not the real name, just renamed for brevity.
{
    var result = new List<DocumentViewModel>();
    try
    {
        var response = _service.GetMonthlyReports(val, category);
        response = response.Where(t => ((t.Year.Value == DateTime.Now.AddYears(-1).Year) && (t.Month.Value >= DateTime.Now.Month)) || ((t.Year.Value == DateTime.Now.Year) && (t.Month.Value <= DateTime.Now.Month)))
             .OrderByDescending(t => t.Year.Value)
             .ThenByDescending(t => t.Month.Value)
             .ToList();
        foreach (var item in response)
        {
            var dvm = new DocumentViewModel()
            {
                LastChanged = item.LastImportDate,
                Name = MakeNameForMonthlyReports(item.FileName),
                Url = GetDocumentUrl(item.FileName)
            };
            result.Add(dvm);
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message, ex);
    }
    return result;
}

private static string MakeNameForMonthlyReports(string filename)
{
    string[] fileTags = filename.Split('_');
    string monthToTranslate = string.Empty;
    switch (Convert.ToInt32(fileTags[3]))
    {
        case 1:
            monthToTranslate = "Global.Library.DateSettings.Month.January";
            break;
        case 2:
            monthToTranslate = "Global.Library.DateSettings.Month.February";
            break;
        case 3:
            monthToTranslate = "Global.Library.DateSettings.Month.March";
            break;
        //case 4 etcetera
    }
    return $"{SC.Globalization.Translate.Text(monthToTranslate)} {fileTags[2]} {fileTags[1]}.pdf";
}

After being outside the Parallel.Invoke command while debugging, the text translation seem to work.

While writing this question, this makes sense as the context is not passed into the parallel tasks, but how can I make the context available (without running into unexpected behavior)? Some might think, why use Parallel.Invoke anyway? I'm lazy on this one, and don't want to rewrite the called _service object to work asynchronously, but I do want to speed up these 6 calls to _service.

New insights: one of the parallel tasks seem to have Context. It can translate correctly while debugging on one of the threads being run by Parallel.Invoke. I didn't see this until now, as not all tasks returning documents, yet. It can't on other threads. This seem to be a Thread thingie...

Another addition: I'm using DictionaryDomain in my multi site solution.

3
  • Can you try creating a variable var language = Sitecore.Context.Language before Parallel and then use Translate.TextByLanguage(string key, Language language) instead of Translate.Text?
    – Marek Musielak
    Feb 14, 2018 at 10:51
  • @Marek Musielak: That works, before Parallel indeed.
    – Michael
    Feb 14, 2018 at 10:58
  • Comment converted to an answer
    – Marek Musielak
    Feb 14, 2018 at 11:08

1 Answer 1

4

There is no Sitecore.Context inside Parallel.Invoke. And Sitecore.Context is used in Translate methods. That's why you need to pass all the necessary data to the method. Try:

  1. Create variables
var language = Sitecore.Context.Language;
var database = Sitecore.Context.ContentDatabase ?? Sitecore.Context.Database;

before Parallel.Invoke.

  1. Use
 Translate.TextByLanguage(null, new TranslateOptions {Database = database}, key, language, key);

instead of Translate.Text.

4
  • Do you mean i should pass the language to the documenthelper class? I'll try this right away.
    – Michael
    Feb 14, 2018 at 11:17
  • Not working unfortunaly. It seems it can't find the dictionary itself while running some of the threads created while doing Parellel.Invoke. Also running Translate.TextByDomain is not working at the same time.
    – Michael
    Feb 14, 2018 at 11:27
  • Answer edited. This should do the trick.
    – Marek Musielak
    Feb 14, 2018 at 11:42
  • 1
    Marek, +1 you nailed it -almost-, thanks :) Didn't tell you, but I'm using domain dictionary in my (multi) site, so had to replace null with my Dictionary domain. Added line above Parellel.Invoke: var dom = Sitecore.Context.Site.DictionaryDomain;
    – Michael
    Feb 14, 2018 at 12:00

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.