如何在 C# 中序列化 DBParameter
本文关键字:序列化 DBParameter | 更新日期: 2023-09-27 18:34:36
我正在尝试序列化我在类中定义的DBParameter。
当它尝试转换为序列化时,它会给出以下错误。
"使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。">
这是我的代码
[Serializable]
public class DemoClass{
public List<DbParameter> Parameters { get; set; }
}
任何人都可以帮我解决这个问题吗? 如何序列化参数属性?
谢谢
DbParameter
不是序列化的好选择。
首先,存在它是一个抽象基类的问题,因此对于大多数序列化程序(包括XmlSerializer
(,您需要提前正式通告预期的具体子类 - 而那些不需要这样做的人通常会想要[Serializable]
- 但事实并非如此。
第二个(也许更重要的(问题是它是实现(它基本上与 ADO.NET 绑定(,其中序列化应该是关于数据的。
我强烈建议出于序列化目的编写自己的 DTO 模型,该模型侧重于您需要了解的内容,例如Name
,Value
是最明显的事情,但DataType
和Direction
也很重要 - 并序列化您自己的模型。这将解决这两个问题。
还有第三个问题,即我首先会质疑序列化参数的目的。如果这是出于 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;
}
}
}