本节介绍的是Microsoft.AspNet.Localization工程。该工程是运行在Asp.net 5环境中的运行时多语言设置。

ASP.net 5中间件技术

在新的Asp.net 5中,可以将组件组册到asp.net环境中。注册是通过接口IApplicationBuilder的扩展方法实现的。

 public static IApplicationBuilder UseMiddleware(this IApplicationBuilder builder, Type middleware, params object[] args)

[该扩展方法通过可变参数args传递所需要的参数以及外的RequestDelegate(delegate Task RequestDelegate(HttpContext context))类型(系统会在内部给该类型参数赋值)。创建Type(middleware)类型实例。之后调用Type(middleware)的Invoke方法,不过和构造函数不同的是,当Invoke方法参数大于一个时,参数全部来自于以来注入,而不是args]

通过IApplicationBuilder注入的中间件,必须有一个方法是Invoke,Invoke方法的参数是可变参数,长度不受限制,系统会从asp.net的反转控制中获取参数;系统之后会调用该Invoke方法。[此处有疑问:为啥不定义成包含invoke方法的接口,更加面向对象]

我们在Microsoft.AspNet.Localization工程中可以找到俩个类:

  • IApplicationBuilderExtensions 中间注册方法,在Microsoft.AspNet.Localization工程中的实现。
  • RequestLocalizationMiddleware 中间件类,是Microsoft.AspNet.Localization的入口。
    public static class IApplicationBuilderExtensions
{
public static IApplicationBuilder UseRequestLocalization([NotNull] this IApplicationBuilder builder)
{
var options = new RequestLocalizationOptions(); return UseRequestLocalization(builder, options);
} public static IApplicationBuilder UseRequestLocalization(
[NotNull] this IApplicationBuilder builder,
[NotNull] RequestLocalizationOptions options)
=> builder.UseMiddleware<RequestLocalizationMiddleware>(options);
}

IApplicationBuilderExtensions

    public class RequestLocalizationMiddleware
{
private readonly RequestDelegate _next;
private readonly RequestLocalizationOptions _options; public RequestLocalizationMiddleware([NotNull] RequestDelegate next, [NotNull] RequestLocalizationOptions options)
{
_next = next;
_options = options;
} public async Task Invoke([NotNull] HttpContext context)
{
var requestCulture = _options.DefaultRequestCulture ??
new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); IRequestCultureProvider winningProvider = null; if (_options.RequestCultureProviders != null)
{
foreach (var provider in _options.RequestCultureProviders)
{
var result = await provider.DetermineRequestCulture(context);
if (result != null)
{
requestCulture = result;
winningProvider = provider;
break;
}
}
} context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider)); SetCurrentThreadCulture(requestCulture); await _next(context);
} private static void SetCurrentThreadCulture(RequestCulture requestCulture)
{
#if DNX451
Thread.CurrentThread.CurrentCulture = requestCulture.Culture;
Thread.CurrentThread.CurrentUICulture = requestCulture.UICulture;
#else
CultureInfo.CurrentCulture = requestCulture.Culture;
CultureInfo.CurrentUICulture = requestCulture.UICulture;
#endif
}
}

RequestLocalizationMiddleware

注册前的参数RequestLocalizationOptions

IApplicationBuilderExtensions中,我们对于中间件RequestLocalizationMiddleware注册时,需要传入RequestLocalizationOptions类型的实例,大多数时候传入的都是默认的无参实例。

我们看RequestLocalizationOptions类只有4个属性,代码如下:

public class RequestLocalizationOptions
{
public RequestLocalizationOptions()
{
DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider { Options = this },
new CookieRequestCultureProvider { Options = this },
new AcceptLanguageHeaderRequestCultureProvider { Options = this }
};
}
public RequestCulture DefaultRequestCulture { get; set; }
public IList<CultureInfo> SupportedCultures { get; set; }
public IList<CultureInfo> SupportedUICultures { get; set; }
public IList<IRequestCultureProvider> RequestCultureProviders { get; set; }
}

我们看到在无参的构造函数中,系统初始化了DefaultRequestCulture和RequestCultureProviders。系统会遍历RequestCultureProviders寻找适应的语言,当找不到合适的语言时,使用DefaultRequestCulture。

  • RequestCultureProviders:默认初始化三种多语言提供源:queryString、cookie、acceptHeader。
  • SupportedCultures:系统支持的语言
  • SupportedUICultures:系统支持的UI语言
  • DefaultRequestCulture:默认的语言源

[当我们需要自定义RequestCultureProvider时,我们有俩种方式,自定义类继承类RequestCultureProvider(或者直接继承接口IRequestCultureProvider),或者将CustomRequestCultureProvider注册到RequestCultureProviders中,并在CustomRequestCultureProvider类构造函数中注册Task<RequestCulture>方法]

注册时的顺序

系统是按照RequestLocalizationOptions中RequestCultureProviders的顺序获取合适的语言,如果没有则使用DefaultRequestCulture。默认情况,系统会根据queryString、cookie、acceptHeader(默认最多取前三项语言)的顺序读取<是短路算法>。

注册后的RequestCultureFeature

