错误描述:
由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或打开对每个 Microsoft .NET Framework SDK 文档的跟踪并检查服务器跟踪日志。
客户端调用WCF的时候报上面的错误,WCF只能序列化基础的数据类型,不能直接序列化SqlParameter类型,需要使用自定义类,然后在WCF服务端转换的方式解决:
自定义类代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
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> /// 参数名称 /// </summary> [DataMember] private string paraName = "" ; public string ParaName { get { return this .paraName; } set { this .paraName = value; } } /// <summary> /// 参数长度 /// </summary> [DataMember] private int paraLength = 0; public int ParaLength { get { return this .paraLength; } set { this .paraLength = value; } } /// <summary> /// 参数值 /// </summary> [DataMember] private object paraValue = null ; public object ParaValue { get { return this .paraValue; } set { this .paraValue = value; } } /// <summary> /// 参数类型 /// </summary> [DataMember] private SqlDbType paraDbType = SqlDbType.NVarChar; public SqlDbType ParaDbType { get { return this .paraDbType; } set { this .paraDbType = value; } } #endregion /// <summary> /// 构造函数 /// </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> /// 转换成SqlParameter类型 /// </summary> /// <returns></returns> public SqlParameter ConvertToSqlParameter() { SqlParameter parameter = new SqlParameter( this .paraName, this .paraDbType, this .paraLength); parameter.Value = this .paraValue; return parameter; } } } |
WCF服务端代码如下:
接口代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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); } } |
接口实现类代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
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类型的数组 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类型的问题了。
代码下载地址:点此下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.cnblogs.com/dotnet261010/p/7457527.html