作者: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属性,在同一个类上标识很多次,如下图: