首页 > 代码库 > (002).NET大型B2C开源项目nopcommerce解析——安装页面

(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 =http://www.mamicode.com/ 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;        }

        这个方法的总流程(包括调用的子方法)是:

  1. 获取“nop.installation.lang”的cookie值
  2. 遍历并读取“/App_Data/Localization/Installation/”目录下符合命名要求(正则表达式)的XML文件,将其中子节点信息(页面所用字符串)储存在InstallationLanguage对象中,将 根节点(<Language Name="简体中文" IsDefault="false" IsRightToLeft="false">)储存在List<InstallationLocaleResource> 中。
  3. 根据List<InstallationLocaleResource>中的Code属性匹配cookie值,得出当前语言对象InstallationLanguage
  4. 如果cookie匹配不上(没有cookie),则根据浏览器中Request.UserLanguages的首选项(httpContext.Request.UserLanguages.FirstOrDefault())匹配Code属性
  5. 如果还是匹配不上,则返回IsDefault属性为true的XML对应的InstallationLanguage
  6. 如果完全匹配不上,则返回任意XML对应的InstallationLanguage
  7. 如果出什么意外,GetCurrentLanguage返回null的话就直接输出传过来的字符串
  8. 如果没什么意外的话就根据字符串在 List<InstallationLocaleResource>匹配符合条件的信息并返回

以上操作涉及到的实现类主要是InstallationLocalizationService。

        而功能就完成了。

1.2变更区域文字

        页面输出的下拉框是这样子的:

image

        nopcommerce的实现则是下拉框变更触发onchange事件(onchange="window.location.href = http://www.mamicode.com/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)

(002).NET大型B2C开源项目nopcommerce解析——安装页面