turquoiseowl / i18n

Smart internationalization for ASP.NET
Other
556 stars 156 forks source link

Deprecate EntityLocalizationMiddleware #334

Closed macote closed 7 years ago

macote commented 7 years ago

Also, revert ca6e4f258c4fd447a0cff8ab647d965453398f0e changes since HttpContext is a property in this context.

turquoiseowl commented 7 years ago

Nice job, thanks.

ajbeaven commented 6 years ago

I'm finding that Application_ReleaseRequestState is not executed so the ResponseFilter is never installed and any nuggets in the response are not translated. When is this event suppose to be triggered? Would using SignalR stop this from happening?

I also tried using the (now deprecated) EntityLocalizationMiddleware which does cause the ResponseFilter to be installed but unfortunately I get a NullReferenceException on m_stagingBuffer in the Write method :/

ajbeaven commented 6 years ago

I'm guessing SignalR uses a different request/response lifecycle than a normal .NET request, which is why that event is never fired.

For those that come after me wanting to know how to get SignalR working with i18n, here's a custom HubPiplineModule that installs the ResponseFilter and avoids the NullReferenceException issue mentioned above:

public class i18nHubPipelineModule : HubPipelineModule
{
    private readonly i18nSettings _i18nSettings;

    public i18nHubPipelineModule(i18nSettings i18nSettings)
    {
        _i18nSettings = i18nSettings;
    }

    /// <summary>
    /// Translates the SignalR response sent back when a client sends a request
    /// </summary>
    protected override object OnAfterIncoming(object result, IHubIncomingInvokerContext context)
    {
        var requestUrl = context.Hub.Context.Request.Url.AbsoluteUri;
        LanguageTag.ExtractLangTagFromUrl(requestUrl, UriKind.Absolute, out var langTag);
        var translatedResult = TranslateResult(result, langTag);
        return base.OnAfterIncoming(translatedResult, context);
    }

    private object TranslateResult(object result, string langTag)
    {
        var translationRepository = new POTranslationRepository(_i18nSettings);
        var textLocalizer = new TextLocalizer(_i18nSettings, translationRepository);
        var nuggetLocalizer = new NuggetLocalizer(_i18nSettings, textLocalizer);
        var emailLanguageItems = new[] { new LanguageItem(new LanguageTag(langTag), LanguageItem.PalQualitySetting, 0) };

        var translatedJson = JsonConvert.SerializeObject(result);
        translatedJson = LocalizedApplication.Current.NuggetLocalizerForApp.ProcessNuggets(translatedJson, emailLanguageItems);
        return JsonConvert.DeserializeObject(translatedJson);
    }
}

It's a bit more convoluted than seems necessary but that's because HttpContext.Response doesn't exist when using websockets.