解决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类型的问题了。

代码下载地址:点此下载

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

(0)

相关推荐

  • C# 中用 Sqlparameter 的两种用法

    新建一个表: create table abc ( id int IDENTITY(1,1) NOT NULL, name nvarchar(100) , sex nvarchar(10) ) insert into abc values('asf','男') insert into abc values('ai','女') 创建表格完成. 新建一个存储过程: create procedure selbyid ( @id int, @thename nvarchar(100) output )

  • asp.net SqlParameter如何根据条件有选择的添加参数

    SqlParameter带参数的增删改查语句,可以防止注入.有时候写sql语句的时候会根据方法传进来的参数来判断sql语句中where条件的参数. 一般方法 DAL层方法 复制代码 代码如下: public UserInfo GetAll(UserInfo a) { string strSql = "select id,name,code,password from [tb].[dbo].[User] where 1=1"; strSql += " and [id]=@id&

  • 详解C#中SqlParameter的作用与用法

    一般来说,在更新DataTable或是DataSet时,如果不采用SqlParameter,那么当输入的Sql语句出现歧义时,如字符串中含有单引号,程序就会发生错误,并且他人可以轻易地通过拼接Sql语句来进行注入攻击. string sql = "update Table1 set name = 'Pudding' where ID = '1'";//未采用SqlParameter SqlConnection conn = new SqlConnection(); conn.Conne

  • asp.net SqlParameter关于Like的传参数无效问题

    按常规的思路,我们会这样写 复制代码 代码如下: String searchName ="Sam"; String strSql = "select * FROM Table1 where Name like '%@Name%' "; SqlParameter[] parameters = { new SqlParameter("@Name", searchName) }; 但结果是查询不到结果,跟踪代码也没有发现错误,又不想用字符串拼接的方式(

  • 数据库SqlParameter 的插入操作,防止sql注入的实现代码

    例子:  点击Button1按钮的时候就把数据插入数据库中. 复制代码 代码如下: using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Text;using System.Data.SqlClient;using System.Data;using Syste

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

    错误描述: 由于内部错误,服务器无法处理该请求.有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或打开对每个 Microsoft .NET Framework SDK 文档的跟踪并检查服务器跟踪日志. 客户端调用WCF的时候报上面的错误,WCF只能序列化基础的数据类型,不能直接序列化SqlParameter类型,

  • Redis序列化转换类型报错的解决

    Cannot convert value of type 'org.springframework.data.redis.core.convert.MappingRedisConverter' to required type 'org.springframework.data.redis.core.mapping.RedisMappingContext': no matching editors or conversion strategy found 在setValue的序列化方式的时候报错

  • python使用json序列化datetime类型实例解析

    使用python的json模块序列化时间或者其他不支持的类型时会抛异常,例如下面的代码: # -*- coding: cp936 -*- from datetime import datetime import json if __name__=='__main__': now = datetime.now() json.dumps({'now':now}) 运行会出现下面的错误信息: Traceback (most recent call last): File "C:\Users\xx\De

  • 解决python写入mysql中datetime类型遇到的问题

    刚开始使用python,还不太熟练,遇到一个datetime数据类型的问题: 在mysql数据库中,有一个datetime类型的字段用于存储记录的日期时间值.python程序中有对应的一个datetime变量dt. 现在需要往mysql数据库中添加记录,每次添加时,将datetime型变量dt写入mysql数据库tablename表中exTime字段里. 问题,如何写入?调试时,总是无法写入. 运行环境:windows10 python 3.6 mysql5.6.38 运行结果提示: Proce

  • 完美解决element-ui的el-input设置number类型后的相关问题

    element-ui的el-input, 设置type="number"后,后边会多一个上下箭头,并且在中文输入法输入数据的时候,光标上移!! 前端的强迫症啊 (凭啥你这输入框和别人的不一样, 凭啥你光标就上移了, 你就不能正常点!!!) so,解决一下 1. 解决掉上下箭头 ::v-deep input::-webkit-outer-spin-button, ::v-deep input::-webkit-inner-spin-button { -webkit-appearance:

  • 解决SpringBoot下Redis序列化乱码的问题

    目录 SpringBoot下Redis序列化乱码 注意问题 SpringBoot配置Redis序列化规则,防止乱码 下面我们可以编写测试类了 具体可以看下图 我们需要对它进行配置 SpringBoot下Redis序列化乱码 项目最初的序列化方案用的是JDK序列化类,但保存到redis里会产生乱码不方便查看管理. public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {         redisTem

  • Jackson处理Optional时遇到问题的解决与分析

    目录 前言 目录 正文 1. 序列化Optional类型的问题 2. 原因分析 3. 解决办法 总结 前言 Optional是Java8中增加的一个特性,它的出现是为了解决Java中的空指针问题,相关介绍可以参考这篇Java8中的Optional操作: 但是在Jackson中操作Optional类型的属性时,会遇到一些问题,比如序列化的数据不符合预期等: 下面就来介绍下遇到的问题以及如何解决: 目录 序列化Optional类型的问题 原因分析 解决办法 正文 1. 序列化Optional类型的问

  • 如何利用Jackson序列化忽略指定类型的属性详解

    前言 本文准确来讲是探讨如何用 Jackson 来序列化 Apache avro 对象,因为简单用 Jackson 来序列化 Apache avro 对象会报错.原因是序列化 Schema getSchema() 时会报错,后面会讲到,需要序列化时忽略该属性.那么能不能在 getSchema() 上加上 @JsonIgnore 来忽略该属性呢?原理上是通的.不过手工修改的 avsc 生成的 Java 文件随时会因为重新编译而还原,所以不太具有实际可操作性,当然通过定制编译 avsc 用的模板文件

  • 详解Python之数据序列化(json、pickle、shelve)

    一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样.很多时候我们会有这样的需求: 把内存中的各种数据类型的数据通过网络传送给其它机器或客户端: 把内存中的各种数据类型的数据保存到本地磁盘持久化: 2.数据格式 如果要将一个系统内的数据通过网络传输给其它系统或客户端,我们通常都需要先把这些数据转化为字符串或字节串,而且需要规定一种统一的数据格式才能让数据接收端正确解析并理解这些数据的含义.XML 是早期被

  • C# web api返回类型设置为json的两种方法

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Application_Start()方法中添加一句: 复制代码 代码如下: GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 修改后: 复制代码 代码如下: protected void

随机推荐