解决WCF不能直接序列化SqlParameter类型的问题

 更新时间:2022年03月04日 10:33:55   作者:.NET开发菜鸟  
这篇文章介绍了解决WCF不能直接序列化SqlParameter类型的问题,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

错误描述:

由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或打开对每个 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
{
    /// <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服务端代码如下:

接口代码:

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 ";

            //定义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类型的问题了。

代码下载地址:点此下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#保存图片到数据库并读取显示图片的方法

    C#保存图片到数据库并读取显示图片的方法

    将图像保存到SQL server2000的Image字段中
    2013-04-04
  • C#实现倒计时关闭提示框功能

    C#实现倒计时关闭提示框功能

    最近小编接到一个功能需要实现一个提示框并且能自动关闭的,看到这个需求真是懵了,四处搜集资料才搞定,接下来通过本文给大家分享C#实现倒计时关闭提示框功能,感兴趣的朋友跟随小编一起看看吧
    2019-07-07
  • Visual C#.Net 网络程序开发-Socket篇

    Visual C#.Net 网络程序开发-Socket篇

    Visual C#.Net 网络程序开发-Socket篇...
    2007-03-03
  • C#跨窗体操作(引用传递) 实例代码

    C#跨窗体操作(引用传递) 实例代码

    现在给大家介绍一种最简单的跨窗体操作,WinForm的窗体是一个类,C#的类是引用类型,那么我们应该可以将WinForm窗体类进行传递,那不就可以进行操作了么?
    2013-03-03
  • 基于字符集、字符编码与HTTP编码解码之万象详解

    基于字符集、字符编码与HTTP编码解码之万象详解

    本篇文章小编为大家介绍,基于字符集、字符编码与HTTP编码解码之万象详解。需要的朋友参考下
    2013-04-04
  • C# Directory.GetFiles()函数案例详解

    C# Directory.GetFiles()函数案例详解

    这篇文章主要介绍了C# Directory.GetFiles()函数案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C# cmd中修改显示(显示进度变化效果)的方法

    C# cmd中修改显示(显示进度变化效果)的方法

    好多人想在运行或者调试含有大量数据或者比较慢C#程序的时候能够显示自己的程序完成的程度,这里有一个方法能发不断地修改cmd的同一行,以达到显示完成百分比的目的
    2013-04-04
  • .NET C#利用ZXing生成、识别二维码/条形码

    .NET C#利用ZXing生成、识别二维码/条形码

    ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。这篇文章主要给大家介绍了.NET C#利用ZXing生成、识别二维码/条形码的方法,文中给出了详细的示例代码,有需要的朋友们可以参考借鉴。
    2016-12-12
  • winform把Office转成PDF文件

    winform把Office转成PDF文件

    这篇文章介绍了winform把Office转成PDF文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中const,readonly和static关键字的用法介绍

    C#中const,readonly和static关键字的用法介绍

    这篇文章介绍了C#中const,readonly和static关键字的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08

最新评论