none
动态调用WebService时如何保持Session RRS feed

  • 问题

  • 我按照网上介绍的方法进行WebService的动态调用,然而如果WebService方法中包含有操作Session的动作,则前后动作之间无法保持Session。一直困惑与此,不止如何解决,望各位老师给予指点。

    如下是动态调用WebService的方法:
        public object InvokeWebservice(string url, string @namespace, string classname, string methodname, object[] args)
        {
            try
            {
                System.Net.WebClient wc = new System.Net.WebClient();
    
                System.IO.Stream stream = wc.OpenRead(url + "?WSDL");
    
                System.Web.Services.Description.ServiceDescription sd
                    = System.Web.Services.Description.ServiceDescription.Read(stream);
    
                System.Web.Services.Description.ServiceDescriptionImporter sdi
                    = new System.Web.Services.Description.ServiceDescriptionImporter();
    
                sdi.AddServiceDescription(sd, "", "");
    
                System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
                System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
    
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);
    
                Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
                System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();
    
                System.CodeDom.Compiler.CompilerParameters cplist
                    = new System.CodeDom.Compiler.CompilerParameters();
    
                cplist.GenerateExecutable = false;
                cplist.GenerateInMemory = true;
    
                cplist.ReferencedAssemblies.Add("System.dll");
                cplist.ReferencedAssemblies.Add("System.XML.dll");
                cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                cplist.ReferencedAssemblies.Add("System.Data.dll");
    
                System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                if (true == cr.Errors.HasErrors)
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                    {
                        sb.Append(ce.ToString());
                        sb.Append(System.Environment.NewLine);
                    }
    
                    throw new Exception(sb.ToString());
                }
    
                System.Reflection.Assembly assembly = cr.CompiledAssembly;
                Type t = assembly.GetType(@namespace + "." + classname, true, true);
                object obj = Activator.CreateInstance(t);
                System.Reflection.MethodInfo mi = t.GetMethod(methodname);
                return mi.Invoke(obj, args);
            }
    
            catch (Exception ex)
            {
                throw ex;
            }
        }
    



    如下是WebService中的两个方法:
        [WebMethod(EnableSession=true)]
        public bool Authenticate(string uid, string pwd)
        {
            if (uid == pwd)
            {
                Session["authentification"] = "1";
                return true;
            }
            else
            {
                return false;
            }
        }
    
        [WebMethod(EnableSession = true)]
        public bool Test()
        {
            if (Session["authentification"] != null && Session["authentification"].ToString() == "1")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    
    2009年6月2日 3:44

答案

  • 先谢谢您,这个原理我了解了,但是针对我上面的动态调用Webservice方法,应该在哪里获取返回http头中的cookie内容呢?又该在哪里发送呢?劳驾再次指点一下吧,不胜感激。
    请注意看我添加的注释
    public partial class _Default : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
             Response.Write("测试web服务,直接方法<br/>");
             CookieContainer container = new CookieContainer();
             localhost.Service1 service1 = new localhost.Service1();
             service1.CookieContainer = container;
             Response.Write(service1.Authenticate("raymond", "raymond"));
             service1.CookieContainer = container;//如果这里不是下面的语句得到的仍然为False
             Response.Write(service1.Test());
             Response.Write("测试web服务,CodeDom方法<br/>");
             Response.Write(InvokeWebservice("http://localhost/MyTestWebService/Service1.asmx", "MyTestWebService", "Service1", "Authenticate", new object[] { "raymond", "raymond" },container));
             Response.Write(InvokeWebservice("http://localhost/MyTestWebService/Service1.asmx", "MyTestWebService", "Service1", "Test", new object[] { },container));
          }
    
          public object InvokeWebservice(string url, string @namespace, string classname, string methodname, object[] args,CookieContainer container)
          {
             try
             {
                System.Net.WebClient wc = new System.Net.WebClient();
    
                System.IO.Stream stream = wc.OpenRead(url + "?WSDL");
    
                System.Web.Services.Description.ServiceDescription sd
                    = System.Web.Services.Description.ServiceDescription.Read(stream);
    
                System.Web.Services.Description.ServiceDescriptionImporter sdi
                    = new System.Web.Services.Description.ServiceDescriptionImporter();
    
                sdi.AddServiceDescription(sd, "", "");
    
                System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
                System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
    
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);
    
                Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
                System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();
    
                System.CodeDom.Compiler.CompilerParameters cplist
                    = new System.CodeDom.Compiler.CompilerParameters();
    
                cplist.GenerateExecutable = false;
                cplist.GenerateInMemory = true;
    
                cplist.ReferencedAssemblies.Add("System.dll");
                cplist.ReferencedAssemblies.Add("System.XML.dll");
                cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                cplist.ReferencedAssemblies.Add("System.Data.dll");
    
                System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                if (true == cr.Errors.HasErrors)
                {
                   System.Text.StringBuilder sb = new System.Text.StringBuilder();
                   foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                   {
                      sb.Append(ce.ToString());
                      sb.Append(System.Environment.NewLine);
                   }
    
                   throw new Exception(sb.ToString());
                }
    
                System.Reflection.Assembly assembly = cr.CompiledAssembly;
                Type t = assembly.GetType(@namespace + "." + classname, true, true);
                object obj = Activator.CreateInstance(t);
    
                //设置CookieContainer 1987raymond添加
                PropertyInfo property = t.GetProperty("CookieContainer");
                property.SetValue(obj, container, null);
    
                System.Reflection.MethodInfo mi = t.GetMethod(methodname);
                return mi.Invoke(obj, args);
             }
    
             catch (Exception ex)
             {
                throw ex;
             }
          }
       }



    执行结果
    测试web服务,直接方法
    TrueTrue测试web服务,CodeDom方法
    TrueTrue

    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月2日 6:34
    版主

