Add JSON Serialization Support for OLE#11527
Conversation
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/BinaryFormat/WinFormsBinaryFormatWriter.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #11527 +/- ##
====================================================
- Coverage 97.03492% 76.03659% -20.99833%
====================================================
Files 1182 3178 +1996
Lines 354561 639600 +285039
Branches 5411 47215 +41804
====================================================
+ Hits 344048 486330 +142282
- Misses 9724 149750 +140026
- Partials 789 3520 +2731
Flags with carried forward coverage won't be shown. Click here to find out more. |
JeremyKuhne
left a comment
There was a problem hiding this comment.
Generally looks good, some minor comments.
src/System.Windows.Forms/src/System/Windows/Forms/BinaryFormat/WinFormsBinaryFormatWriter.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
|
@willibrandon you might be interested in the clipboard work here. |
…ot forcing preview language version which is not supported by VB Use fluent assertions in ClipboardProxyTests - copied from Loni's PR dotnet#11527 for future merging.
Enable simple creation of VB test projects in this repo solution by not forcing preview language version which is not supported by VB Use fluent assertions in ClipboardProxyTests - copied from Loni's PR #11527 for future merging.
eba27ab to
f989d2c
Compare
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataObjectTests.cs
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Nrbf/WinFormsSerializationRecordExtensions.cs
Outdated
Show resolved
Hide resolved
|
Thanks for working on these new APIs 🤤 I plan on testing your branch this evening, and will post any feedback that I have here. |
|
Looks good! I am able to drag and drop JSON cats now 😸 var data = new DataObject();
var cat = new NyanCat()
{
Ascii = _nyanCatAscii
};
data.SetDataAsJson(nameof(_nyanCatAscii), cat);
toolStripItem.DoDragDrop(
data: data,
allowedEffects: DragDropEffects.All,
dragImage: _nyanCatAscii301Bmp,
cursorOffset: new Point(0, 111),
useDefaultDragImage: false); |
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ClipboardTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/ComDisabledTests/ClipboardComTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Nrbf/WinFormsSerializationRecordExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Nrbf/WinFormsSerializationRecordExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Nrbf/WinFormsSerializationRecordExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
636f011 to
b958ea9
Compare
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataObjectTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/Clipboard.cs
Outdated
Show resolved
Hide resolved
392d779 to
be917f2
Compare
be917f2 to
c3e7d65
Compare
src/System.Windows.Forms/tests/TestUtilities/DataObjectTestHelpers.cs
Outdated
Show resolved
Hide resolved
| outData.Should().BeSameAs(data); | ||
| } | ||
|
|
||
| public static IEnumerable<object[]> DataObjectWithJsonMockRoundTripData() |
There was a problem hiding this comment.
Consider replacing with TheoryData time permitting
src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataObjectTests.cs
Outdated
Show resolved
Hide resolved
- Add test for requiring resolver with SetDataAsJson
...orms/tests/UnitTests/System/Windows/Forms/BinaryFormat/WinFormsBinaryFormattedObjectTests.cs
Outdated
Show resolved
Hide resolved
...orms/tests/UnitTests/System/Windows/Forms/BinaryFormat/WinFormsBinaryFormattedObjectTests.cs
Outdated
Show resolved
Hide resolved
...orms/tests/UnitTests/System/Windows/Forms/BinaryFormat/WinFormsBinaryFormattedObjectTests.cs
Outdated
Show resolved
Hide resolved
| { | ||
| object? result = _innerData.GetData(format, autoConvert); | ||
| // Avoid exposing our internal JsonData<T> | ||
| return result is IJsonData ? null : result; |
There was a problem hiding this comment.
We would need the same change in Clipboard.GetData, or alternatively we could block this in the BinaryFormatUtilities reader code. This is the case of legacyMode == true and we can test if the stream contains BD-ed JsonData struct
There was a problem hiding this comment.
Clipboard.GetData will call to DataObject.GetData so I don't think JsonData will still not be exposed in that scenario, but I'll also write a test for this
There was a problem hiding this comment.
You are right, but still user applications that have no access to JsonData type will throw a first chance SerializationException from BInaryFormatter. If this scenario is blocked before the binary formatter, then there is no exception.
There was a problem hiding this comment.
Wouldn't the exception be a good indicator for user the data has been JSON serialized and binary formatted - if they want to deserialize this with BinaryFormatter to retrieve the data, they need to follow recommended steps? Otherwise, user will just get null and that gives very little information to user what went wrong. We also cannot avoid this exception from happening if user is trying to retrieve data in older .NET versions. We check and return null here because this is for in proc scenarios where users doing SetDataAsJson should use TryGetData instead of GetData.
There was a problem hiding this comment.
I agree with argument about exception stirring the user in the right direction. But are you sure that result is IJsonData can happen outside an internalsvisible to assembly?
There was a problem hiding this comment.
Yes, I had tested this in our scratch project which does not have InternalsVisibleTo and this is the following results:
TestData testData = new() { x = 1 };
DataObject dataObject = new DataObject();
dataObject.SetDataAsJson("test", testData);
// This is null.
var test1 = dataObject.GetData("test");
Clipboard.SetDataObject(dataObject, copy: false);
// This is null.
var test2 = Clipboard.GetData("test");
Clipboard.SetDataObject(dataObject, copy: true);
// Empty memory stream. If first chance exception on, throws SerializationException when path to use BinaryFormatter enabled
var test3 = Clipboard.GetData("test");There was a problem hiding this comment.
But are you hitting a breakpoint on line 243 with result not null?
...icrosoft.VisualBasic/tests/UnitTests/Microsoft/VisualBasic/MyServices/ClipboardProxyTests.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/Clipboard.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/TestUtilities/DataObjectTestHelpers.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Nrbf/WinFormsSerializationRecordExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/OLE/JsonData.cs
Outdated
Show resolved
Hide resolved
|
Congratulations on getting this merged! |
Related: #11368
This is a start to support JSON serialization in OLE scenarios.
JsonData: This is our wrapper class that holds the JSON serialized data along with the original type information. Note that the data that is being JSON serialized uses default JsonSerializer behavior. Users can follow the remarks of the public APIs if custom JSON serialization behavior is needed.Public APIs:
DataObject.SetDataAsJson()- Allows users to add data toDataObjectthat will be JSON serialized. This is how we support JSON serialization for drag/drop scenario.Clipboard.SetDataAsJson()- Allows users to conveniently JSON serialize a type onto the clipboard, but note that this does not acceptDataObjectbeing passed in. If users want to place aDataObjecton the clipboard, users should ensure data they want to be JSON serialized is already in theDataObjectby utilizingDataObject.SetDataAsJsonand then useClipboard.SetDataObject().Control.DoDragDropAsJson()- Allows users to conveniently JSON serialize a type for drag operation, but note that this does not acceptDataObjectbeing passed in. If users wants to start a drag operation with aDataObject, user should ensure data they want to be JSON serialized is already in theDataObjectby utilizingDataObject.SetDataAsJsonand then useControl.DoDragDrop()Tests:
JsonData<T>. If using legacy GetData APIs, user should change to use TryGetData APIs, otherwise follow recommendations to manually deserialize the data.JsonDatanot existing in .NET 8. In order to properly deserialize, users will need to follow recommendations to manually deserialize the stream.JsonSerializeruses reflection to serialize by default, which will not be available when trimming is turned on. In the future, we will need to either use source generator APIs to support trimming or configure JsonSerializerOptions.TypeInfoResolverto support trim scenarios.
Microsoft Reviewers: Open in CodeFlow