程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#WebService之Session之我見

C#WebService之Session之我見

編輯:C#入門知識

   這幾天一直在學習WebService的知識。正好現在有一個項目,需要在WebService實現如下接口: 

String Login(string username, string password) // 登錄方法,返回值用來指名是不是登錄成功,並且這個值在之後的接口中用來找到相對應的服務器上的session。

       因此WebService需要使用到Session,而網上大部分資料是說WebService是無狀態的(StateLess),不怎麼支持Session。因此難題出現了,首先在Web Serivice

放上聲明如下Attribute,[WebMethod(EnableSession = true)],此為表示在webService上能使用Session。

      現在放上我寫的WebService的例子代碼(service端):

view plaincopy to clipboardprint?/// <summary>  
/// Summary description for Service1  
/// </summary>  
[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.ComponentModel.ToolboxItem(false)] 
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.   
[System.Web.Script.Services.ScriptService] 
public class Bussiness : System.Web.Services.WebService 

     
    [WebMethod(Description = "登錄方法,返回值用來指名是不是登錄成功,並且這個值在之後的接口中用來找到相對應的服務器上的session", 
        EnableSession = true)] 
    public string Login(string username, string password) 
    { 
 
        string state = ""; 
        if (IsLogin(username)) 
            state = "Logined"; 
        else 
        { 
            state = UserHelper.Login(username, password); 
            if (state != null && state != "Failed")//  
            { 
                //Session.Timeout = 1;  
                Session[state] = username; 
            } 
        } 
        return state; 
 
    } 
    [WebMethod(Description = "判斷是否登錄", 
      EnableSession = true)] 
    private  bool  IsLogin(string name) 
    { 
        if (name != null &&  Session[name]!=null&& Session[name].ToString() == name) 
            return true; 
        return false; 
    } 
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class Bussiness : System.Web.Services.WebService
    {
       
        [WebMethod(Description = "登錄方法,返回值用來指名是不是登錄成功,並且這個值在之後的接口中用來找到相對應的服務器上的session",
            EnableSession = true)]
        public string Login(string username, string password)
        {

            string state = "";
            if (IsLogin(username))
                state = "Logined";
            else
            {
                state = UserHelper.Login(username, password);
                if (state != null && state != "Failed")//
                {
                    //Session.Timeout = 1;
                    Session[state] = username;
                }
            }
            return state;

        }
        [WebMethod(Description = "判斷是否登錄",
          EnableSession = true)]
        private  bool  IsLogin(string name)
        {
            if (name != null &&  Session[name]!=null&& Session[name].ToString() == name)
                return true;
            return false;
        }
 客戶端代碼,我用的是soap方式寫的,soap方式調用WebService的方法,我參看了《Programing Web Service with SOAP》。具體方式參看第三章的。我的客戶端SOAP代碼(我新建一個類)如下:

view plaincopy to clipboardprint?using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.Web.Services; 
using System.Web.Services.Protocols; 
using System.Xml.Serialization; 
 
namespace Test 

    [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")] 
    public class BusService : SoapHttpClientProtocol 
    { 
        public BusService() 
        { 
            // this.Url = "http://localhost:4243/Bussiness.asmx";  
             this.Url = "http://localhost/Bussiness/Bussiness.asmx"; 
        }  
        [System.Web.Services.Protocols.SoapDocumentMethod( 
            "http://tempuri.org/Login", 
            RequestNamespace = "http://tempuri.org/", 
            ResponseNamespace = "http://tempuri.org/", 
            Use = System.Web.Services.Description.SoapBindingUse.Literal, 
            ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 
        public string Login(string username, string password) 
        { 
            object[] result = this.Invoke("Login", 
                                            new object[] { username, password }); 
            return (string)result[0]; 
 
        } 
    } 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;

namespace Test
{
    [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")]
    public class BusService : SoapHttpClientProtocol
    {
        public BusService()
        {
            // this.Url = "http://localhost:4243/Bussiness.asmx";
             this.Url = "http://localhost/Bussiness/Bussiness.asmx";
        }
        [System.Web.Services.Protocols.SoapDocumentMethod(
            "http://tempuri.org/Login",
            RequestNamespace = "http://tempuri.org/",
            ResponseNamespace = "http://tempuri.org/",
            Use = System.Web.Services.Description.SoapBindingUse.Literal,
            ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public string Login(string username, string password)
        {
            object[] result = this.Invoke("Login",
                                            new object[] { username, password });
            return (string)result[0];

        }
    }
}
 

客戶點調用代碼,也就是用戶端的調用代碼,我寫的是控制台的測試代碼,如下:

view plaincopy to clipboardprint?namespace Test 

    public class Program 
    { 
        static void Main(string[] args) 
        { 
            string name = "admin"; 
            string password = "123"; 
            TestLogin tl = new TestLogin(name, password);             
            string state = tl.Login(); 
            Console.WriteLine("State = " + state); 
            state = tl.Login(); 
            Console.WriteLine("State = " + state); 
            Console.Read(); 
        } 
    } 
    public class TestLogin 
    { 
        public string name = ""; 
        public string psw = ""; 
        BusService bus = new BusService(); 
        public TestLogin(string name, string psw) 
        {          
            this.name = name; 
            this.psw = psw; 
          } 
        public string Login() 
        { 
            return bus.Login(this.name, this.psw); 
        } 
    }      

namespace Test
{
    public class Program
    {
        static void Main(string[] args)
        {
            string name = "admin";
            string password = "123";
            TestLogin tl = new TestLogin(name, password);           
            string state = tl.Login();
            Console.WriteLine("State = " + state);
            state = tl.Login();
            Console.WriteLine("State = " + state);
            Console.Read();
        }
    }
    public class TestLogin
    {
        public string name = "";
        public string psw = "";
        BusService bus = new BusService();
        public TestLogin(string name, string psw)
        {        
            this.name = name;
            this.psw = psw;
          }
        public string Login()
        {
            return bus.Login(this.name, this.psw);
        }
    }    
}
寫到這裡進行運行,感覺一切應該按照自己想想的正確的打印出來。打印結果應該是如下這樣的:

State = admin

State = Logined

結果實際運行的效果與自己設想的不太一樣,實際運行的結果是

State = admin

State = admin

這樣的運行結果說明,WebService 的Server端的Session,根本沒有保存。通過斷點調試發現,第二次讀取的Session為空,就是沒有保存。

因此只在Server端進行聲明EnableSession = true,是不夠的,這只是說明Server端現在能用session了。

經過上網查閱資料得知:要想使用Session,在進行上一步的聲明之後,還要在客戶端實例話WebService對象時,對其CookieContainer也要進行初始化方可使用Session的存儲狀態。另外在多個webservice代理中,只要含有相同的cookie,就能共用相同的session,其中的cookie通過代理類的CookieContainer.GetCookies(new Uri(s.Url))["ASP.NET_SessionId"]取得,如果其他的webserivce代理類需要用相同的session則可以用CookieContainer.Add方法,將取得的cookie加入即可(還沒進行測試)。

知道了如何使用後,修改客戶端的Soap代碼即可,修改後的代碼(紅色部分為修改的代碼)如下:

view plaincopy to clipboardprint?    [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")] 
    public class BusService : SoapHttpClientProtocol 
    { 
        <strong><span style="color:#ff0000;">private static  System.Net.CookieContainer cookieContainer;</span> 
        <span style="color:#ff0000;">static BusService() 
        { 
            cookieContainer = new System.Net.CookieContainer(); 
        }</span></strong> 
        public BusService() 
        { 
             this.Url = "http://localhost:4243/Bussiness.asmx"; 
           <strong><span style="color:#ff6666;">  this.CookieContainer = new System.Net.CookieContainer(); 
</span></strong>            // this.Url = "http://localhost/Bussiness/Bussiness.asmx";  
        }  
        [System.Web.Services.Protocols.SoapDocumentMethod( 
            "http://tempuri.org/Login", 
            RequestNamespace = "http://tempuri.org/", 
            ResponseNamespace = "http://tempuri.org/", 
            Use = System.Web.Services.Description.SoapBindingUse.Literal, 
            ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 
        public string Login(string username, string password) 
        { 
            object[] result = this.Invoke("Login", 
                                            new object[] { username, password }); 
            return (string)result[0]; 
        } 
    } 
    [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")]
    public class BusService : SoapHttpClientProtocol
    {
        <strong><span style="color:#ff0000;">private static  System.Net.CookieContainer cookieContainer;</span>
        <span style="color:#ff0000;">static BusService()
        {
            cookieContainer = new System.Net.CookieContainer();
        }</span></strong>
        public BusService()
        {
             this.Url = "http://localhost:4243/Bussiness.asmx";
           <strong><span style="color:#ff6666;">  this.CookieContainer = new System.Net.CookieContainer();
</span></strong>            // this.Url = "http://localhost/Bussiness/Bussiness.asmx";
        }
        [System.Web.Services.Protocols.SoapDocumentMethod(
            "http://tempuri.org/Login",
            RequestNamespace = "http://tempuri.org/",
            ResponseNamespace = "http://tempuri.org/",
            Use = System.Web.Services.Description.SoapBindingUse.Literal,
            ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
        public string Login(string username, string password)
        {
            object[] result = this.Invoke("Login",
                                            new object[] { username, password });
            return (string)result[0];
        }
    }
 
修改完了之後,進行測試,測試結果與設想的結果一樣。

 

摘自:示申 言舌 的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved