• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            道。道。道

            安全特性不等于安全的特性

               :: 首頁 :: 聯系 :: 聚合  :: 管理

            常用鏈接

            搜索

            •  

            最新評論

            添加Web引用的時候,WebService在客戶端有一個代理,如下:
                [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
                [System.Diagnostics.DebuggerStepThroughAttribute()]
                [System.ComponentModel.DesignerCategoryAttribute("code")]
                [System.Web.Services.WebServiceBindingAttribute(Name="WebService1Soap", Namespace="http://tempuri.org/")
               public partial class WebService1 : System.Web.Services.Protocols.SoapHttpClientProtocol
             
            客戶端調用WebServivce就是通過這個代理類來調用的。
             
            2.       調用WebService方法,客戶端和服務器端通信是Xml,所以代理類跟Xml之間就有序列化和反序列化的過程
            3.       客戶端調用WebService的過程如下
            a)         客戶端調用代理類Hello world方法
            string str = (new Service2.WebService1()).HelloWorld ();
            b)         代理類調用基類SoapHttpClientProtocal的Invoke方法
                    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld0766", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
                    public string HelloWorld() {
                        object[] results = this.Invoke("HelloWorld", new object[0]);
                        return ((string)(results[0]));
                    }
            c)         SoapHttpClientProtocal進行Soap序列化Soap頭和方法,都是這個類自己做的,但是輸入參數和返回值,是利用的XmlSerializer,輸入參數要序列化,返回值要反序列化。
                    protected object[] Invoke(string methodName, object[] parameters)
                    {
                            
                            try
                            {
                                message1.SetStream(stream1);
                                this.Serialize(message1);//注1
                            }
                           
                            response1 = this.GetWebResponse(request1);
                            Stream stream2 = null;
                            try
                            {
                                stream2 = response1.GetResponseStream();
                                objArray1 = this.ReadResponse(message1, response1, stream2, false);//注2
                            }
                      }
                     
                      注1:this.Serialize中有一句參數序列化的代碼如下
                      method1.parameterSerializer.Serialize(writer1, message.GetParameterValues(), null, flag1 ? text2 : null);
                      注2:this.ReadResponse中有一句返回值的反序列化的代碼如下
                      message.SetParameterValues((object[]) method1.returnSerializer.Deserialize(reader1, flag1 ? text1 : null));
            d)         XmlSerializer會緩存臨時程序集,這個程序集作用是序列化和反序列化,如果緩存中沒有會調用TempAssembly產生一個
             
            Static的緩存(就是我們每次調用慢的罪魁禍首):private static TempAssemblyCache cache;
            獲取緩存中的程序集:this.tempAssembly = XmlSerializer.cache[defaultNamespace, type];
            緩存中沒有就去加載:Assembly assembly1 = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out implementation1);
            加載沒有就去產生(會生成臨時文件并編譯,很慢):
            this.tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly1, implementation1);
             
            e)         TempAssemlby這個類負責加載以及產生臨時程序集
            LoadGeneratedAssemlby方法中,有一段邏輯,就是默認去加載序列化類,這個類的命名是規則如下
                    internal static string GetTempAssemblyName(AssemblyName parent, string ns)
                    {
                        return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode())));
                    }
                   同時,如果加載失敗會觸發AppDomain.CurrentDomain.AssemblyResolve事件
                    
            4.       結論
            1)   WebService的序列化是調用XmlSerializer
             
            2)   WebService慢,是因為產生序列化類慢,所謂的臨時文件都是XmlSerializer的中間代碼??梢栽赾onfig文件中加入如下的配置,臨時序列化的文件就不會被刪除了,WinForm程序是*.exe.config,asp.net是web.config。
                    <configuration>
              <system.diagnostics>
                <switches>
                  <add name="XmlSerialization.Compilation" value="4"/>
                </switches>
              </system.diagnostics>
            </configuration>
             
            臨時文件在C:\Documents and Settings\抹布\Local Settings\Temp下,注意,因為名稱是隨機的,序列化的dll文件,并不能重用,重開進程會重新生成。
            3)   如果自定義序列化類,可以跳過產生臨時序列化的步驟,大大提高第一次加載的速度,也就是說,只要有一個
            程序集名稱+.XmlSerializers”的序列化類存在,就不會動態生成序列化程序集了。
             
            4)   在代理類上可以加
            [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "TestPerformance.XmlSerializers")]
            指定Xml序列化的類,這個序列化的類可以通過一個工具產生,
            但是根據研究TempAssemlby的LoadGeneratedAssemlby代碼發現,這個Attribute可以不加的,只要你有一個GetTempAssemblyName返回值一樣的名稱的序列化類即可。
             
            5)   根據加載失敗會觸發AppDomain.CurrentDomain.AssemblyResolve事件,可以在加載失敗后動態產生序列化類,如下。
                    http://support.microsoft.com/kb/872800/zh-cn,請參考這個kb
                  private void Form1_Load(object sender, EventArgs e)
                    {
                        AppDomain.CurrentDomain.AssemblyResolve +=
                            new ResolveEventHandler(MyResolveEventHandler);
                    }
             
                    static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
                    {
                        Assembly a = null;
                        string[] arr = args.Name.Split(new string[] { "." }, StringSplitOptions.None);
                        if (args.Name.IndexOf("XmlSerializers") >= 0)
                        {
                            if (!System.IO.File.Exists(args.Name + ".dll"))
                                PreGenNS.Pregen.Generate(new string[] { arr[0] });
                            string sSerializersDLL = args.Name + ".dll";
                            string smartDeploymentHostLocation = "";
                            a = Assembly.LoadFrom(smartDeploymentHostLocation + sSerializersDLL);
                        }
                        return a;
                    }
            6)VS2005利用Release編譯,會產生AssemblyName+"XmlSerializer.dll"的序列化文件,可以隨著客戶端一起部署,跟5這種方式不太一樣,可以根據實際情況來選擇。
            利用5這種方式,是第一次調用WebService時,動態生成序列化類;而6是在軟件發布時,生成這個類,并部署到客戶端。
            posted on 2007-11-07 15:35 獨孤九劍 閱讀(3635) 評論(0)  編輯 收藏 引用 所屬分類: Learn articles
            色婷婷综合久久久久中文一区二区 | 亚洲欧美日韩中文久久| 国产精品久久新婚兰兰| 久久er99热精品一区二区| 久久91精品国产91久久小草| 国产午夜精品理论片久久| 99久久这里只精品国产免费| 99久久99这里只有免费的精品| 精品国产乱码久久久久久浪潮| 狠狠色丁香婷婷久久综合| 久久不射电影网| 亚洲精品乱码久久久久久蜜桃图片| 久久不射电影网| 久久无码AV中文出轨人妻| 久久综合丁香激情久久| 亚洲中文字幕无码久久精品1| 伊人久久大香线蕉精品| 久久人人爽人人爽人人片AV不| 国产精品毛片久久久久久久| 久久精品中文字幕一区| 久久精品国产精品亜洲毛片| 精品乱码久久久久久久| 久久天天躁夜夜躁狠狠躁2022| 久久精品国产第一区二区| 久久婷婷综合中文字幕| 国产精品久久久久影院嫩草| 亚洲中文字幕无码久久综合网| 一本大道久久东京热无码AV| 久久影视综合亚洲| 99久久国产综合精品成人影院| 69国产成人综合久久精品| 久久精品国产亚洲AV蜜臀色欲| 无码任你躁久久久久久| 久久精品无码一区二区三区日韩 | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久综合综合久久97色| 国产精品久久久久9999高清| 久久男人Av资源网站无码软件| 久久久久久人妻无码| 久久久久久亚洲Av无码精品专口| 色婷婷综合久久久久中文一区二区|