2022年4月
net core 多语言国际化,语言参数放在URL中的实现
本来最简单的做法,就是将语言选择放在cookie中,但出于对SEO的考虑,这样做无法让搜索引擎抓取多语种页面,最好的做法,还是不同语言有不同的路径,例如:
http://www.xxx.com/zh-ch/products
http://www.xxx.com/en-us/products
....
静态类 Langs.cs 中,定义可以用的语言:
public readonly static string[] LangCodes = new string[] { "vi-vn", "en-us", "zh-cn" };
识别用的路由约束类,其中的 "auto" 是特殊定义的,主要用于用户第一次进入时对用户的 Accept-Languages 进行自动识别:
public class LanguageRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (!values.ContainsKey("culture"))
return false;
var culture = values["culture"]?.ToString();
if (culture == null) return false;
return culture == "auto" || Langs.LangCodes.Contains(culture);
}
}
路由约束:
public class LanguageRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (!values.ContainsKey("culture"))
return false;
var culture = values["culture"]?.ToString();
if (culture == null) return false;
return culture == "auto" || Langs.LangCodes.Contains(culture);
}
}
然后在 program.cs 中配置:
builder.Services.AddRazorPages().AddRazorPagesOptions(options =>
{
options.Conventions.Add(new CulturePageRouteConvention());
}).AddRazorRuntimeCompilation();
builder.Services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("culture", typeof(LanguageRouteConstraint));
});
builder.Services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("culture", typeof(LanguageRouteConstraint));
});
路由:
app.MapControllerRoute(name: "default", pattern: "{culture:culture=auto}/{controller:slugify=Home}/{action:slugify=Index}/{id?}");
net core web 项目最高效、最规范的主动内存缓存实现
很多人会直接用静态类做内存缓存,包括我自己之前也是这样做,但这样内存的生命周期及GC机制得不到保障,特别是对于多线程的控制,静态类都是无能为力。
另外就是 MemoryCache,很多人都习惯用他的 MemoryCache.TryGetValue 来实现自动缓存,这对于小项目及访问量不大的项目是可行的,但如果对于大项目,这样会导致访问很慢,因为是被动式的去拉取数据,有没有一种更好的方式呢,好在net core 提供了 BackgroundService 及 IHostedService,两者类似,可以完美的解决我们的需求,这里我就举例说一下使用 IHostedService 来实现主动式缓存网站首页的全部数据,以实现最快速的首页访问。
新建逻辑处理服务类:
public class DbServices : IHostedService, IDisposable
{
CancellationToken cancelToken;
HomeData? datas;
Task? mainTask;
private ILogger logger;
public DbServices(ILogger logger)
{
this.logger=logger;
}
public HomeData? GetHomeData()
{
return datas;
}
public Task StartAsync(CancellationToken cancellationToken)
{
cancelToken = cancellationToken;
mainTask = Task.Factory.StartNew(HomeDataWork, cancellationToken);
return Task.CompletedTask;
}
private async void HomeDataWork()
{
DateTime last = DateTime.Now.AddMinutes(-2);
while (!cancelToken.IsCancellationRequested)
{
int sec = 30000 - (int)(DateTime.Now - last).TotalMilliseconds;
if (sec > 0)
await Task.Delay(sec);
last = DateTime.Now;
HomeData? _data = .....;//实现获取数据
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public void Dispose()
{
mainTask?.Dispose();
}
}
Program.cs 中:
builder.Services.AddSingleton<DbServices>();
builder.Services.AddHostedService<DbServices>(provider => provider.GetService<DbServices>());
大功造成,该服务会在后台主动更新内存数据,首页可以直接无任何延迟直接获取数据:
DbServices? service = MyHttpContext.Current?.RequestServices.GetService(typeof(DbServices)) as DbServices;
HomeData = service?.GetHomeData(Langs.Instance.LangCode) ?? new();
net core web 6.0 怎样做到不打包视图view文件,及怎样防止生成很多语言资源包
直接编辑 xxx.csproj 项目文件:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!--不打包视图文件-->
<RazorCompileOnBuild>false</RazorCompileOnBuild>
<RazorCompileOnPublish>false</RazorCompileOnPublish>
<!--防止生成很多语言资源包-->
<SatelliteResourceLanguages>zh-Hans;vi</SatelliteResourceLanguages>
</PropertyGroup>
Net core web 项目怎样输出日志到输出窗口
Program.cs 中:
var serviceProvider = builder.Services.BuildServiceProvider();
var logger = serviceProvider.GetService<ILogger<MyServices>>();
builder.Services.AddSingleton(typeof(ILogger), logger);
这样就会将 ILogger 注入到相关类中,可以直接通过构造函数来获取了:
private ILogger logger;
public void MyServices(ILogger logger)
{
this.logger = logger;
...
}