-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Serialization of DataColumn Type Corrected #27286
Conversation
|
|
||
| dc.DataType = (Type)info.GetValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.DataType", i), typeof(Type)); | ||
| string typeName = (string)info.GetValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.DataType", i), typeof(string)); | ||
| dc.DataType = Type.GetType(typeName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should throw here if the type isn't resolvable: Type.GetType(typeName, throwOnError: true);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danmosemsft @stephentoub any strong opinion whether we should throw a TypeLoadException or a SerializationException here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the common pattern is a SerializationException with a nested exception (TypeLoadException in this case)
| ms.Seek(0, SeekOrigin.Begin); | ||
| dtDeserialized = (DataTable)bf.Deserialize(ms); | ||
| } | ||
| Assert.Equal(dc.DataType.ToString(), dtDeserialized.Columns[0].DataType.ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to call .ToString() on both types? I expect Assert.Equal to be able to check for equality of two types.
| public void DataColumnTypeSerialization() | ||
| { | ||
| DataTable dt = new DataTable("MyTable"); | ||
| DataColumn dc = new DataColumn("dc", typeof(Int32)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: int instead of Int32
| info.AddValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.MaxLength", i), Columns[i].MaxLength); | ||
| info.AddValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.DataType", i), Columns[i].DataType); | ||
|
|
||
| info.AddValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.DataType", i), Columns[i].DataType.AssemblyQualifiedName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When someone tries to deserialize on .NET Core a DataTable serialized on NETFX using SerializationFormat.Binary, it will throw (because Type is not serializable). Is the error reasonable and if not can we improve it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I understand you correctly, you are talking about the situation when DataTable is serialized on netfx and when we are trying to deserialize it in .net core, it will throw an exception as DataTable.DataColumn_{0}.DataType will be of type Type rather than string.
We can add a private optional field to tell whether the data has been serialized on netfx or on netcore. Then we can take appropriate action while deserializing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need a field. In .NET Framework it reads off the value here:
dc.SimpleType = (SimpleType)info.GetValue(string.Format(formatProvider, "DataTable.DataColumn_{0}.SimpleType", i), typeof(SimpleType));
In .NET Core you would check whether info contained a value for DataTable.DataColumn_{0}.SimpleType and if so then it came from .NET Framework and you can't deal with that so you have to bail with a SerializationException with a nice message explaining that .NET Core cannot deserialize DataTables sewrialized on .NET Framework using SerializationFormat.Binary and they should use SerializationFormat.Xml or some other serialization mechanism.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no way to check whether info contains string.Format(formatProvider, "DataTable.DataColumn_{0}.SimpleType", i), typeof(SimpleType) this or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't browse through the SerializationInfo object (by using its internal helper methods) outside of System.Private.CoreLib. There's a reason for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe throwing a SerializationException is enough here. We don't do anything fancy at other places where we can't deserialize unsupported types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason we are not changing the identifier (DataTable.DataColumn_{0}.DataType)? We are now storing a different "kind" of data inside it, although for the same purpose. It seems to me it may be clearer to rename it.
Even if later we modified .NET Framework to read/write this "new" format, it does not require us use the same name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah it would be good to change it . I suggestDataTable.DataColumn_{0}.DataType_AssemblyQualifiedName ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't browse through the SerializationInfo object (by using its internal helper methods) outside of System.Private.CoreLib.
I would have expected GetValueNoThrow to do the job? But it's fine as is.
|
@dotnet-bot test OSX x64 Debug Build |
|
@dotnet-bot test Tizen armel Debug Build |
|
@danmosemsft any more feedback ? |
Commit migrated from dotnet/corefx@a87573a
Fixes https://github.com/dotnet/corefx/issues/26472