LazZiya / XLocalizer

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

Value cannot be null. (Parameter 'source') #47

Closed faresayyad closed 4 months ago

faresayyad commented 4 months ago

Hello I am getting this error when trying to start the application ArgumentNullException: Value cannot be null. (Parameter 'source') System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) System.Linq.Enumerable.Any(IEnumerable source, Func<TSource, bool> predicate) XLocalizer.Routing.RouteSegmentRequestCultureProvider.DetermineProviderCultureResult(HttpContext httpContext) Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.g__AwaitMatcher|8_0(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matcherTask) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

I followed this tutorial to setup XLocalizer : https://ziyad.info/en/articles/1040-XLocalizer_for_Asp_Net_Core

I am using .net 7, anyone passed by this issue and can help ?

LazZiya commented 4 months ago

It seems an issue with the supported cultures and default culture setup. Can you share the startup.cs?

faresayyad commented 4 months ago

Sure, but there are no startup.cs as am using .net 7, therefore I will share the program.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Starter.DAL.Repository.IRepository;
using Starter.DAL.Repository;
using Starter.DAL.EF;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Localization;
using System.Globalization;
using XLocalizer.Routing;
using XLocalizer.Xml;
using XLocalizer;
using XLocalizer.Translate;
using XLocalizer.Translate.MyMemoryTranslate;
using Starter.Web.LocalizationResources;
using XLocalizer.ErrorMessages;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddAutoMapper(typeof(Program));

builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("BloggingDatabase")));

builder.Services.AddDefaultIdentity<IdentityUser>(
    options =>
    {
        //SignIn
        options.SignIn.RequireConfirmedAccount = builder.Configuration.GetValue<bool>("Identity:SignIn:RequireConfirmedAccount");
        options.SignIn.RequireConfirmedEmail = builder.Configuration.GetValue<bool>("Identity:SignIn:RequireConfirmedEmail");
        options.SignIn.RequireConfirmedPhoneNumber = builder.Configuration.GetValue<bool>("Identity:SignIn:RequireConfirmedPhoneNumber");
        //Password
        options.Password.RequireUppercase = builder.Configuration.GetValue<bool>("Identity:PasswordPolicy:RequireUppercase");
        options.Password.RequireLowercase = builder.Configuration.GetValue<bool>("Identity:PasswordPolicy:RequireLowercase");
        options.Password.RequiredLength = builder.Configuration.GetValue<int>("Identity:PasswordPolicy:RequiredLength");
        options.Password.RequireDigit = builder.Configuration.GetValue<bool>("Identity:PasswordPolicy:RequireDigit");
        options.Password.RequiredUniqueChars = builder.Configuration.GetValue<int>("Identity:PasswordPolicy:RequiredUniqueChars");
        //Lockout
        options.Lockout.MaxFailedAccessAttempts = builder.Configuration.GetValue<int>("Identity:Lockout:MaxFailedAccessAttempts");
        //User
        options.User.RequireUniqueEmail = builder.Configuration.GetValue<bool>("Identity:User:RequireUniqueEmail");
    }
    ).AddEntityFrameworkStores<ApplicationDbContext>();

var defaultCulture = builder.Configuration.GetValue<string>("Cultures:DefaultCulture");
builder.Services.Configure<RequestLocalizationOptions>(ops =>
{
    var cultures = builder.Configuration.GetValue<string[]>("Cultures:SupportedCultures")?.Select(m => new CultureInfo(m)).ToList();
    ops.SupportedCultures = cultures;
    ops.SupportedUICultures = cultures;
    ops.DefaultRequestCulture = new RequestCulture(defaultCulture);
    ops.RequestCultureProviders.Insert(0, new RouteSegmentRequestCultureProvider(cultures));
});

builder.Services.AddScoped<IUOW, UOW>();
builder.Services.AddScoped<Starter.Utils.EmailService.IEmailService, Starter.Utils.EmailService.EmailServcice>();
builder.Services.AddHttpClient<ITranslator, MyMemoryTranslateService>();
builder.Services.AddSingleton<IXResourceProvider, XmlResourceProvider>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

builder.Services.AddRazorPages().AddRazorPagesOptions(ops =>
{
    ops.Conventions.Insert(0, new RouteTemplateModelConventionRazorPages());
})
    .AddXLocalizer<LocSource, MyMemoryTranslateService>(ops =>
    {
        ops.ResourcesPath = "LocalizationResources";
        ops.AutoAddKeys = true;
        ops.AutoTranslate = true;
        ops.TranslateFromCulture = defaultCulture;
        ops.UseExpressMemoryCache = true;
        ops.LocalizeDefaultCulture = true;
        ops.ModelBindingErrors = new ModelBindingErrors
        {
            ValueMustBeANumberAccessor = "Value '{0}' should be a number"
        };
        ops.ValidationErrors = new ValidationErrors
        {

        };
    });

if (!string.IsNullOrEmpty(builder.Configuration.GetValue<string>("SocialNetworksLogins:Facebook:AppId")) &&
    !string.IsNullOrEmpty(builder.Configuration.GetValue<string>("SocialNetworksLogins:Facebook:AppSecret")))
{
    builder.Services.AddAuthentication().AddFacebook(facebookOptions =>
    {
        facebookOptions.AppId = builder.Configuration.GetValue<string>("SocialNetworksLogins:Facebook:AppId");
        facebookOptions.AppSecret = builder.Configuration.GetValue<string>("SocialNetworksLogins:Facebook:AppSecret");
        facebookOptions.AccessDeniedPath = "/AccessDeniedPathInfo";
    });
}

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

builder.Services.AddSession();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseRequestLocalization();

app.MapRazorPages();

app.MapControllerRoute(
    name: "default",
    pattern: "{culture=" + defaultCulture + "}/{controller=Home}/{action=Index}/{id?}",
    defaults: new { culture = defaultCulture, controller = "Home", action = "Index" });

app.Run();
LazZiya commented 4 months ago

Are the values assigned correctly?

var defaultCulture = builder.Configuration.GetValue<string>("Cultures:DefaultCulture");
builder.Services.Configure<RequestLocalizationOptions>(ops =>
{
    var cultures = builder.Configuration.GetValue<string[]>("Cultures:SupportedCultures")?.Select(m => new CultureInfo(m)).ToList();
    ops.SupportedCultures = cultures;
    ops.SupportedUICultures = cultures;
    ops.DefaultRequestCulture = new RequestCulture(defaultCulture);
    ops.RequestCultureProviders.Insert(0, new RouteSegmentRequestCultureProvider(cultures));
});
faresayyad commented 4 months ago

Actually no, I figured out the variable where I get the SupportedCultures from appsetting is null. I fix the code and it's working now. Thank you