LazZiya / XLocalizer

Localizer package for Asp.Net Core web applications, powered by online translation and auto resource creating.
https://docs.ziyad.info
129 stars 14 forks source link

AmbiguousActionException when using services.AddMvc().AddXDbLocalizer<TDbContext, TTranslator>() #22

Closed morgrowe closed 3 years ago

morgrowe commented 3 years ago

Hi Ziya,

Hope you're well.

I've successfully added XLocalizer.DB to a RazorPages project, but I'm having issues adding it to an existing Mvc project. Despite changes I've tried to make, I either get the 'AmbiguousActionException' exception or the route localization doesn't work at all. It's a very simple project with only one controller.

sdfsdfdsffff

Here's the Startup.cs:

public class Startup
    {
        ...

        public void ConfigureServices(IServiceCollection services)
        {
           ...

            var connection = Configuration.GetConnectionString("WLPDB");
            services.AddDbContext<PreferenceFormDbContext>(options =>
                options.UseSqlServer(connection),
                ServiceLifetime.Transient,
                ServiceLifetime.Transient);

            services.Configure<RequestLocalizationOptions>(ops =>
            {
                var supportedCultures = new[]
                {
                    new CultureInfo("cy"),
                    new CultureInfo("en")
                };

                ops.SupportedCultures = supportedCultures;
                ops.SupportedUICultures = supportedCultures;
                ops.DefaultRequestCulture = new RequestCulture("en");

                ops.RequestCultureProviders.Insert(0, new RouteSegmentRequestCultureProvider(supportedCultures));
            });

            services.AddMvc(
                options => {
                    options.EnableEndpointRouting = false;
                })
                .AddMvcOptions(ops => { ops.Conventions.Insert(0, new RouteTemplateModelConventionMvc()); })
                .AddXDbLocalizer<PreferenceFormDbContext, DummyTranslator>(ops =>
                {
                    ops.AutoAddKeys = false;
                    ops.AutoTranslate = false;
                })
                .AddRazorRuntimeCompilation();
            }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRequestLocalization();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

And the Index method in the HomeController is very straight forward:

        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

I've got the exception to go away by removing:

    ops.RequestCultureProviders.Insert(0, new RouteSegmentRequestCultureProvider(supportedCultures));

and

    .AddMvcOptions(ops => { ops.Conventions.Insert(0, new RouteTemplateModelConventionMvc()); })

and updating my MapRoute to:

    routes.MapRoute(
        name: "default",
        template: "{culture=en}/{controller=Home}/{action=Index}/{id?}");

But doing this ignores the culture in the URL--it always returns "en", even if "cy" is in the URL.

Any guidance would be really appreciated. I'm more than likely doing something silly again.

Cheers Morgan

LazZiya commented 3 years ago

Hi @morgrowe , glad to see you again :)

For MVC you need to add [Route] attribute to the actions:

public class HomeController : Controller
{
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        [Route("")]
        public IActionResult Index()
        {
            return View();
        }

        [Route("Privacy")]
        public IActionResult Privacy()
        {
            return View();
        }
}

MVC Sample

morgrowe commented 3 years ago

Hi Ziya

Thank you, as always, for your quick response. Adding the Route decorators fixed that issue. :)

I have one final problem and I can't for the life of me figure out what's doing on.

I have seeded by database with the cultures and some dummy resources:

res

cul

It doesn't seem to be localizing strings unless the culture is set to my secondary one: cy. My default is en. So if I go to /, or /en the culture is correctly being set to en but the string isn't being localized:

xczxxx

However, if I go to /cy, it does get localized:

tesjfjsdfd

Any idea what's going on there? I bet I've misconfigured something in my Startup.cs. I haven't changed it since my original post.

Cheers Morgan

LazZiya commented 3 years ago

Hi @morgrowe

Actually this is already reported in a previous issue #19, I can't say it is a bug, but a design issue that needs enhancement.

I didn't publish an update yet, but it seems time is already came to fix this :)

morgrowe commented 3 years ago

I see! That makes sense. I agree it's not a bug, but it would be great to add the option mentioned in #19 to support key codes. I look forward to the update. :)

Thanks Morgan

LazZiya commented 3 years ago

Hi @morgrowe ,

Fix is available now.

BR, Ziya

LazZiya commented 3 years ago

And for DB version update to XLocalizer.DB v1.0.2

morgrowe commented 3 years ago

Brilliant, thanks Ziya :)