解決WCF不能直接序列化SqlParameter類型的問題
錯誤描述:
由于內(nèi)部錯誤,服務器無法處理該請求。有關該錯誤的詳細信息,請打開服務器上的 IncludeExceptionDetailInFaults (從 ServiceBehaviorAttribute 或從 <serviceDebug> 配置行為)以便將異常信息發(fā)送回客戶端,或打開對每個 Microsoft .NET Framework SDK 文檔的跟蹤并檢查服務器跟蹤日志。
客戶端調(diào)用WCF的時候報上面的錯誤,WCF只能序列化基礎的數(shù)據(jù)類型,不能直接序列化SqlParameter類型,需要使用自定義類,然后在WCF服務端轉(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>
/// 方法標記為DataContract約束,屬性標記為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ù)長度
/// </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服務端代碼如下:
接口代碼:
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)”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IMyService”。
[ServiceContract]
public interface IMyService
{
[OperationContract]
DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters);
}
}接口實現(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)”菜單上的“重命名”命令,可以同時更改代碼、svc 和配置文件中的類名“MyService”。
// 注意: 為了啟動 WCF 測試客戶端以測試此服務,請在解決方案資源管理器中選擇 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)
};
//實例化WCF服務
ServiceReference.MyServiceClient client=new ServiceReference.MyServiceClient();
//調(diào)用WCF服務提供的方法
DataTable dt = client.ExeceteQuery(strSQL, paras);
this.dataGridView1.DataSource = dt;
}
}
}這樣就可以解決WCF不能直接序列化SqlParameter類型的問題了。
代碼下載地址:點此下載
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問題的解決
這篇文章主要給大家介紹了關于C#(.net)中按字節(jié)數(shù)截取字符串最后出現(xiàn)亂碼問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-06-06

