Winform 呼叫WCF客戶端,所有服務端方法在執行的時候均找不到(編譯沒有問題)
作者:jiankunking 出處:http://blog.csdn.net/jiankunking
今天在開發過程中遇到了一個很噁心的問題,就是Form窗體ShowDialog的時候,直接報出下面的錯誤:
有關呼叫實時(JIT)除錯而不是此對話方塊的詳細資訊,
請參見此訊息的結尾。
************** 異常文字 **************
System.MissingMethodException: 找不到方法:“XXX.XXX.DataObject.SPI.DataObjectColumn[] XXX.XXX.WCFClient.WCFService.ServiceClient.DataColumn_GetListByDOID(System.String)”。
在 XXX.XXX.Common.CommonHelp.UI.HelpForm.HelpDisplayEditorForm_Load(Object sender, EventArgs e)
在 System.Windows.Forms.Form.OnLoad(EventArgs e)
在 System.Windows.Forms.Form.OnCreateControl()
在 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
在 System.Windows.Forms.Control.CreateControl()
在 System.Windows.Forms.Control.WmShowWindow(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
在 System.Windows.Forms.Form.WmShowWindow(Message& m)
在 System.Windows.Forms.Form.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
將斷點加在HelpDisplayEditorForm_Load函式上發現,根本進不到函式內部,就報錯了。
個人認為是Form窗體在ShowDialog函式之後,HelpDisplayEditorForm_Load函式之前發生的異常,於是上網搜資料,看微軟的原始碼,也沒什麼收穫。於是,諮詢了一下同事,同事說把HelpDisplayEditorForm_Load中的所有程式碼遮蔽掉,看看效果。
我把HelpDisplayEditorForm_Load內所有程式碼遮蔽到以後,斷點可以進入HelpDisplayEditorForm_Load函式內部了,然後,一部分一部分程式碼的放開,發現,只要到需要呼叫服務端方法的時候,就會報出上面的錯誤(所有呼叫WCF服務端方法的地方都會報錯)。
更新過錯誤提示的dll(通過dll反編譯發現錯誤提示的函式在dll中是存在的),重啟過iis等等N過方法之後,還有木有搞定。
由於,是所有WCF服務端方法均不可用,於是回頭研究WCF客戶端,發現WCF客戶端有問題,有人在獲取WCF服務端方法的時候,WCF將服務契約標識方法入參中的自定義型別、返回值是自定義型別的,均隱式進行了實體類序列化(此處的序列化指的是,將自定義型別的實體,標識成了WCF資料契約的型別)。
比如SPI中的實體類如下:
using System.Data;
namespace XXXX.XXXX.Common.CommonHelp.SPI
{
/// <summary>
/// 智慧幫助資料實體類
/// 對應資料庫:[A_CommonHelp]
/// </summary>
public class CommonHelpDataEntity
{
/// <summary>
/// HelpEntity 是一個指標 標明該CommonHelpDataEntity屬於哪一個CommonHelpEntity
/// </summary>
private CommonHelpEntity entity;
public CommonHelpEntity HelpEntity
{
get { return entity; }
}
private string displayColumns;
/// <summary>
/// 顯示欄位
/// </summary>
public string DisplayColumns
{
get { return displayColumns; }
set { displayColumns = value; }
}
private string sourceObject;
/// <summary>
/// 源SQL語句
/// </summary>
public string SourceObject
{
get { return sourceObject; }
set { sourceObject = value; }
}
private string dataTextField;
/// <summary>
/// 繫結Text欄位
/// </summary>
public string DataTextField
{
get { return dataTextField; }
set { dataTextField = value; }
}
private string dataValueField;
/// <summary>
/// 繫結Value欄位
/// </summary>
public string DataValueField
{
get { return dataValueField; }
set { dataValueField = value; }
}
private string orderFields;
/// <summary>
/// 預設排序欄位
/// </summary>
public string OrderFields
{
get { return orderFields; }
set { orderFields = value; }
}
public string rowId;
/// <summary>
/// 標誌欄位
/// </summary>
public string RowId
{
get { return rowId; }
set { rowId = value; }
}
private string defaultValueCondition;
/// <summary>
/// 預設值條件
/// </summary>
public string DefaultValueCondition
{
get { return defaultValueCondition; }
set { defaultValueCondition = value; }
}
private string category;
/// <summary>
/// 幫助類別
/// </summary>
public string Category
{
get { return category; }
set { category = value; }
}
private string selectDataObjectId;
/// <summary>
/// 搜尋引擎型別幫助勾選的資料物件的Id
/// </summary>
public string SelectDataObjectId
{
get { return selectDataObjectId; }
set { selectDataObjectId = value; }
}
private string searchEngineId;
/// <summary>
/// 搜尋引擎幫助A_SearchEngine ID
/// </summary>
public string SearchEngineId
{
get { return searchEngineId; }
set { searchEngineId = value; }
}
private string dataModeldId;
/// <summary>
/// 資料模型Id
/// </summary>
public string DataModeldId
{
get { return dataModeldId; }
set { dataModeldId = value; }
}
private string createTime;
/// <summary>
/// 幫助建立時間
/// </summary>
public string CreateTime
{
get { return createTime; }
set { createTime = value; }
}
private string lastUpdateTime;
/// <summary>
/// 幫助 最後更新時間
/// </summary>
public string LastUpdateTime
{
get { return lastUpdateTime; }
set { lastUpdateTime = value; }
}
public CommonHelpDataEntity()
{
entity = new CommonHelpEntity();
entity.SetDataEntity(this);
}
public CommonHelpDataEntity(CommonHelpEntity info)
{
entity = info;
entity.SetDataEntity(this);
}
public CommonHelpDataEntity(DataRow row)
{
entity=new CommonHelpEntity();
entity.Id = row["Id"].ToString();
entity.Code = row["Code"].ToString();
entity.Name = row["Name"].ToString();
entity.Contains = row["DisplayColumns"].ToString();
entity.SetDataEntity(this);
this.DisplayColumns = row["DisplayColumns"].ToString();
this.SourceObject = row["SourceObject"].ToString();
this.DataTextField = row["DataTextField"].ToString();
this.DataValueField = row["DataValueField"].ToString();
this.OrderFields = row["OrderFields"].ToString();
this.RowId = row["Id"].ToString();
//int value=(row["Category"].ToString().Trim().Length==0)?0:int.Parse(row["Category"].ToString());
//this.Category = Enum.GetName(typeof(HelpTypeEnum), value);
this.Category = row["Category"].ToString();
this.SearchEngineId = row["SearchEngineId"].ToString();
this.SelectDataObjectId = row["SelectDataObjectId"].ToString();
this.DefaultValueCondition = row["DefaultValueCondition"].ToString();
this.CreateTime = row["CreateTime"].ToString();
this.lastUpdateTime = row["lastUpdateTime"].ToString();
this.dataModeldId = row["DataModeldId"].ToString();
}
/// <summary>
/// 關聯資料實體
/// </summary>
/// <param name="entity"></param>
public void AssociateHelpEntity(CommonHelpEntity entity)
{
entity.SetDataEntity(this);
this.entity = entity;
}
}
}
標識序列化之後的類的為: [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="CommonHelpDataEntity", Namespace="http://schemas.datacontract.org/2004/07/XXXX.XXXX.Common.CommonHelp.SPI")]
[System.SerializableAttribute()]
public partial class CommonHelpDataEntity : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CategoryField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string CreateTimeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DataTextFieldField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DataValueFieldField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DefaultValueConditionField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string DisplayColumnsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string LastUpdateTimeField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string OrderFieldsField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string RowIdField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string SearchEngineIdField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string SelectDataObjectIdField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string SourceObjectField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string rowId1Field;
[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 Category {
get {
return this.CategoryField;
}
set {
if ((object.ReferenceEquals(this.CategoryField, value) != true)) {
this.CategoryField = value;
this.RaisePropertyChanged("Category");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CreateTime {
get {
return this.CreateTimeField;
}
set {
if ((object.ReferenceEquals(this.CreateTimeField, value) != true)) {
this.CreateTimeField = value;
this.RaisePropertyChanged("CreateTime");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DataTextField {
get {
return this.DataTextFieldField;
}
set {
if ((object.ReferenceEquals(this.DataTextFieldField, value) != true)) {
this.DataTextFieldField = value;
this.RaisePropertyChanged("DataTextField");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DataValueField {
get {
return this.DataValueFieldField;
}
set {
if ((object.ReferenceEquals(this.DataValueFieldField, value) != true)) {
this.DataValueFieldField = value;
this.RaisePropertyChanged("DataValueField");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DefaultValueCondition {
get {
return this.DefaultValueConditionField;
}
set {
if ((object.ReferenceEquals(this.DefaultValueConditionField, value) != true)) {
this.DefaultValueConditionField = value;
this.RaisePropertyChanged("DefaultValueCondition");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string DisplayColumns {
get {
return this.DisplayColumnsField;
}
set {
if ((object.ReferenceEquals(this.DisplayColumnsField, value) != true)) {
this.DisplayColumnsField = value;
this.RaisePropertyChanged("DisplayColumns");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string LastUpdateTime {
get {
return this.LastUpdateTimeField;
}
set {
if ((object.ReferenceEquals(this.LastUpdateTimeField, value) != true)) {
this.LastUpdateTimeField = value;
this.RaisePropertyChanged("LastUpdateTime");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string OrderFields {
get {
return this.OrderFieldsField;
}
set {
if ((object.ReferenceEquals(this.OrderFieldsField, value) != true)) {
this.OrderFieldsField = value;
this.RaisePropertyChanged("OrderFields");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string RowId {
get {
return this.RowIdField;
}
set {
if ((object.ReferenceEquals(this.RowIdField, value) != true)) {
this.RowIdField = value;
this.RaisePropertyChanged("RowId");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string SearchEngineId {
get {
return this.SearchEngineIdField;
}
set {
if ((object.ReferenceEquals(this.SearchEngineIdField, value) != true)) {
this.SearchEngineIdField = value;
this.RaisePropertyChanged("SearchEngineId");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string SelectDataObjectId {
get {
return this.SelectDataObjectIdField;
}
set {
if ((object.ReferenceEquals(this.SelectDataObjectIdField, value) != true)) {
this.SelectDataObjectIdField = value;
this.RaisePropertyChanged("SelectDataObjectId");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string SourceObject {
get {
return this.SourceObjectField;
}
set {
if ((object.ReferenceEquals(this.SourceObjectField, value) != true)) {
this.SourceObjectField = value;
this.RaisePropertyChanged("SourceObject");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(Name="rowId")]
public string rowId1 {
get {
return this.rowId1Field;
}
set {
if ((object.ReferenceEquals(this.rowId1Field, value) != true)) {
this.rowId1Field = value;
this.RaisePropertyChanged("rowId1");
}
}
}
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));
}
}
}
該標識序列化之後的類在是Reference.cs檔案中找到的。
此處的詳細分析,可以參考:點選開啟連結
解決方案:
將Reference.cs檔案所有標識序列化的類、列舉,全部刪除,改為引用SPI中的實體類、列舉,然後,重新生成WCFClient,部署,問題搞定。
今天的收穫:
1、斷點沒有進入函式(HelpDisplayEditorForm_Load),並不表示問題,一定在函式之外。
2、資料契約中KnownTypeAttribute屬性,在同一個類上標識很多次,如下圖:
相關文章
- Java與WCF互動(一):Java客戶端呼叫WCF服務 (轉)Java客戶端
- 服務端,客戶端服務端客戶端
- 客戶端,服務端客戶端服務端
- 如何編譯C#版本的Protocol Buffers與gRPC服務端,客戶端程式碼編譯C#ProtocolRPC服務端客戶端
- socket實現服務端多執行緒,客戶端重複輸入服務端執行緒客戶端
- 服務端渲染和客戶端渲染服務端客戶端
- Feign客戶端呼叫服務時丟失Header引數的解決方案客戶端Header
- Zookeeper C客戶端庫編譯客戶端編譯
- 使用Golang搭建gRPC服務提供給.NetCore客戶端呼叫GolangRPCNetCore客戶端
- python建立tcp服務端和客戶端PythonTCP服務端客戶端
- Qt實現基於多執行緒的檔案傳輸(服務端,客戶端)QT執行緒服務端客戶端
- [提問交流]用onethink做服務,給ajax客戶端呼叫的時候,為何客戶端只第一次獲得到值,之後都是空值,這是為什麼?客戶端
- 「iOS」行車服務app 「客戶端、後端思路+程式碼」iOSAPP客戶端後端
- macOS 自帶的ftp服務端&vnc客戶端MacFTP服務端VNC客戶端
- C#版Nebula客戶端編譯C#客戶端編譯
- Skywalking PHP客戶端編譯安裝PHP客戶端編譯
- OSSEC服務端配置客戶端批次部署方案服務端客戶端
- golang實現tcp客戶端服務端程式GolangTCP客戶端服務端
- 使用Apollo Server搭建GraphQL的服務端和客戶端Server服務端客戶端
- 實現客戶端與服務端的HTTP通訊客戶端服務端HTTP
- 在Ubuntu 18.04上編譯安裝pppoe客戶端軟體Ubuntu編譯客戶端
- 微服務架構,客戶端如何catch服務端的異常?微服務架構客戶端服務端
- 前端如何保持與伺服器時間同步(如何解決客戶端與服務端時間不對稱的問題)?前端伺服器客戶端服務端
- win10沒有telnet客戶端怎麼辦 windows10中沒有telnet客戶端的解決教程Win10客戶端Windows
- Dubbo原始碼解析之客戶端初始化及服務呼叫原始碼客戶端
- rsync備份【基於客戶端與服務端】客戶端服務端
- 埃森哲:端到端客戶服務報告
- MQTT伺服器搭建服務端和客戶端MQQT伺服器服務端客戶端
- frp內網穿透,客戶端能訪問,服務端訪問報錯404,有兄弟遇到過嗎FRP內網穿透客戶端服務端
- WCF服務端的.NET Core支援專案Core WCF 正式啟動服務端
- 初識Spring Cloud Eureka(三)(Eureka客戶端之間 服務的相互呼叫)SpringCloud客戶端
- Java的oauth2.0 服務端與客戶端的實現JavaOAuth服務端客戶端
- Dart編譯技術在服務端的探索和應用Dart編譯服務端
- Eureka高可用叢集服務端和客戶端配置服務端客戶端
- 服務端如何獲取客戶端請求IP地址服務端客戶端
- MQTT協議從服務端到客戶端詳解MQQT協議服務端客戶端
- 在容器服務中獲取客戶端真實源 IP客戶端
- 服務端經典的C10k問題(譯)服務端
- Socket最簡單的客戶端與服務端通訊-Java客戶端服務端Java