Winform客戶端引用WCF客戶端後,部分類無法正常使用

衣舞晨風發表於2015-09-08

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

在專案中用到WCF,專案的結構是這樣的:


在SPI專案中編寫該解決方案中公共的類及函式;
在WCFService專案中寫的是svc檔案及WCF服務介面;
在Client中新增WCF服務引用的時候該WCFService專案,然後再UI專案中初始化Client的例項。通過該例項WCFService中的方法。
問題:

有時會出現這麼一種情況,在UI中通過初始化Client的例項。通過該例項WCFService中的方法MethodA,該方法的入參是SPI中類ConnectionInfo的例項,然後在UI中再次使用類ConnectionInfo時會發現ConnectionInfo是在Client名稱空間下的類,而不是在SPI名稱空間下的類。

在WCF自動生成的客戶端代理類(Reference.cs檔案),會將SPI中的類ConnectionInfo,序列化成

   

 [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="ConnectionInfo", Namespace="http://schemas.datacontract.org/2004/07/HaiChuang.AMAC.DataSourceSettings.SPI.Mod" +
        "el")]
    [System.SerializableAttribute()]
    public partial class ConnectionInfo : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
        
        [System.NonSerializedAttribute()]
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string ConnectionStringField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string GuidField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string LocationField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string MenuGuidField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string NameField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private string TypeField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private int idField;
        
        [global::System.ComponentModel.BrowsableAttribute(false)]
        public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
            get {
                return this.extensionDataField;
            }
            set {
                this.extensionDataField = value;
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string ConnectionString {
            get {
                return this.ConnectionStringField;
            }
            set {
                if ((object.ReferenceEquals(this.ConnectionStringField, value) != true)) {
                    this.ConnectionStringField = value;
                    this.RaisePropertyChanged("ConnectionString");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Guid {
            get {
                return this.GuidField;
            }
            set {
                if ((object.ReferenceEquals(this.GuidField, value) != true)) {
                    this.GuidField = value;
                    this.RaisePropertyChanged("Guid");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Location {
            get {
                return this.LocationField;
            }
            set {
                if ((object.ReferenceEquals(this.LocationField, value) != true)) {
                    this.LocationField = value;
                    this.RaisePropertyChanged("Location");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string MenuGuid {
            get {
                return this.MenuGuidField;
            }
            set {
                if ((object.ReferenceEquals(this.MenuGuidField, value) != true)) {
                    this.MenuGuidField = value;
                    this.RaisePropertyChanged("MenuGuid");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Name {
            get {
                return this.NameField;
            }
            set {
                if ((object.ReferenceEquals(this.NameField, value) != true)) {
                    this.NameField = value;
                    this.RaisePropertyChanged("Name");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Type {
            get {
                return this.TypeField;
            }
            set {
                if ((object.ReferenceEquals(this.TypeField, value) != true)) {
                    this.TypeField = value;
                    this.RaisePropertyChanged("Type");
                }
            }
        }
        
        [System.Runtime.Serialization.DataMemberAttribute()]
        public int id {
            get {
                return this.idField;
            }
            set {
                if ((this.idField.Equals(value) != true)) {
                    this.idField = value;
                    this.RaisePropertyChanged("id");
                }
            }
        }
        
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        
        protected void RaisePropertyChanged(string propertyName) {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null)) {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }
    }
該實體類程式碼為:

/// <summary>
    /// 資料來源資訊
    /// </summary>
    public class ConnectionInfo
    {
        public int id { get; set; }
        public string Guid { get; set; }
        public string Name { get; set; }
        public string Location { get; set; }
        public string Type { get; set; }
        public string ConnectionString { get; set; }
        public string MenuGuid { get; set; }

    }

在 CLient專案的wcf引用上右鍵,可以看到該實體類


在專案中可以找到該dll


開啟該dll,可以看到該類的資訊


此處看到的類資訊是被轉成WCF資料契約形式的類資訊


解決方案:

  如果要在UI專案中使用SPI名稱空間下的類ConnectionInfo,則將Reference.cs檔案中的public partial class ConnectionInfo刪除,再在UI中引用SPI專案即可。

小注:

如果不進行修改,則在客戶端呼叫WCF服務端方法的時候,獲取函式入參型別或者返回值型別的型別(如果該入參、返回值 型別為自定義實體類),是通過WCF服務端獲取的,即使該實體類在SPI中,客戶端也有,呼叫的也是服務端的。

就相當於你自己顯式將該自定義實體類標記為資料契約。

使用WebService也會出現這種問題,解決思路一樣。
但產生這個問題的原因暫時還沒有找到,因為UI專案中已經引用SPI專案了,還是會在Reference.cs檔案中生成ConnectionInfo類的相關資訊。希望知道原因的朋友留言說一下,謝謝。

相關文章