如何在 C# 中序列化 DBParameter

本文关键字:序列化 DBParameter | 更新日期: 2023-09-27 18:34:36

我正在尝试序列化我在类中定义的DBParameter。

当它尝试转换为序列化时,它会给出以下错误。

"使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。">

这是我的代码

[Serializable]
public class DemoClass{
public List<DbParameter> Parameters { get; set; }
}

任何人都可以帮我解决这个问题吗? 如何序列化参数属性?

谢谢

如何在 C# 中序列化 DBParameter

DbParameter不是

序列化的好选择。

首先,存在它是一个抽象基类的问题,因此对于大多数序列化程序(包括XmlSerializer(,您需要提前正式通告预期的具体子类 - 而那些不需要这样做的人通常会想要[Serializable] - 但事实并非如此。

第二个(也许更重要的(问题是它是实现(它基本上与 ADO.NET 绑定(,其中序列化应该是关于数据的

我强烈建议出于序列化目的编写自己的 DTO 模型,该模型侧重于您需要了解的内容,例如NameValue是最明显的事情,但DataTypeDirection也很重要 - 并序列化您自己的模型。这将解决这两个问题。

还有第三个问题,即我首先会质疑序列化参数的目的。如果这是出于 RPC 目的,我强烈建议不要这样做,因为听起来您正在打开一个任意 sql 漏洞。对于 RPC,只需定义并传递参数/参数作为服务边界的一部分。

最好手动序列化它们(集合不是字典(:

public static string ParameterCollectionToXml(System.Data.IDataParameterCollection collection)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    using (System.IO.TextWriter sw = new System.IO.StringWriter(sb))
    {
        using (System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(sw, new System.Xml.XmlWriterSettings()
        {
            Indent = true,
            IndentChars = " ",
            CheckCharacters = false
        }))
        {
            xw.WriteStartDocument();
            xw.WriteStartElement("Parameters");
            foreach (System.Data.IDataParameter thisParameter in collection)
            {
                xw.WriteStartElement("Parameter");

                xw.WriteStartElement("ParameterName");
                xw.WriteValue(thisParameter.ParameterName);
                xw.WriteEndElement();

                xw.WriteStartElement("DbType");
                xw.WriteValue(thisParameter.DbType);
                xw.WriteEndElement();

                xw.WriteStartElement("Direction");
                xw.WriteValue(thisParameter.Direction);
                xw.WriteEndElement();
                xw.WriteStartElement("IsNullable");
                xw.WriteValue(thisParameter.IsNullable);
                xw.WriteEndElement();

                xw.WriteStartElement("SourceColumn");
                xw.WriteValue(thisParameter.SourceColumn);
                xw.WriteEndElement();
                // SourceVersion
                xw.WriteStartElement("Value");
                xw.WriteValue(thisParameter.Value);
                xw.WriteEndElement();
                xw.WriteEndElement();
            } // Next thisParameter 

            xw.WriteEndElement(); // root 
            xw.WriteEndDocument();
            xw.Flush();
        } // End Using xw
        sw.Flush();
    } // End Using sw 
    return sb.ToString();
} // End Function ParameterCollectionToXml 

public static string ParameterCollectionToXml(System.Data.Common.DbParameterCollection collection)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    using (System.IO.TextWriter sw = new System.IO.StringWriter(sb))
    {
        using (System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(sw, new System.Xml.XmlWriterSettings()
        {
            Indent = true,
            IndentChars = " ",
            CheckCharacters = false
        }))
        {
            xw.WriteStartDocument();
            xw.WriteStartElement("Parameters");
            foreach (System.Data.Common.DbParameter thisParameter in collection)
            {
                xw.WriteStartElement("Parameter");

                xw.WriteStartElement("ParameterName");
                xw.WriteValue(thisParameter.ParameterName);
                xw.WriteEndElement();

                xw.WriteStartElement("DbType");
                xw.WriteValue(thisParameter.DbType);
                xw.WriteEndElement();

                xw.WriteStartElement("Direction");
                xw.WriteValue(thisParameter.Direction);
                xw.WriteEndElement();
                xw.WriteStartElement("IsNullable");
                xw.WriteValue(thisParameter.IsNullable);
                xw.WriteEndElement();
                xw.WriteStartElement("Size");
                xw.WriteValue(thisParameter.Size);
                xw.WriteEndElement();

                xw.WriteStartElement("SourceColumn");
                xw.WriteValue(thisParameter.SourceColumn);
                xw.WriteEndElement();
                xw.WriteStartElement("SourceColumnNullMapping");
                xw.WriteValue(thisParameter.SourceColumnNullMapping);
                xw.WriteEndElement();
                // SourceVersion
                xw.WriteStartElement("Value");
                xw.WriteValue(thisParameter.Value);
                xw.WriteEndElement();
                xw.WriteEndElement();
            } // Next thisParameter 

            xw.WriteEndElement(); // root 
            xw.WriteEndDocument();
            xw.Flush();
        } // End Using xw
        sw.Flush();
    } // End Using sw 
    return sb.ToString();
} // End Function ParameterCollectionToXml 

public static string ParameterCollectionToJson(System.Data.Common.DbParameterCollection collection)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    using (System.IO.TextWriter sw = new System.IO.StringWriter(sb))
    {

        using (Newtonsoft.Json.JsonWriter jw = new Newtonsoft.Json.JsonTextWriter(sw))
        {
            jw.Formatting = Newtonsoft.Json.Formatting.Indented;
            jw.WriteStartArray();
            foreach (System.Data.Common.DbParameter thisParameter in collection)
            {
                jw.WriteStartObject();
                jw.WritePropertyName("ParameterName");
                jw.WriteValue(thisParameter.ParameterName);
                jw.WritePropertyName("DbType");
                jw.WriteValue(thisParameter.DbType);

                jw.WritePropertyName("Direction");
                jw.WriteValue(thisParameter.Direction);
                jw.WritePropertyName("IsNullable");
                jw.WriteValue(thisParameter.IsNullable);
                jw.WritePropertyName("Size");
                jw.WriteValue(thisParameter.Size);
                jw.WritePropertyName("SourceColumn");
                jw.WriteValue(thisParameter.SourceColumn);
                jw.WritePropertyName("SourceColumnNullMapping");
                jw.WriteValue(thisParameter.SourceColumnNullMapping);
                // SourceVersion
                jw.WritePropertyName("Value");
                jw.WriteValue(thisParameter.Value);
                jw.WriteEndObject();
            } // Next thisParameter 

            jw.WriteEndArray();
            jw.Flush();
        } // End Using xw
        sw.Flush();
    } // End Using sw 
    return sb.ToString();
}

public static string ParameterCollectionToJson(System.Data.IDataParameterCollection collection)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    using (System.IO.TextWriter sw = new System.IO.StringWriter(sb))
    {

        using (Newtonsoft.Json.JsonWriter jw = new Newtonsoft.Json.JsonTextWriter(sw))
        {
            jw.Formatting = Newtonsoft.Json.Formatting.Indented;
            jw.WriteStartArray();
            foreach (System.Data.IDataParameter thisParameter in collection)
            {
                jw.WriteStartObject();
                jw.WritePropertyName("ParameterName");
                jw.WriteValue(thisParameter.ParameterName);
                jw.WritePropertyName("DbType");
                jw.WriteValue(thisParameter.DbType);

                jw.WritePropertyName("Direction");
                jw.WriteValue(thisParameter.Direction);
                jw.WritePropertyName("IsNullable");
                jw.WriteValue(thisParameter.IsNullable);
                jw.WritePropertyName("SourceColumn");
                jw.WriteValue(thisParameter.SourceColumn);
                // SourceVersion
                jw.WritePropertyName("Value");
                jw.WriteValue(thisParameter.Value);
                jw.WriteEndObject();
            } // Next thisParameter 

            jw.WriteEndArray();
            jw.Flush();
        } // End Using xw
        sw.Flush();
    } // End Using sw 
    return sb.ToString();
}

对于System.Text.Json,这是

namespace JsonTools
{

    public class ParameterCollectionHelper 
    {
        private delegate bool WriteValueExtender_t(System.Type t, System.Text.Json.Utf8JsonWriter jsonWriter, object obj);

        // https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonWriter.cs#L525
        private static bool WriteValueInternalUnhandled(System.Type t, System.Text.Json.Utf8JsonWriter jsonWriter, object obj)
        {
            // The problem with the functional c-type switch is that it is not getting the precompiled speed that the actual switch-case syntax gets. 
            // C# 7+ Switch
            switch (obj)
            {
                case System.Guid tGuid:
                    jsonWriter.WriteStringValue(tGuid);
                    return false;
                case System.String tString:
                    jsonWriter.WriteStringValue(tString);
                    return false;
                case System.Char tChar:
                    jsonWriter.WriteStringValue(tChar.ToString(System.Globalization.CultureInfo.InvariantCulture));
                    return false;
                case System.Boolean tBoolean:
                    jsonWriter.WriteBooleanValue(tBoolean);
                    return false;
                case System.DateTime tDateTime:
                    jsonWriter.WriteStringValue(tDateTime);
                    return false;
                case System.DateTimeOffset tOffset:
                    jsonWriter.WriteStringValue(tOffset);
                    return false;
                case System.Single tSingle:
                    jsonWriter.WriteNumberValue(tSingle);
                    return false;
                case System.Double tDouble:
                    jsonWriter.WriteNumberValue(tDouble);
                    return false;
                case System.Decimal tDecimal:
                    jsonWriter.WriteNumberValue(tDecimal);
                    return false;
                case System.Byte tByte:
                    jsonWriter.WriteNumberValue(tByte);
                    return false;
                case System.SByte tSByte:
                    jsonWriter.WriteNumberValue(tSByte);
                    return false;
                case System.Int16 tInt16:
                    jsonWriter.WriteNumberValue(tInt16);
                    return false;
                case System.UInt16 tUInt16:
                    jsonWriter.WriteNumberValue(tUInt16);
                    return false;
                case System.Int32 tInt32:
                    jsonWriter.WriteNumberValue(tInt32);
                    return false;
                case System.UInt32 tUInt32:
                    jsonWriter.WriteNumberValue(tUInt32);
                    return false;
                case System.Int64 tInt64:
                    jsonWriter.WriteNumberValue(tInt64);
                    return false;
                case System.UInt64 tUInt64:
                    jsonWriter.WriteNumberValue(tUInt64);
                    return false;
                case System.IntPtr tIntPtr:
                    jsonWriter.WriteNumberValue(tIntPtr.ToInt64());
                    return false;
                case System.UIntPtr tUIntPtr:
                    jsonWriter.WriteNumberValue(tUIntPtr.ToUInt64());
                    return false;
                // https://github.com/microsoftarchive/bcl/blob/master/Libraries/BigRational/BigRationalLibrary/BigRational.cs
                // https://github.com/orgs/microsoftarchive/repositories
                case System.Numerics.BigInteger tBigInteger:
                    jsonWriter.WriteStringValue(tBigInteger.ToString(System.Globalization.CultureInfo.InvariantCulture)); // TODO: FixMe
                    return false;
                case byte[] tBuffer:
                    jsonWriter.WriteStringValue(System.Convert.ToBase64String(tBuffer));
                    return false;
            }
            return true;
        }

        private static void WriteValue(System.Text.Json.Utf8JsonWriter jsonWriter, object obj, WriteValueExtender_t extensions)
        {
            if (obj == System.DBNull.Value || obj == null)
            {
                jsonWriter.WriteNullValue();
                return;
            }
            System.Type t = obj.GetType();
            if (WriteValueInternalUnhandled(t, jsonWriter, obj))
                if (extensions != null || extensions(t, jsonWriter, obj))
                    throw new System.NotImplementedException("WriteValue for " + t.FullName);
        }
        private static void WriteValue(System.Text.Json.Utf8JsonWriter jsonWriter, object obj)
        {
            if (obj == System.DBNull.Value || obj == null)
            {
                jsonWriter.WriteNullValue();
                return;
            }
            System.Type t = obj.GetType();
            if (WriteValueInternalUnhandled(t, jsonWriter, obj))
                throw new System.NotImplementedException("WriteValue for " + t.FullName);
        }

        public static string ParameterCollectionToJson(System.Data.Common.DbParameterCollection collection)
        {
            string retValue = null;
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                using (System.Text.Json.Utf8JsonWriter jw = new System.Text.Json.Utf8JsonWriter(stream,
                   new System.Text.Json.JsonWriterOptions
                   {
                       Indented = true
                   })
                )
                {
                    jw.WriteStartArray();
                    foreach (System.Data.Common.DbParameter thisParameter in collection)
                    {
                        jw.WriteStartObject();
                        jw.WritePropertyName("ParameterName");
                        WriteValue(jw, thisParameter.ParameterName);

                        jw.WritePropertyName("DbType");
                        WriteValue(jw, thisParameter.DbType);

                        jw.WritePropertyName("Direction");
                        WriteValue(jw, thisParameter.Direction);
                        jw.WritePropertyName("IsNullable");
                        WriteValue(jw, thisParameter.IsNullable);
                        jw.WritePropertyName("Size");
                        WriteValue(jw, thisParameter.Size);
                        jw.WritePropertyName("SourceColumn");
                        WriteValue(jw, thisParameter.SourceColumn);
                        jw.WritePropertyName("SourceColumnNullMapping");
                        WriteValue(jw, thisParameter.SourceColumnNullMapping);
                        // SourceVersion
                        jw.WritePropertyName("Value");
                        WriteValue(jw, thisParameter.Value);
                        jw.WriteEndObject();
                    } // Next thisParameter 
                    jw.WriteEndArray();
                    jw.Flush();
                } // End Using jw 
                stream.Flush();

                stream.Position = 0;
                byte[] bytes = stream.ToArray();
                retValue = System.Text.Encoding.UTF8.GetString(bytes);
            } // End Using stream
            return retValue;
        }

        public static string ParameterCollectionToJson(System.Data.IDataParameterCollection collection)
        {
            string retValue = null;
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                using (System.Text.Json.Utf8JsonWriter jw = new System.Text.Json.Utf8JsonWriter(stream,
                   new System.Text.Json.JsonWriterOptions
                   {
                       Indented = true
                   })
                )
                {
                    jw.WriteStartArray();
                    foreach (System.Data.IDataParameter thisParameter in collection)
                    {
                        jw.WriteStartObject();
                        jw.WritePropertyName("ParameterName");
                        WriteValue(jw, thisParameter.ParameterName);

                        jw.WritePropertyName("DbType");
                        WriteValue(jw, thisParameter.DbType);

                        jw.WritePropertyName("Direction");
                        WriteValue(jw, thisParameter.Direction);
                        jw.WritePropertyName("IsNullable");
                        WriteValue(jw, thisParameter.IsNullable);
                        jw.WritePropertyName("SourceColumn");
                        WriteValue(jw, thisParameter.SourceColumn);
                        // SourceVersion
                        jw.WritePropertyName("Value");
                        WriteValue(jw, thisParameter.Value);
                        jw.WriteEndObject();
                    } // Next thisParameter 
                    jw.WriteEndArray();
                    jw.Flush();
                } // End Using jw 
                stream.Flush();

                stream.Position = 0;
                byte[] bytes = stream.ToArray();
                retValue = System.Text.Encoding.UTF8.GetString(bytes);
            } // End Using stream
            return retValue;
        }

    }

}