多WebService的状态同步以及实现WebService基类

     WebService非常轻量,基于SOAP,在做客户端程序的时候,可以借助VS的自动生成代理类,相比较于Web Api还需要自己手写访问代码省了很多事情,做一些小型的和简单的服务非常方便。之前使用WebService的时候都是用一个asmx文件,将所有代码揉在一个文件里,代码写多了,看的有点头大。今天就试着将这些代码拆分一下,在一个Web项目里,创建多个asmx文件,为了便于共用代码,需要有一个基类,其它的WebService类均从这个基类派生;另一个也同时测试下多个asmx的cookie是否能同步。

1、首先在VS中搭建项目结构,首先建立一个空白解决方案,我将这个空白解决方案取名为“WebServiceTest”;

2、然后依次添加2个项目,项目名和类型如下所示;

项目名称 项目类型
Services 空白的Asp.net Web应用程序项目
ClientWindows窗体应用程序

项目结构最后的效果如下:

1

3、接下来在Services项目中新建类文件:BaseService.cs。

注意不要建成了asmx文件,同时将其声明为abstract,否则在Client项目里引用的时候,会将这个BaseService识别为一个独立的WebService

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Services
{
    public abstract class BaseService : WebService
    {
        [WebMethod(EnableSession = true)]
        public string CurrentUser()
        {
            return Context.Session["CurrentUser"]?.ToString();
        }
    }
}

4、接下来新建一个WebService文件:UserService.asmx,该WebService继承自BaseService,模拟一个简单的登录效果,其代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Services
{
    /// <summary>
    /// Service1 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/User")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class UserService : BaseService
    {
        [WebMethod(EnableSession = true)]
        public bool Login(string name, string pwd)
        {
            if (AppContext.LoginUsers.Contains(name))
            {
                Context.Session["CurrentUser"] = name;
                return true;
            }
            if (AppContext.Users.Keys.Contains(name) && AppContext.Users[name] == pwd)
            {
                AppContext.LoginUsers.Add(name);
                Context.Session["CurrentUser"] = name;
                return true;
            }
            return false;
        }

        [WebMethod(EnableSession =true)]
        public void LogOut()
        {
            string name = Session["CurrentUser"]?.ToString();
            if (!string.IsNullOrEmpty(name) && AppContext.LoginUsers.Contains(name))
            {
                AppContext.LoginUsers.Remove(name);
            }
            Session["CurrentUser"] = null;
        }
    }
}

5、新建一个AppContext文件,用于模拟所有用户信息,并用于存储当前所有登录用户的信息,代码如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Services
{
    public class AppContext
    {
        public static Dictionary<string,string> Users = new Dictionary<string, string>()
        {
            { "user1","111"},
            { "user2","111"},
            { "alexywt","111"}
        };

        public static List<string> LoginUsers = new List<string>();
    }
}

6、再添加一个WebService文件:TestService.asmx,这个文件只是为了检验2个不同的WebService可以共用同一session、cookie而设,不需要再添加任何方法,直接使用继承自BaseService的方法验证即可,代码如下;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Services
{
    /// <summary>
    /// TestService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/Test")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class TestService : BaseService
    {

    }
}

7、在Client项目中的窗体中添加3个按钮,1个文本框,界面如下所示;

1

对象 描述
文本框 输入登录用户名
“登录”按钮 调用UserService的Login方法进行登录操作
“退出”按钮 调用UserService的LogOut方法进行退出操作
“查看”按钮 调用TestService的CurrentUser方法获取当前用户,并显示

窗体的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;

namespace Client
{
    public partial class Form1 : Form
    {
        private static CookieContainer cookieBox = new CookieContainer();

        private UserServiceRef.UserService userService;

        private TestServiceRef.TestService testService;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string name = textBox1.Text;
            if (string.IsNullOrEmpty(name)) return;

            userService = new UserServiceRef.UserService();
            userService.CookieContainer = cookieBox;
            userService.Credentials = CredentialCache.DefaultCredentials;

            userService.Login(name, "111");
            name = userService.CurrentUser();
            MessageBox.Show(name);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            testService = new TestServiceRef.TestService();
            testService.CookieContainer = cookieBox;
            testService.Credentials = CredentialCache.DefaultCredentials;

            string name = testService.CurrentUser();
            MessageBox.Show(name);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (userService == null) return;
            userService.LogOut();
        }
    }
}

8、先将2个项目编译一下,然后只启动Web项目Services,在Client项目的“\bin\Debug”目录下,运行“client.exe”三次,打开3个客户端,分别输入账号,并登录,分别点击查看,得到3个不同的用户名,点击其中1个退出按钮,再点击3个查看按钮,可以发现只有当前客户端退出了,另2个客户端没有影响,说明对于同一个Client程序,cookie没有影响。

1

posted @ 2021-06-12 23:07  alexywt  阅读(232)  评论(0编辑  收藏  举报