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

.Net 7 Razor Class Library Localization #44655

Closed
Julien-Marpault opened this issue Oct 19, 2022 · 7 comments
Closed

.Net 7 Razor Class Library Localization #44655

Julien-Marpault opened this issue Oct 19, 2022 · 7 comments
Assignees
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-localization ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. investigate Status: Resolved

Comments

@Julien-Marpault
Copy link

Julien-Marpault commented Oct 19, 2022

I have a project with Controllers, Views etc. in a separate Razor Class Library.
image

In the application project I added in Program.cs

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services
    .AddControllersWithViews()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();

and

WebApplication app = builder.Build();

string[] supportedCultures = new[] { "fr" };
RequestLocalizationOptions localizationOptions = new();
localizationOptions.SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

.........

In my Login View I Added the ViewLocalizer

@inject IViewLocalizer Localizer
@model LoginViewModel
@{
    ViewData["Title"] = Localizer["Title"];
    ViewData["Greetings"] = Localizer["Greetings"];
}

<form method="post" asp-route-returnUrl="@Model.ReturnUrl">
    @Html.AntiForgeryToken()
    <section>
        <div class="input-group">
            <div asp-validation-summary="All" class="text-validation"></div>
        </div>
        <div class="input-group">
            <input asp-for="@Model.Email" class="border-bottom-dark" autofocus required autocomplete="off" />
            <label asp-for="@Model.Email">@Localizer["Model_Email"]</label>
        </div>
    </section>
    <footer>
        <button class="btn btn-full-width btn-ok">@Localizer["Button_Validate"]</button>
    </footer>
</form>

login.fr.resx file contains this:

Button_Validate Valider
Greetings Bienvenue !
Model_Email Email
Model_Email_Address E-mail invalide
Model_Email_Required E-mail requis
Title Connectez-vous ou créez un compte

But there's no way to have my string localized.

If I move the resource folder to the application project, it's working, but I want to distribute a default Localization with the Library

I read documentation an stackoverflow, but I've already done what is explained.

Thanks for your help.

@Julien-Marpault Julien-Marpault changed the title .Net 7 Razor Claa Library Localization .Net 7 Razor Class Library Localization Oct 19, 2022
@TanayParikh TanayParikh added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-localization labels Oct 19, 2022
@MackinnonBuck
Copy link
Member

Thanks for contacting us, @Julien-Marpault.

If I'm understanding the problem correctly, this is similar to aspnet/Razor#2404. For a possible workaround, please see the suggestions in aspnet/Localization#328. Could you please try this and let us know if covers your scenario? Thanks.

@MackinnonBuck MackinnonBuck added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Oct 20, 2022
@ghost
Copy link

ghost commented Oct 20, 2022

Hi @Julien-Marpault. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@Julien-Marpault
Copy link
Author

I tried but it doesn't work.

I made a custom implementation of IViewLocalizer with this method changing:

 public void Contextualize(ViewContext viewContext)
    {
        if (viewContext == null)
        {
            throw new ArgumentNullException(nameof(viewContext));
        }

        // Given a view path "/Views/Home/Index.cshtml" we want a baseName like "MyApplication.Views.Home.Index"
        string? path = viewContext.ExecutingFilePath;

        if (string.IsNullOrEmpty(path))
        {
            path = viewContext.View.Path;
        }

        Debug.Assert(!string.IsNullOrEmpty(path), "Couldn't determine a path for the view");

        if (viewContext.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
        {
            string? currentApplicationName = new AssemblyName(controllerActionDescriptor.ControllerTypeInfo.Assembly.FullName ?? string.Empty).Name;
            _applicationName = currentApplicationName ?? _hostingEnvironment.ApplicationName; ;
        }

        string baseName = BuildBaseName(path);
        _localizer = _localizerFactory.Create(baseName, _applicationName);
    }

but it doesn't work.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Oct 20, 2022
@Julien-Marpault
Copy link
Author

I moved y resources files to my main project to keep going on.
But I face another issue with DataAnnotation Localization.
As explained in the documentation
I created resource files like
Resources/ViewModels/LoginViewModels.resx

LoginViewModel:

public class LoginViewModel
{
    [Required(ErrorMessage = "Required")]
    [EmailAddress(ErrorMessage = "EmailAddress")]
    public string Email { get; set; }

    public string? ReturnUrl { get; set; }
}

Program.cs

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services
    .AddControllersWithViews()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();

But... It doesn't work :)

@mkArtakMSFT mkArtakMSFT added investigate and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Oct 25, 2022
@MackinnonBuck
Copy link
Member

@Julien-Marpault It looks like the name of that .resx file doesn't match the name of the model (see the extra "s" at the end). Could you try following the naming conventions suggested here to see if it resolves your issue?

@Julien-Marpault
Copy link
Author

It was a mistake when I wrote the ticket.
I found the solution in the meantime.

IViewLocalizer custom implementation plus assembly decorators.
I'll write a blog post about it and link it here.

@MackinnonBuck
Copy link
Member

Glad you were able to resolve the issue, @Julien-Marpault! I'm going to close this issue out, but please feel free to comment with your blog post link for others who run into this.

@MackinnonBuck MackinnonBuck closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2022
@MackinnonBuck MackinnonBuck added the ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. label Oct 27, 2022
@ghost ghost added the Status: Resolved label Oct 27, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Nov 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-localization ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. investigate Status: Resolved
Projects
None yet
Development

No branches or pull requests

4 participants