Asp.net5 的运行时环境Context可以注册不同类型的参数,所以系统最后注册了IRequestCultureFeature接口的实例。

 context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider));

整体结构

整个工程的文件可以用以下结构表示:

[Asp.net 5] Localization-Asp.net运行时多语言的更多相关文章

  1. ASP.NET Core3.0 中的运行时编译

    运行时编译 通过 Razor 文件的运行时编译补充生成时编译. 当 .cshtml 文件的内容发生更改时,ASP.NET Core MVC 将重新编译 Razor 文件 . 通过 Razor 文件的运 ...

  2. [ASP.NET Core MVC] 如何实现运行时动态定义Controller类型?

    昨天有个朋友在微信上问我一个问题:他希望通过动态脚本的形式实现对ASP.NET Core MVC应用的扩展,比如在程序运行过程中上传一段C#脚本将其中定义的Controller类型注册到应用中,问我是 ...

  3. Windows Store App 全球化:运行时响应语言变更

    在应用程序运行过程中,系统的语言.像素.对比度等系统设置可能会发生改变,应用程序应根据系统环境的改变及时做出适当的响应.为了解决这样的问题,可以在应用程序中为系统状态更改事件注册事件处理方法,当语言. ...

  4. cefSharp 设置运行时系统语言

    在使用用CefSharp使用过程中,系统用了很多第三方控件.这些控件很多能够根据浏览器设置的语言来进行控件展示对应语言. 在cefSharp可以设置系统语言,代码如下: CefSharp.Settin ...

  5. Runtime运行时的那点事儿

    注:本文是对 Colin Wheeler 的 Understanding the Objective-C Runtime 的翻译. 初学 Objective-C(以下简称ObjC) 的人很容易忽略一个 ...

  6. ASP.NET 5运行时升级到Beta5

    在Visual Studio 2015 RTM和Windows 10正式发布之前,微软把开源.NET升级到了beta5,带来了一些增强和改变.和Visual Studio 2015 RC一起安装的AS ...

  7. ASP.NET 运行时详解 揭开请求过程神秘面纱

    对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就 ...

  8. ASP.NET运行时详解 集成模式和经典模式

    遗留问题 在<ASP.NET运行时详解 生命周期入口分析>中遗留两个问题,包括Application的InitInternal方法执行细节.IIS6和II7经典模式请求管道管理类Appli ...

  9. ASP.NET运行时详解 生命周期入口分析

    说起ASP.NET的生命周期,网上有很多的介绍.之前也看了些这方面的博客,但我感觉很多程序猿像我一样,看的时候似乎明白,一段时间过后又忘了.所以,最近Heavi花了一段时间研究ASP.NET的源代码, ...

随机推荐

  1. 使用 Productivity Power Tools 2013来帮助你提高 VS2013的工作效率

    Visual Studio Gallery中发布了Productivity Power Tools 2013 的更新.在此版本中,此版本解决了客户报告的大量错误和问题,并介绍了一项称为语法行压缩的新功 ...

  2. 解读ASP.NET 5 & MVC6系列(6):Middleware详解

    在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章我们就来一一分析,在这里如 ...

  3. Python黑帽编程 3.2 ARP监控

    Python黑帽编程 3.2 ARP监控 在第3.1节<ARP欺骗>中,我们学习了ARP的基本原理,使用Python实现了我们自己的ARP欺骗工具.在上一节的基础上,我们来实现一个ARP监 ...

  4. 相识HTML5 canvas

    Canvas是HTML的API,我们可以用它在网页中实时的来生成图像. 文章导读 1.必备技能 2.用于画图的函数 例子: -会话气泡-    -心形-    -钟表-      -星球里的星星- - ...

  5. [SDK2.2]SQL Azure (13) Azure的两种关系型数据库服务:SQL Azure与SQL Server VM的不同

    <Windows Azure Platform 系列文章目录> 如果熟悉Windows Azure平台的用户不难发现,对于SQL Server数据库来说,微软提供了两种服务,分别是: -W ...

  6. Step by Step 创建一个新的Dynamics CRM Organization

    原创地址:http://www.cnblogs.com/jfzhu/p/4012833.html 转载请注明出处 前面演示过如何安装Dynamics CRM 2013,参见<Step by st ...

  7. gulp思考

    Gulp,一个基于流的构建工具. 这是自己写的一个构建的demo,只是一个纯演示的示例,并没有完成什么项目工作.下面根据这个demo介绍一下Gulp. 上代码: gulpfile.js 'use st ...

  8. 2013 duilib入门简明教程 -- 自绘控件 (15)

        在[2013 duilib入门简明教程 -- 复杂控件介绍 (13)]中虽然介绍了界面设计器上的所有控件,但是还有一些控件并没有被放到界面设计器上,还有一些常用控件duilib并没有提供(比如 ...

  9. WCF 安全性 之 Windows

    案例下载 http://download.csdn.net/detail/woxpp/4113172 服务端配置代码 <system.serviceModel> <services& ...

  10. JS原生第五篇 (帅哥)

    1.1 节点 1. 节点        网页是有很多的节点组成的  . 元素节点   指的是 :  标签     li  span 文本节点      属性节点 父子兄弟    父    parent ...