全部回复

  • 一般的ws  session 是cookie 保持的
    在两次访问之间保持一个cookie 上下文  就可以保持一个session

    所以你需要把前一次返回的结果的http头中 cookie 的所有内容    作为下一次发送你request http头的cookie内容就可以保持session上下文了


    紫柔版主的头像真叫萌得一个不行啊。。。。
    2009年6月2日 5:34
  • 先谢谢您,这个原理我了解了,但是针对我上面的动态调用Webservice方法,应该在哪里获取返回http头中的cookie内容呢?又该在哪里发送呢?劳驾再次指点一下吧,不胜感激。
    2009年6月2日 6:19
  • 先谢谢您,这个原理我了解了,但是针对我上面的动态调用Webservice方法,应该在哪里获取返回http头中的cookie内容呢?又该在哪里发送呢?劳驾再次指点一下吧,不胜感激。
    请注意看我添加的注释
    public partial class _Default : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
             Response.Write("测试web服务,直接方法<br/>");
             CookieContainer container = new CookieContainer();
             localhost.Service1 service1 = new localhost.Service1();
             service1.CookieContainer = container;
             Response.Write(service1.Authenticate("raymond", "raymond"));
             service1.CookieContainer = container;//如果这里不是下面的语句得到的仍然为False
             Response.Write(service1.Test());
             Response.Write("测试web服务,CodeDom方法<br/>");
             Response.Write(InvokeWebservice("http://localhost/MyTestWebService/Service1.asmx", "MyTestWebService", "Service1", "Authenticate", new object[] { "raymond", "raymond" },container));
             Response.Write(InvokeWebservice("http://localhost/MyTestWebService/Service1.asmx", "MyTestWebService", "Service1", "Test", new object[] { },container));
          }
    
          public object InvokeWebservice(string url, string @namespace, string classname, string methodname, object[] args,CookieContainer container)
          {
             try
             {
                System.Net.WebClient wc = new System.Net.WebClient();
    
                System.IO.Stream stream = wc.OpenRead(url + "?WSDL");
    
                System.Web.Services.Description.ServiceDescription sd
                    = System.Web.Services.Description.ServiceDescription.Read(stream);
    
                System.Web.Services.Description.ServiceDescriptionImporter sdi
                    = new System.Web.Services.Description.ServiceDescriptionImporter();
    
                sdi.AddServiceDescription(sd, "", "");
    
                System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
                System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
    
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);
    
                Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
                System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();
    
                System.CodeDom.Compiler.CompilerParameters cplist
                    = new System.CodeDom.Compiler.CompilerParameters();
    
                cplist.GenerateExecutable = false;
                cplist.GenerateInMemory = true;
    
                cplist.ReferencedAssemblies.Add("System.dll");
                cplist.ReferencedAssemblies.Add("System.XML.dll");
                cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                cplist.ReferencedAssemblies.Add("System.Data.dll");
    
                System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                if (true == cr.Errors.HasErrors)
                {
                   System.Text.StringBuilder sb = new System.Text.StringBuilder();
                   foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                   {
                      sb.Append(ce.ToString());
                      sb.Append(System.Environment.NewLine);
                   }
    
                   throw new Exception(sb.ToString());
                }
    
                System.Reflection.Assembly assembly = cr.CompiledAssembly;
                Type t = assembly.GetType(@namespace + "." + classname, true, true);
                object obj = Activator.CreateInstance(t);
    
                //设置CookieContainer 1987raymond添加
                PropertyInfo property = t.GetProperty("CookieContainer");
                property.SetValue(obj, container, null);
    
                System.Reflection.MethodInfo mi = t.GetMethod(methodname);
                return mi.Invoke(obj, args);
             }
    
             catch (Exception ex)
             {
                throw ex;
             }
          }
       }



    执行结果
    测试web服务,直接方法
    TrueTrue测试web服务,CodeDom方法
    TrueTrue

    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月2日 6:34
    版主
  • 谢谢,谢谢 1987raymond ,谢谢 韦恩卑鄙 ,问题已得以解决,多谢 1987raymond 这么细心的帮我调代码,小弟很是感动。
    2009年6月2日 7:24
  • 谢谢,谢谢 1987raymond ,谢谢 韦恩卑鄙 ,问题已得以解决,多谢 1987raymond 这么细心的帮我调代码,小弟很是感动。

    不用谢 大家互相学习
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月2日 7:25
    版主
  • 谢谢,谢谢 1987raymond ,谢谢 韦恩卑鄙 ,问题已得以解决,多谢 1987raymond 这么细心的帮我调代码,小弟很是感动。

    我还在奇怪你执著用System.Net.WebClient wc = new System.Net.WebClient();

    那样我就不好告诉你cookiecontainer怎么用了
    紫柔版主的头像真叫萌得一个不行啊。。。。
    2009年6月2日 8:36
  • 感谢,终于知道解决办法了。

    做个标记

    2010年8月26日 10:18