Repository navigation
Move the request-language GetResource overload to Web - #940
Merged
Merged
Conversation
added 2 commits
October 17, 2026 20:43
ITranslationService.GetResource(name) read the working language of the current request, so Business code could call it and silently get an empty or wrong-language text outside a request. It is now on IRequestTranslationService in Grand.Web.Common, which extends ITranslationService. Business no longer sees the overload at compile time and TranslationService no longer depends on IContextAccessor. Web, admin panels and plugins inject IRequestTranslationService, so their GetResource(name) calls are unchanged. The API module does not reference Grand.Web.Common and passes the working language explicitly.
…ionService - Add IContextAccessor.WorkingLanguageId() in the API module so validators no longer throw when no working language is resolved - Move RequestTranslationService to its own file and derive it from TranslationService instead of forwarding every member - Return an empty string from GetResource(name) when there is no work context
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the explicit-context work in Business (after #930, #931, #932, #936, #937, #938, #939)
Type: feature
Issue
ITranslationService.GetResource(name)reads the working language of the current request. #938 removed its last calls fromsrc/Business, but nothing stopped new ones: the overload sat on the Business interface, andTranslationServicestill injectedIContextAccessoronly to serve it. Business code that calls it runs fine in a request and returns an empty or wrong-language text in a scheduled task, a background handler or the admin panel. #937 documented this overload as the accepted remainder of M1.Solution
ITranslationService(Grand.Business.Core) keeps onlyGetResource(name, languageId, defaultValue, returnEmptyIfNotFound).TranslationServiceno longer takesIContextAccessor, so Business has no ambient read of the request left.IRequestTranslationService : ITranslationServiceinGrand.Web.Common.LocalizationaddsGetResource(name)in the working language of the request.RequestTranslationServiceforwards everything else to the registeredITranslationService, so a replaced implementation still applies.LocService(Loc[...]in views) and the plugins injectIRequestTranslationService. TheirGetResource(name)calls are unchanged; only the injected type changes.Grand.Module.Apidoes not referenceGrand.Web.Common. Its 17 validators readcontextAccessor.WorkContext.WorkingLanguage.Idonce and pass it..ai/guides describe the new contract.Known remainder: plugin providers (payment, shipping, tax, discount rules, widgets) resolve
FriendlyNameandDescription()throughIRequestTranslationServiceand are called from Business services (PaymentService,ShippingService,PricingService). This is the same behavior as before, now visible in the type. Fixing it means passing a language throughIProviderand the provider contracts, which is a separate change.Breaking changes
ITranslationService.GetResource(string name)is removed. Plugins call it onIRequestTranslationService(Grand.Web.Common.Localization) instead, or pass a language. A plugin built against the old interface fails withMissingMethodExceptionuntil rebuilt.TranslationServiceconstructor:(IRepository<TranslationResource>, IMediator);IContextAccessorremoved.LocServiceand the Admin/Store/Vendor/AdminShared base controllers, view model services and validators takeIRequestTranslationServiceinstead ofITranslationService.IContextAccessor.Testing
Automated: the solution builds, and
dotnet test GrandNode.slnxpasses.Grand.Business.Marketing.Testsfailed one test in the parallel full run and passes on its own, which is the known parallel flake. NewRequestTranslationServiceTestscover the request language, a request without a language (empty string), and that the explicit overload does not read the request.PluginDependencyCycleTestsand the payment provider tests registerIRequestTranslationServicein their hand-built containers.Manual (not run yet):
/api/...with a token) with an invalid product (empty name): the validation message is in the working language.