Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

原文: Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

为什么选择wcf?   因为好像wcf和wpf就是哥俩,,,

为什么选择异步调用?  用起来体验相对好一点,不会因为服务的速度影响用户体验,避免页面假死

首先新建一个wcf服务程序

public class ServiceLogin : IServiceLogin
    {
        public bool Login(string username, string pwd)
        {
            if ("root" == username && "root" == pwd)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public UserInfo GetUserInfo(string userid)
        {
            return new UserInfo() { username="root",fullname="管理员", role="admin",userid="1" };
        }
    }

这里暂时固定root用户,

客户端添加一个新的项目PW.SericeCenter,用来引用wcf服务,供其他各个模块调用

在引用时高级里勾选生成异步操作

ServiceComm 封装service,这里可以做一些数据的处理,比如PW.Common.UserInfo数据的转换,或者更为简便的你可以用json,因为wcf返回的对象Userinfo是在引用服务的生成的代码中,不宜做改动,最好是转换成自己的ViewModel,做数据绑定更为方便

public event System.EventHandler<ServicesEventArgs<bool>> LoginCompleted;
        public void Login(string username,string pwd)
        {
            ServiceLogin.ServiceLoginClient client = new ServiceLogin.ServiceLoginClient();
            client.LoginCompleted += (sender, e) =>
            {
                ServicesEventArgs<bool> arg = new ServicesEventArgs<bool>();

                if (e.Error == null)
                {
                    arg.Result = e.Result;
                    arg.Succesed = true;
                }
                else
                {
                    arg.Succesed = false;
                    arg.Error = e.Error;
                    //写错误日志
                    //.....
                }
                if (LoginCompleted != null)
                {
                    LoginCompleted.Invoke(this, arg);
                }
            };
            client.LoginAsync(username, pwd);
        }

public event EventHandler<ServicesEventArgs<PW.Common.UserInfo>> GetUserInfoCompleted;
        public void GetUserInfo(string userid)
        {
            ServiceLogin.ServiceLoginClient client = new ServiceLogin.ServiceLoginClient();
            client.GetUserInfoCompleted += (sender, e) =>
            {
                ServicesEventArgs<PW.Common.UserInfo> arg = new ServicesEventArgs<PW.Common.UserInfo>();

                if (e.Error == null)
                {
                    if (e.Result != null)
                    {
                        arg.Result = new PW.Common.UserInfo() { fullname = e.Result.fullname, role = e.Result.role, userid = e.Result.userid, username = e.Result.username };
                    }
                    else
                    {
                        arg.Result = null;
                    }

                    arg.Succesed = true;
                }
                else
                {
                    arg.Succesed = false;
                    arg.Error = e.Error;
                    //写错误日志
                    //.....
                }
                if (GetUserInfoCompleted != null)
                {
                    GetUserInfoCompleted.Invoke(this, arg);
                }
            };
            client.GetUserInfoAsync(userid);
        }

然后在login模块调用

ServiceComm sc = new ServiceComm();
                sc.LoginCompleted += (serice, eve) =>
                {
                    if (eve.Succesed && eve.Result)
                    {
//成功后balabala
                        GlobalData.EventAggregator.GetEvent<BaseDataLoadedEvent>().Publish(1);
                        LoadAllModules();
                        #region 独立存储区操作
                        try
                        {
                            if (IsolatedStorageFile.IsEnabled == true)
                            {
                                IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForAssembly();
                                IsolatedStorageFileStream isoFileStream = isoFile.OpenFile("login.txt", System.IO.FileMode.Create);
                                String loginStr = "";
                                if (this.cbxRemPassword.IsChecked == true)
                                {
                                    loginStr = String.Format("{0}", this.txtName.Text.Trim());
                                }
                                Byte[] bts = Encoding.UTF8.GetBytes(loginStr);
                                isoFileStream.Write(bts, 0, bts.Length);
                                isoFileStream.Close();
                                isoFile.Dispose();
                            }
                        }
                        catch (Exception)
                        {

                        }
                        #endregion
                        GlobalData.UserName = this.txtName.Text.Trim();
                    }
                    else
                    {
//失败后balabala
                        this.btnLogin.IsEnabled = true;
                        this.gcLogin.Visibility = Visibility.Visible;
                        this.loadingInfo.Visibility = Visibility.Collapsed;
                        MessageBox.Show("登陆失败!");
                    }
                };
                sc.Login(this.txtName.Text.Trim(), this.txtPassword.Password.Trim());

写完这些吐槽MessageBox.Show("登陆失败!");真的不是一般的难看。。。。有时间换掉

就是这么不协调,,,,登录等待画面暂时有些粗糙,有时间美化一下

登录成功的就和之前一样了。。。

本事wpf去调用wcf服务很简单,但是我搞了一天,主要耗时在了安全验证上面了,

最初想用x509,看了写文章,自己也试了试,很是麻烦,安装证书比较坑,好像是有客户端免安装证书的,但我还是放弃了x509

最后看到了csdn这个问题

https://bbs.csdn.net/topics/390774814/

我就按照消息头拦截这个做的

感觉可以扩展,实现不同的客户端不同的token ,然后每个用户每次登陆带着不同的token,虽然token被人截取了还是不安全,,,再研究吧

具体怎么嵌入到我的项目的就不细说了,论坛有demo连接

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/10657769.html
今日推荐