Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParseAndTranslate change headers. #338

Closed
jeancroy opened this issue Apr 19, 2017 · 8 comments
Closed

ParseAndTranslate change headers. #338

jeancroy opened this issue Apr 19, 2017 · 8 comments
Labels

Comments

@jeancroy
Copy link
Contributor

jeancroy commented Apr 19, 2017

The recommended way to translate a segment of text is

    string entity = HttpContext.ParseAndTranslate("Hi - [[[Sign in]]]");

However it does a bit more that just translate the text, it try to setup headers as a side effect.
It make a call to ProcessOutgoing which aim to rewrite url consistently with url localisation scheme. BUT that method also try to rewrite url in headers

Possible problem of those hidden side effect include error when there are no http response. (for example sending email at scheduled time)

System.PlatformNotSupportedException: This operation requires IIS integrated pipeline mode.
   at System.Web.HttpResponse.get_Headers()
   at System.Web.HttpResponseWrapper.get_Headers()
   at i18n.EarlyUrlLocalizer.ProcessOutgoing(String entity, String langtag, HttpContextBase context)
   at i18n.HttpContextExtensions.ParseAndTranslate(HttpContextBase context, String entity

Possible solution include splitting ProcessOutgoing as ProcessOutgoingNuggets and ProcessOutgoingHeaders. Then call header localization only when filtering request.

@turquoiseowl
Copy link
Owner

Yes, I agree with your suggestion. That feature was an afterthought... I would be happy to merge a PR on this. Thanks.

@vhatuncev
Copy link
Contributor

@jeancroy looks like you call ParseAndTranslate method inside environment without http context, is it correct?

@jeancroy
Copy link
Contributor Author

I considered it. My use case is producing emails and reports in a background process.
It looks like I side-stepped the issue by calling some methods used by the internal of ParseAndTranslate.

 public static string TranslateNugget(string input, ILanguageTag lt = null)
        {
            if (lt == null) lt = HttpContext.Current.GetPrincipalAppLanguageForRequest();

            var langs = new[] { new LanguageItem(lt, LanguageItem.PalQualitySetting, 0) };

            var nuggetLocalizer = LocalizedApplication.Current.NuggetLocalizerForApp;
            if (nuggetLocalizer != null)
            {
                return LocalizedApplication.Current
                    .NuggetLocalizerForApp.ProcessNuggets(input, langs)
                    .Replace("\x5b\x5b\x5b","")   // Remove any remaining [[[ ]]]
                    .Replace("\x5d\x5d\x5d", "");

            }
            return input;
        }

Now if you truly don't have any context the above lt==null case wont work.
It think I ended up creating a minimal context with

var oldHttpContext = HttpContext.Current;
var fakeHttpContext = new HttpContext(new HttpRequest(null, "fakeurl", null), new HttpResponse(null));
HttpContext.Current = fakeHttpContext;
var langTag = LanguageHelpers.GetMatchingAppLanguage(lang);
fakeHttpContext.SetPrincipalAppLanguageForRequest(langTag);

@vhatuncev
Copy link
Contributor

@jeancroy I made the change as you initially suggested. But I don't sure if anyone's code already rely on existing side effect when calling manually HttpContext.ParseAndTranslate method. I assume it won't if i18n used by asp.net request pipeline, otherwise headers leave intact. I expect @turquoiseowl can provide any thoughts about it?
Regarding producing translations inside background process, my project requires same functionality as well. Making a stub for this purpose is not clean solution and I'm thinking to implement clean method which does not depend on http context

@jeancroy
Copy link
Contributor Author

Making a stub for this purpose is not clean solution and I'm thinking to implement clean method which does not depend on http context

Another reason I've made a stub is that I'm trying to render views to string, and the view engine need such stub for things like @Url.Action() to point to the proper place. I also use it to provide context to format date & numbers with user locale.

@vhatuncev
Copy link
Contributor

@jeancroy just interesting, how i18n helps with date & numbers format, can you provide an example?

@turquoiseowl
Copy link
Owner

@vhatuncev i18n does the following by default for a request that matches an application language:

Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = langtag.GetCultureInfo();

This is in the default LocalizedApplication.SetPrincipalAppLanguageForRequestHandlers delegate.

@turquoiseowl
Copy link
Owner

Apologies for slow response to the PR.

I've now merged it and tested ParseAndTranslate and normal request handling, and all looks good.

Suggest this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants