解決WCF不能直接序列化SqlParameter類型的問題
錯(cuò)誤描述:
由于內(nèi)部錯(cuò)誤,服務(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類型的問題了。
代碼下載地址:點(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的基本用法,通過Mask的原理分析實(shí)例代碼相結(jié)合給大家講解的非常詳細(xì),需要的朋友參考下吧2021-06-06
C#配置log4net實(shí)現(xiàn)將日志分類記錄到不同的日志文件中
log4net是.Net下一個(gè)非常優(yōu)秀的開源日志記錄組件,log4net記錄日志的功能非常強(qiáng)大,它可以將日志分不同的等級(jí),以不同的格式,輸出到不同的媒介,下面我們就來看看C#如何配置log4net讓日志分類記錄到不同的日志文件吧2024-02-02
C#將hashtable值轉(zhuǎn)換到數(shù)組中的方法
這篇文章主要介紹了C#將hashtable值轉(zhuǎn)換到數(shù)組中的方法,涉及C#中CopyTo方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
C#實(shí)現(xiàn)計(jì)算年齡的簡(jiǎn)單方法匯總
本文給大家分享的是C#代碼實(shí)現(xiàn)的簡(jiǎn)單實(shí)用的給出用戶的出生日期,計(jì)算出用戶的年齡的代碼,另外附上其他網(wǎng)友的方法,算是對(duì)計(jì)算年齡的一次小結(jié),希望大家能夠喜歡。2015-05-05
c#使用UTF-8編碼實(shí)現(xiàn)處理多語(yǔ)言文本
UTF-8編碼是現(xiàn)代應(yīng)用中處理多語(yǔ)言文本的首選,所以本文為大家詳細(xì)介紹了C#如何使用UTF-8編碼實(shí)現(xiàn)處理多語(yǔ)言文本,感興趣的小伙伴可以了解下2024-01-01

