(002).NET大型B2C开源项目nopcommerce解析——安装页面
本文主要介绍安装页面涉及到实现的功能以及原理。
初次启动nopcommerce会进入一个URL为”/install”的页面,这个页面涉及到了2个功能:1.页面全球化;2.数据准备工作。
0.储备知识
特性
javascript事件
cookie
多活动结果集
1.页面全球化
1.1显示区域文字
在安装页面右下角有一个选择区域语言功能,可以看到里面有相当多的语言可供选择。选择完对应区域后,页面的文字也会相应变化。
页面全球化有一种最简单的实现就是分文件夹建站,比如微软的MSDN,但是同一个页面共有的基础设计恐怕非常冗余——我是指最差的情况。
而微信的实现则是路由参数,比如。
nopcommerce的页面是强类型视图。开发者在Nop.Web-InstallController-Index()里定义好了视图模型InstallModel然后往页面输出。
[Validator(typeof(InstallValidator))] public partial class InstallModel : BaseNopModel { public InstallModel() { this.AvailableLanguages = new List<SelectListItem>(); } [AllowHtml] public string AdminEmail { get; set; } [AllowHtml] [DataType(DataType.Password)] public string AdminPassword { get; set; } [AllowHtml] [DataType(DataType.Password)] public string ConfirmPassword { get; set; } [AllowHtml] public string DatabaseConnectionString { get; set; } public string DataProvider { get; set; } public bool DisableSqlCompact { get; set; } //SQL Server properties public string SqlConnectionInfo { get; set; } [AllowHtml] public string SqlServerName { get; set; } [AllowHtml] public string SqlDatabaseName { get; set; } [AllowHtml] public string SqlServerUsername { get; set; } [AllowHtml] public string SqlServerPassword { get; set; } public string SqlAuthenticationType { get; set; } public bool SqlServerCreateDatabase { get; set; } public bool UseCustomCollation { get; set; } [AllowHtml] public string Collation { get; set; } public bool DisableSampleDataOption { get; set; } public bool InstallSampleData { get; set; } public List<SelectListItem> AvailableLanguages { get; set; } }
这里特性和继承基类先不要管。大致说明一下就是,这个特性是视图验证框架FluentValidation用的,而父类是领域对象基类。
页面设计地区区域的字符串通过GetResource(string resourceName)方法统一生成。
/// <summary> /// Get locale resource value /// </summary> /// <param name="resourceName">Resource name</param> /// <returns>Resource value</returns> public string GetResource(string resourceName) { var language = GetCurrentLanguage(); if (language == null) return resourceName; var resourceValue = language.Resources .Where(r => r.Name.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase)) .Select(r => r.Value) .FirstOrDefault(); if (String.IsNullOrEmpty(resourceValue)) //return name return resourceName; return resourceValue; }
这个方法的总流程(包括调用的子方法)是:
- 获取“nop.installation.lang”的cookie值
- 遍历并读取“/App_Data/Localization/Installation/”目录下符合命名要求(正则表达式)的XML文件,将其中子节点信息(页面所用字符串)储存在InstallationLanguage对象中,将 根节点(<Language Name="简体中文" IsDefault="false" IsRightToLeft="false">)储存在List<InstallationLocaleResource> 中。
- 根据List<InstallationLocaleResource>中的Code属性匹配cookie值,得出当前语言对象InstallationLanguage
- 如果cookie匹配不上(没有cookie),则根据浏览器中Request.UserLanguages的首选项(httpContext.Request.UserLanguages.FirstOrDefault())匹配Code属性
- 如果还是匹配不上,则返回IsDefault属性为true的XML对应的InstallationLanguage
- 如果完全匹配不上,则返回任意XML对应的InstallationLanguage
- 如果出什么意外,GetCurrentLanguage返回null的话就直接输出传过来的字符串
- 如果没什么意外的话就根据字符串在 List<InstallationLocaleResource>匹配符合条件的信息并返回
以上操作涉及到的实现类主要是InstallationLocalizationService。
而功能就完成了。
1.2变更区域文字
页面输出的下拉框是这样子的:
nopcommerce的实现则是下拉框变更触发onchange事件(onchange="window.location.href = this.value;"),继而发出get请求页面。
从结果上看页面的路由没有变化,但其实这是ChangeLanguage重定向的结果:
public ActionResult ChangeLanguage(string language) { if (DataSettingsHelper.DatabaseIsInstalled()) return RedirectToRoute("HomePage"); _locService.SaveCurrentLanguage(language); //Reload the page return RedirectToAction("Index", "Install"); }
而中间的_locService.SaveCurrentLanguage(language);将名为“nop.installation.lang”的cookie的值变更为请求的语言类型。
public virtual void SaveCurrentLanguage(string languageCode) { var httpContext = EngineContext.Current.Resolve<HttpContextBase>(); var cookie = new HttpCookie(LanguageCookieName); cookie.HttpOnly = true; cookie.Value = languageCode; cookie.Expires = DateTime.Now.AddHours(24); httpContext.Response.Cookies.Remove(LanguageCookieName); httpContext.Response.Cookies.Add(cookie); }
因为cookie变更了,所以GetResource方法得到字符串也会根据当前区域变更。
第一句代码正如其表述一般,是判断数据库已经安装后,根据HomePage这个规则,重定向到主页。
2.数据准备工作
导入数据相比就比较简单。通过一系列判断后执行多活动结果集(sql脚本)。主要是由于强类型属性比较多,所以其POST action if else 比较多。这些操作执行完后其实还有一个插件安装和权限安装的流程,自己看源代码吧。
InstallController-public ActionResult Index(InstallModel model)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。