解决WCF不能直接序列化SqlParameter类型的问题
错误描述:
由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从配置行为)以便将异常信息发送回客户端,或打开对每个 Microsoft .NET Framework SDK 文档的跟踪并检查服务器跟踪日志。客户端调用WCF的时候报上面的错误,WCF只能序列化基础的数据类型,不能直接序列化SqlParameter类型,需要使用自定义类,然后在WCF服务端转换的方式解决:
自定义类代码如下:
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{/// /// 方法标记为DataContract约束,属性标记为DataMember/// [Serializable][DataContract]public class SetSqlParameter{#region 属性/// /// 参数名称/// [DataMember]private string paraName = ""; public string ParaName{get { return this.paraName; }set { this.paraName = value; }}/// /// 参数长度/// [DataMember]private int paraLength = 0; public int ParaLength{get { return this.paraLength; }set { this.paraLength = value; }}/// /// 参数值/// [DataMember]private object paraValue = https://www.it610.com/article/null; public object ParaValue{get { return this.paraValue; }set { this.paraValue = value; }}/// /// 参数类型/// [DataMember]private SqlDbType paraDbType = SqlDbType.NVarChar; public SqlDbType ParaDbType{get { return this.paraDbType; }set { this.paraDbType = value; }}#endregion/// /// 构造函数/// /// public SetSqlParameter(SqlParameter sPara){this.paraName = sPara.ParameterName; this.paraLength = sPara.Size; this.paraValue = https://www.it610.com/article/sPara.Value; this.paraDbType = sPara.SqlDbType; }/// /// 转换成SqlParameter类型/// ///public SqlParameter ConvertToSqlParameter(){SqlParameter parameter = new SqlParameter(this.paraName, this.paraDbType, this.paraLength); parameter.Value = https://www.it610.com/article/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{// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IMyService”。[ServiceContract]public interface IMyService{[OperationContract]DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters); }}
接口实现类代码:
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{// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“MyService”。// 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 MyService.svc 或 MyService.svc.cs,然后开始调试。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类型的数组转换成SqlParameter类型的数组para[i] = parameters[i].ConvertToSqlParameter(); }cmd.Parameters.AddRange(para); }SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dtReturn); }return dtReturn; }}}
客户端调用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 "; //定义SqlParameterSqlParameter para = new SqlParameter("@TypeCode", SqlDbType.Int); para.Value = https://www.it610.com/article/1; //定义SetSqlParameter类型的数组SetSqlParameter[] paras = new SetSqlParameter[] {new SetSqlParameter(para)}; //实例化WCF服务ServiceReference.MyServiceClient client=new ServiceReference.MyServiceClient(); //调用WCF服务提供的方法DataTable dt = client.ExeceteQuery(strSQL, paras); this.dataGridView1.DataSource = dt; }}}
这样就可以解决WCF不能直接序列化SqlParameter类型的问题了。
代码下载地址:点此下载
【解决WCF不能直接序列化SqlParameter类型的问题】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- PHP|PHP 遇见 Serverless,帮你解决这些痛点!
- 听说(分布式ID不能全局递增())
- Debug专栏|“OSError: [WinError 126] 找不到指定的模块”的解决办法
- Are|成功解决C++编译器报错[Error]in C++98 ‘arr‘ must be initialized by constructor, not by‘{...}‘
- 测试用例方法
- VS|VS 返回值被忽略的解决方法
- Mybatis中单双引号引发的惨案及解决
- Java|Java ConcurrentModificationException异常解决案例详解
- Vue|解决导航守卫router.beforeResolve使用不了this.$store
- 详解JavaScript中任意两数加减的解决方案