解決WCF不能直接序列化SqlParameter類型的問(wèn)題
錯(cuò)誤描述:
由于內(nèi)部錯(cuò)誤,服務(wù)器無(wú)法處理該請(qǐng)求。有關(guān)該錯(cuò)誤的詳細(xì)信息,請(qǐng)打開服務(wù)器上的 IncludeExceptionDetailInFaults (從 ServiceBehaviorAttribute 或從 <serviceDebug> 配置行為)以便將異常信息發(fā)送回客戶端,或打開對(duì)每個(gè) Microsoft .NET Framework SDK 文檔的跟蹤并檢查服務(wù)器跟蹤日志。
客戶端調(diào)用WCF的時(shí)候報(bào)上面的錯(cuò)誤,WCF只能序列化基礎(chǔ)的數(shù)據(jù)類型,不能直接序列化SqlParameter類型,需要使用自定義類,然后在WCF服務(wù)端轉(zhuǎn)換的方式解決:
自定義類代碼如下:
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace CommonLib.CustomClass { /// <summary> /// 方法標(biāo)記為DataContract約束,屬性標(biāo)記為DataMember /// </summary> [Serializable] [DataContract] public class SetSqlParameter { #region 屬性 /// <summary> /// 參數(shù)名稱 /// </summary> [DataMember] private string paraName = ""; public string ParaName { get { return this.paraName; } set { this.paraName = value; } } /// <summary> /// 參數(shù)長(zhǎng)度 /// </summary> [DataMember] private int paraLength = 0; public int ParaLength { get { return this.paraLength; } set { this.paraLength = value; } } /// <summary> /// 參數(shù)值 /// </summary> [DataMember] private object paraValue = null; public object ParaValue { get { return this.paraValue; } set { this.paraValue = value; } } /// <summary> /// 參數(shù)類型 /// </summary> [DataMember] private SqlDbType paraDbType = SqlDbType.NVarChar; public SqlDbType ParaDbType { get { return this.paraDbType; } set { this.paraDbType = value; } } #endregion /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="sPara"></param> public SetSqlParameter(SqlParameter sPara) { this.paraName = sPara.ParameterName; this.paraLength = sPara.Size; this.paraValue = sPara.Value; this.paraDbType = sPara.SqlDbType; } /// <summary> /// 轉(zhuǎn)換成SqlParameter類型 /// </summary> /// <returns></returns> public SqlParameter ConvertToSqlParameter() { SqlParameter parameter = new SqlParameter(this.paraName, this.paraDbType, this.paraLength); parameter.Value = this.paraValue; return parameter; } } }
WCF服務(wù)端代碼如下:
接口代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Data; using System.Data.SqlClient; using CommonLib.CustomClass; namespace WcfServiceDemo { // 注意: 使用“重構(gòu)”菜單上的“重命名”命令,可以同時(shí)更改代碼和配置文件中的接口名“IMyService”。 [ServiceContract] public interface IMyService { [OperationContract] DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters); } }
接口實(shí)現(xiàn)類代碼:
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Configuration; using CommonLib.CustomClass; namespace WcfServiceDemo { // 注意: 使用“重構(gòu)”菜單上的“重命名”命令,可以同時(shí)更改代碼、svc 和配置文件中的類名“MyService”。 // 注意: 為了啟動(dòng) WCF 測(cè)試客戶端以測(cè)試此服務(wù),請(qǐng)?jiān)诮鉀Q方案資源管理器中選擇 MyService.svc 或 MyService.svc.cs,然后開始調(diào)試。 public class MyService : IMyService { public DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters) { DataTable dtReturn = new DataTable(); dtReturn.TableName = "ExecuteQuery"; string strCon = ConfigurationManager.ConnectionStrings["HealthHospInfection"].ConnectionString; using (SqlConnection conn = new SqlConnection(strCon)) { SqlCommand cmd = new SqlCommand(strSQL, conn); conn.Open(); if (parameters != null) { SqlParameter[] para = new SqlParameter[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { //把SetSqlParameter類型的數(shù)組轉(zhuǎn)換成SqlParameter類型的數(shù)組 para[i] = parameters[i].ConvertToSqlParameter(); } cmd.Parameters.AddRange(para); } SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dtReturn); } return dtReturn; } } }
客戶端調(diào)用WCF代碼:
using CommonLib.CustomClass; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace winClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btn_GetData_Click(object sender, EventArgs e) { string strSQL = " SELECT * FROM BaseSetMainInfo WHERE TypeCode=@TypeCode "; //定義SqlParameter SqlParameter para = new SqlParameter("@TypeCode", SqlDbType.Int); para.Value = 1; //定義SetSqlParameter類型的數(shù)組 SetSqlParameter[] paras = new SetSqlParameter[] { new SetSqlParameter(para) }; //實(shí)例化WCF服務(wù) ServiceReference.MyServiceClient client=new ServiceReference.MyServiceClient(); //調(diào)用WCF服務(wù)提供的方法 DataTable dt = client.ExeceteQuery(strSQL, paras); this.dataGridView1.DataSource = dt; } } }
這樣就可以解決WCF不能直接序列化SqlParameter類型的問(wèn)題了。
代碼下載地址:點(diǎn)此下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#如何遠(yuǎn)程讀取服務(wù)器上的文本內(nèi)容
這篇文章主要介紹了C#如何遠(yuǎn)程讀取服務(wù)器上的文本內(nèi)容,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01詳解Unity中Mask和RectMask2D組件的對(duì)比與測(cè)試
本篇文章給大家介紹Unity中Mask和RectMask2D組件的對(duì)比與測(cè)試,包括組件用法及RectMask2D的基本用法,通過(guò)Mask的原理分析實(shí)例代碼相結(jié)合給大家講解的非常詳細(xì),需要的朋友參考下吧2021-06-06C#配置log4net實(shí)現(xiàn)將日志分類記錄到不同的日志文件中
log4net是.Net下一個(gè)非常優(yōu)秀的開源日志記錄組件,log4net記錄日志的功能非常強(qiáng)大,它可以將日志分不同的等級(jí),以不同的格式,輸出到不同的媒介,下面我們就來(lái)看看C#如何配置log4net讓日志分類記錄到不同的日志文件吧2024-02-02C#將hashtable值轉(zhuǎn)換到數(shù)組中的方法
這篇文章主要介紹了C#將hashtable值轉(zhuǎn)換到數(shù)組中的方法,涉及C#中CopyTo方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04C#實(shí)現(xiàn)計(jì)算年齡的簡(jiǎn)單方法匯總
本文給大家分享的是C#代碼實(shí)現(xiàn)的簡(jiǎn)單實(shí)用的給出用戶的出生日期,計(jì)算出用戶的年齡的代碼,另外附上其他網(wǎng)友的方法,算是對(duì)計(jì)算年齡的一次小結(jié),希望大家能夠喜歡。2015-05-05c#使用UTF-8編碼實(shí)現(xiàn)處理多語(yǔ)言文本
UTF-8編碼是現(xiàn)代應(yīng)用中處理多語(yǔ)言文本的首選,所以本文為大家詳細(xì)介紹了C#如何使用UTF-8編碼實(shí)現(xiàn)處理多語(yǔ)言文本,感興趣的小伙伴可以了解下2024-01-01