• ASP.NET系统整合DiscuzNT3.6之注意事项


      最近在做一个ASP.NET的系统,需要与Discuz整合实现双向登录、注册、修改密码这些简单的集成。

      查了一些资料,最后还是选择了官方提供的DiscuzToolkit,由于是开源的,所以用起来也方便,可以根据自己的需求做一些调整,在此也感谢DZ团队。

      第一步,当然还是将论坛安装好,调试好,一切正常。

      第二步,学习官方提供API文档,http://nt.discuz.net/showtopic-66493.aspx

      第三步,查看官方提供的示例文档,http://nt.discuz.net/showtopic-81187.aspx

      第四步,项目中引入Discuz.Toolkit.dll(可直接将开源的项目添加到项目中)在网站中增加同步登录或注册BBS帐号的方法,登录后或注册完成时,如下:

    View Code
    //......登录代码,登录成功后。
    
    //将登录信息同步论坛,若没有此会员则 注册
    try
    {
        DiscuzSession ds = DiscuzSessionHelper.GetSession();
        Discuz.Toolkit.User user = null;
        try
        {
            user = ds.GetLoggedInUser().GetUserInfo();
        }
        catch { }
        if (user == null || user.UserName != _user.UserName)
        {
            int uid = ds.GetUserID(_user.UserName);
            if (uid < 1)
            {
                //注册新用户
                uid = ds.Register(_user.UserName, password, _user.Email, true);
                //填充基本信息
                UserForEditing ufe = new UserForEditing();
                ufe.RealName = _user.ActualName;
                ufe.IdCard = _user.IdCard;
                ufe.Mobile = _user.Phone;
                ufe.Phone = _user.Tel;
                ufe.Gender = _user.Gender.ToString();
                ufe.NickName = _user.ActualName;
                ufe.GroupId = 10;//会员等级,可能采用特殊组来做一些其它应用。
                ds.SetUserInfo(uid, ufe);
            }
            //同步登录
            ds.Login(uid, password, true, 0, "");
        }
    }
    catch (Exception ex)
    {
        LogHelper.WriteLog(ex); //错误日志
    } 
    注册或修改密码对应的方法中,同步方法如下:
    View Code
    DiscuzSession ds = DiscuzSessionHelper.GetSession();
    int uid = 0;
    try
    {
        //user = ds.GetLoggedInUser().GetUserInfo();
        uid = ds.GetUserID(oldm.UserName);
    
        if (uid > 0)
        {
            //TODO:Discuz.Web.Services.Actions.Users 与 Discuz.Toolkit.User要对应起来  UserForEditing也一样
            //填充基本信息
            UserForEditing ufe = new UserForEditing();
            ufe.RealName = model.ActualName;
            ufe.IdCard = model.IdCard;
            ufe.Mobile = model.Phone;
            ufe.Phone = model.Tel;
            ufe.Gender = model.Gender.HasValue ? model.Gender.ToString() : "0";
            ufe.NickName = model.ActualName;
            ufe.Password = model.Password;
            ufe.GroupId = model.Level.Value + 16;
            ufe.UserName = model.UserName;
            ufe.Email = model.Email;
            ufe.WebSite = "";
            ufe.Location = "";
            ds.SetUserInfo(uid, ufe);
        }
    }
    catch(Exception ex) {
        LogHelper.WriteLog(ex);
    } 

       以上GroupId、UserName属性,在官方提供的开源项目UserForEditing类中没有这两个属性,我们可以手动加入一下,同时要注意Discuz.Web.Services.Actions.Users 与 Discuz.Toolkit.User要对应起来  UserForEditing也一样,如下: 

    View Code
    //Discuz.Web.Services.API下UserForEditing类中增加:
    
    [JsonPropertyAttribute("group_id")]
    public int? GroupId; //用户组ID
    
    [JsonPropertyAttribute("user_name")]
    public string UserName; //用户名
    
    
    
    //Discuz.Web.Services.API.Actions下Users类的SetInfo()方法中增加:
    
    //组别
    
    if (ufe.GroupId.HasValue)
    {
        userinfo.Groupid = ufe.GroupId.Value;
    }
    //用户名
    if (ufe.UserName != null && ufe.UserName!="")
    {
        userinfo.Username = ufe.UserName;
    }

     如果Services中与前面调用的类属性不一致的话,会出现序列化异常。  

    至此,我们已经实现了网站到论坛的同步登录、注册、修改基本信息功能。


    接下来就是实现,论坛到网站的同步登录、注册、修改了,在这里仅以登录为例,其它都差不多。 
      在这部分,我们就要使用官方提供的API操作了。

      第一步,需要在后台“扩展” - “整合设置” 那里加上调用URL,如图:

      上面,同步数据的URL地址为网站中的一个处理页面,主要就是在这个页面里实现同步操作。

      第二上,了解参数类型,DZ的同步机制是,在论坛有登录、注册等动作操作后,通过javascript脚本,向指定的URL地址传递参数的方式实现通信,参数的基本格式为uid=1&user_name=test&time=1270283913981&action=login&sig=dskljoiwjelkjskdjfoiwelkjsifs。可以在官方提供的API说明中了解这些参数的作用,特别是sig的生成。

      第三步,了解Discuz.Forum.Sync类中各种action的值及参数,方便在网站的api页面中处理。

      接下来,我们来实现登录同步,如下:

    View Code
    private DiscuzSession ds;
    private string action = "", user_name, password;
    private int uid = 0;
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            ds = DiscuzSessionHelper.GetSession();
            if (!IsPostBack)
            {
                action = Handler.RequestQueryString("action");
                uid = Handler.RequestQueryInt("uid");
                user_name = Handler.RequestQueryString("user_name");
                password = Handler.RequestQueryString("password");
                if (action != "" && check_sig()) //验证sig是否合法
                {
                    switch (action)
                    {
                        case "login": //同步登录:uid,user_name,time,action 正序后 + secret(密钥) Md5后 算出sig
                            Login();
                            break;
                        case "logout": //同步退出
                            LoginOut();
                            break;
                        case "updatepwd": //同步修改密码
                            break;
                    }
                }
            }
        }
        catch (Exception ex) {
            LogHelper.WriteLog(ex);
        }
    }
    
    /// <summary>
    /// 登录
    /// </summary>
    private void Login() {
        Discuz.Toolkit.User user= ds.GetUserInfo(uid);
        if (user != null)
            MemberOp.ValidateLogin(user.UserName, user.Password, true);
    }
    /// <summary>
    /// 退出
    /// </summary>
    private void LoginOut()
    {
        MemberOp.LoginOut(false);
    } 

      以上check_sig()方法里,主要就是验证sig是否正确,这个值是通过参数排序后md5出来的,具体过程可以参考方法:Discuz.Forum.Sync.GetUrl()。

      注意密钥apikey、secret、url这几个值一定要配置正确。至此已实现论坛到网站的同步登录和退出。 

    DiscuzToolkit线程同步,相信这两个问题肯定会碰到:

    (1)在注册用户时,碰到以下异常:当前会话所提交的call_id没有大于前一次的call_id

    (2)注册用户时,碰到以下异常:An item with the same key has already been added.

    解决办法:http://www.cnblogs.com/baihmpgy/archive/2012/04/09/2438720.html

    解决方案中,有一处线程锁的问题:

    lock (_syncRoot)  可直接用 lock (this)

  • 相关阅读:
    Xcode工程编译错误之iOS开发之The Xcode build system has crashed. Please close and reopen your workspace
    flutter学习之二Material Design设计规范
    Instruments之Xcode Analyze 代码静态检查及问题解决
    【Flutter学习】之MaterialApp和Scaffold组件使用详解
    ItunesConnect:"Missing Push Notification Entitlement"警告-----以及解决方法
    iOS 微信打开第三方应用(Universal Links 和 URL Schemes)
    关于代理服务器的原理及用法
    Xcode工程编译错误之iOS开发之Sending '__strong typeof (xxx)' (aka 'xxxx *__strong') to parameter of incompatible type 'id<xxx>'
    HL AsySocket 服务开发框架
    feign hystrix 线程池伸缩控制
  • 原文地址:https://www.cnblogs.com/greatwang/p/2711804.html
Copyright © 2020-2023  润新知