WCF只能序列化基础的数据类型,不能直接序列化SqlParameter类型,需要使用自定义类

客户端调用WCF的时候报上面的错误,WCF只能序列化基础的数据类型,不能直接序列化SqlParameter类型,需要使用自定义类,然后在WCF服务端转换的方式解决:

自定义类代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data;
 4 using System.Data.SqlClient;
 5 using System.Linq;
 6 using System.Runtime.Serialization;
 7 using System.Text;
 8 using System.Threading.Tasks;
 9 
10 namespace CommonLib.CustomClass
11 {
12     /// <summary>
13     /// 方法标记为DataContract约束,属性标记为DataMember
14     /// </summary>
15     [Serializable]
16     [DataContract]
17     public class SetSqlParameter
18     {
19         #region 属性
20 
21         /// <summary>
22         /// 参数名称
23         /// </summary>
24         [DataMember]
25         private string paraName = "";
26         public string ParaName
27         {
28             get { return this.paraName; }
29             set { this.paraName = value; }
30 
31         }
32        
33 
34         /// <summary>
35         /// 参数长度
36         /// </summary>
37         [DataMember]
38         private int paraLength = 0;
39         public int ParaLength
40         {
41 
42             get { return this.paraLength; }
43             set { this.paraLength = value; }
44         }
45        
46 
47         /// <summary>
48         /// 参数值
49         /// </summary>
50         [DataMember]
51         private object paraValue = null;
52         public object ParaValue
53         {
54             get { return this.paraValue; }
55             set { this.paraValue = value; }
56         }
57        
58 
59         /// <summary>
60         /// 参数类型
61         /// </summary>
62         [DataMember]
63         private SqlDbType paraDbType = SqlDbType.NVarChar;
64         public SqlDbType ParaDbType
65         {
66             get { return this.paraDbType; }
67 
68             set { this.paraDbType = value; }
69         }
70        
71         #endregion
72 
73         /// <summary>
74         /// 构造函数
75         /// </summary>
76         /// <param name="sPara"></param>
77         public SetSqlParameter(SqlParameter sPara)
78         {
79             this.paraName = sPara.ParameterName;
80             this.paraLength = sPara.Size;
81             this.paraValue = sPara.Value;
82             this.paraDbType = sPara.SqlDbType;
83         }
84 
85         /// <summary>
86         /// 转换成SqlParameter类型
87         /// </summary>
88         /// <returns></returns>
89         public SqlParameter ConvertToSqlParameter()
90         {
91             SqlParameter parameter = new SqlParameter(this.paraName, this.paraDbType, this.paraLength);
92             parameter.Value = this.paraValue;
93             return parameter;
94         }
95     }
96 }

WCF服务端代码如下:

接口代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.Serialization;
 5 using System.ServiceModel;
 6 using System.Text;
 7 using System.Data;
 8 using System.Data.SqlClient;
 9 using CommonLib.CustomClass;
10 
11 namespace WcfServiceDemo
12 {
13     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IMyService”。
14     [ServiceContract]
15     public interface IMyService
16     {
17         [OperationContract]
18         DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters);
19     }
20 }

接口实现类代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data;
 4 using System.Data.SqlClient;
 5 using System.Linq;
 6 using System.Runtime.Serialization;
 7 using System.ServiceModel;
 8 using System.Text;
 9 using System.Configuration;
10 using CommonLib.CustomClass;
11 
12 namespace WcfServiceDemo
13 {
14     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“MyService”。
15     // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 MyService.svc 或 MyService.svc.cs,然后开始调试。
16     public class MyService : IMyService
17     {
18 
19         public DataTable ExeceteQuery(string strSQL, params SetSqlParameter[] parameters)
20         {
21             DataTable dtReturn = new DataTable();
22             dtReturn.TableName = "ExecuteQuery";
23             string strCon = ConfigurationManager.ConnectionStrings["HealthHospInfection"].ConnectionString;
24             using (SqlConnection conn = new SqlConnection(strCon))
25             {
26                 SqlCommand cmd = new SqlCommand(strSQL, conn);
27                 conn.Open();
28                 if (parameters != null)
29                 {
30                     SqlParameter[] para = new SqlParameter[parameters.Length];
31                     for (int i = 0; i < parameters.Length; i++)
32                     {
33                         //把SetSqlParameter类型的数组转换成SqlParameter类型的数组
34                         para[i] = parameters[i].ConvertToSqlParameter();
35                     }
36                     cmd.Parameters.AddRange(para);
37                 }
38 
39                 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
40                 adapter.Fill(dtReturn);
41             }
42             return dtReturn;
43         }
44     }
45 }

客户端调用WCF代码:

 1 using CommonLib.CustomClass;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.ComponentModel;
 5 using System.Data;
 6 using System.Data.SqlClient;
 7 using System.Drawing;
 8 using System.Linq;
 9 using System.Text;
10 using System.Threading.Tasks;
11 using System.Windows.Forms;
12 
13 
14 namespace winClient
15 {
16     public partial class Form1 : Form
17     {
18         public Form1()
19         {
20             InitializeComponent();
21         }
22 
23         private void btn_GetData_Click(object sender, EventArgs e)
24         {
25             
26             string strSQL = " SELECT * FROM BaseSetMainInfo WHERE TypeCode=@TypeCode ";
27 
28             //定义SqlParameter
29             SqlParameter para = new SqlParameter("@TypeCode", SqlDbType.Int);
30             para.Value = 1;
31 
32             //定义SetSqlParameter类型的数组
33             SetSqlParameter[] paras = new SetSqlParameter[] { 
34                 new SetSqlParameter(para)
35             };
36 
37             //实例化WCF服务
38             ServiceReference.MyServiceClient client=new ServiceReference.MyServiceClient();
39             //调用WCF服务提供的方法
40             DataTable dt = client.ExeceteQuery(strSQL, paras);
41             this.dataGridView1.DataSource = dt;
42 
43         }
44     }
45 }

这样就可以解决WCF不能直接序列化SqlParameter类型的问题了。

代码下载地址:https://files.cnblogs.com/files/dotnet261010/WcfSqlParameterDemo.rar

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值