ASP.Net: EshineASPNet教程-多语言与单一登录

之所以把这两个放在一起,是因为这两个模块都可以放在模板页面。大家新建网页的时候默认会继承System.Web.UI.Page,我们这里要把这个改一改,新建一个类,名字叫PageBases,这个类继承System.Web.UI.Page,然后手动修改以后我们创建的每一个页面,集成PageBases。这样的好处是,所有页面公用的属性和方法我们都在这里集中定义,其中包括了多语言和单一登陆。

多语言

Asp.Net多语言的实现用的是公共资源文件的方式,多个页面公用的文本放到App_GlobalResources里面,使用方法:
前台:Text=’<%$ Resources:GResource,titletext %>’
后台:(string)GetGlobalResourceObject(“GResource”, “titletext”)
专用页面的文本(即这些文本就这个页面的功能才会涉及别的页面不需要),放到App_LocalResources里面,每个页面有单独的文件来存储,使用方法:
前台:meta:resourcekey=”Localize1Resource1”
后台:(String)GetLocalResourceObject(“Localize1Resource1.Text”)
不管是Global还是Local,Resources文件夹里面的每一个文件都有不同语言的版本,例如
GResource.resx - 默认语言
GResource.en-us.resx - 英语(美国)
GResource.zh-cn.resx - 中文(中国)
系统根据设置自动把对应语言版本的文本替换到相应的文本位置,这个语言的设置就可以用代码实现了。我们可以重写页面的InitializeCulture()方法。

    protected override void InitializeCulture()
    {
        base.InitializeCulture();

        string s = Request.QueryString["language"];
        if (!String.IsNullOrEmpty(s))
        {
            Page.UICulture = s;
            Page.Culture = s;
            Session["language"] = s;
        }
        else if (!String.IsNullOrEmpty(Session["language"] as string))
        {
            this.UICulture = Session["language"].ToString();
            this.Culture = Session["language"].ToString();
        }
        return;
    }

这里根据url读取的language的值来设置页面语言,这是全局的,值保存在Session,后台也可以使用这个值。
前面讲的是页面文本的多语言处理,除了这个还有数据层面的多语言,也就是数据库里面的内容。其中一种方法是给表里面的每一个字段都设置多个字段来存储多语言版本,比如title,title_eng这样。然后根据Session来展示不同的值。例如:

            if (language == "en-us")
            {
                s = "select top 1 msg_eng from tab_news where id=" + id;
            }
            else
            {
                s = "select top 1 msg from tab_news where id=" + id;
            }

这个也language可以作为参数传进方法里面去。另外也可以把不同语言的数据存放在不同的表里面,但这时候注意千万不用光用自增id来匹配两条数据,否则以后会有麻烦的。笔者此前单位的老系统就是中文英文用的分开的表,切换只用id,但id经常会出现不同步,有1条不同步了后面的数据全都不同步,切记。

单一登录

大多数情况下,网页是允许多个人在同一时间用同一账号登陆的,但是有时候也会希望像游戏那样,重复登陆会把前面那个登陆的顶下去,这个完全是由业务决定的。
如果要实现单一登陆,不管是顶下去,还是后面的登不上,我们都需要采取一些机制,这里分享一种方法,先上代码。

    public bool AmIOnline(string s, Hashtable h)
    {
        //System.Web.SessionState.HttpSessionState Session = HttpContext.Current.Session;
        //Hashtable h = (Hashtable)Application["Online"];

        //继续判断是否该用户已经登陆 
        if (h == null)
            return false;

        //判断哈希表中是否有该用户 
        IDictionaryEnumerator e1 = h.GetEnumerator();
        bool flag = false;
        while (e1.MoveNext())
        {
            if (e1.Value.ToString().CompareTo(s) == 0)
            {
                flag = true;
                break;
            }
        }
        return flag;
    }

    public void CheckUser( Hashtable h)
    {
        //判断用户是否登陆
        if (Session["id"] == null || Session["id"] == "")
        {
            Response.Redirect("login.aspx", true);
        }
        try
        {
            if (!pc.AmIOnline(Session["id"] + "|" + Session["ip"], h))
            {
                //用户没有在线 ,转到登录界面
                Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "message", " <script>alert('本帐号在其他地方登陆!'); window.location.href = 'login.aspx';</script>");
                return;
            }
        }
        catch
        {
            //会话过期 ,转到登录界面
            Response.Redirect("login.aspx");
            return;
        }
    }

上面第一个函数AmIOnline()把当前Session的id和ip传进去,ip用来识别唯一,id用来检查用户并踢出。这里有个哈希表用来存储当前所有在线的用户,逐个检查发现匹配,则把原来的记录删除,因为每个页面都是继承这个PageBases的,在前一个用户继续浏览网页的时候,页面就会检查到记录为空就会跳转到登陆页面并提示帐号在其他地方登陆。用此逻辑来实现单一登陆。

本教程代码参考EshineASPNetWebApp_CodePageBases.cs

相关内容推荐