Skip to content

Commit 6451d77

Browse files
authored
Throw PlatformNotSupportedException in netstandard1.3 (#396)
- stop trying to use DCS in the JSON and XML formatters - if `UseDataContractSerializer` or `!UseXmlSerializer`: - `CanReadType(...)` and `CanWriteType(...)` always return `false` - `ReadFromStreamAsync(...)` and `WriteToStreamAsync(...)` always `throw` - change default XML formatter configuration to use `XmlSerializer` - adjust and disable tests in reaction - add tests of new `netstandard1.3` behavior - nits: - correct namespace of `SerializerConsistencyTests`; was alone in previous namespace - s/DataContractFormatter/XmlSerializerFormatter/ to reflect actual `XmlMediaTypeFormatter` test actions
1 parent cb7628f commit 6451d77

11 files changed

+392
-53
lines changed

Diff for: src/System.Net.Http.Formatting/Formatting/JsonMediaTypeFormatter.cs

+23-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Diagnostics.Contracts;
77
using System.IO;
88
using System.Net.Http.Headers;
9+
#if !NETSTANDARD1_3 // Unnecessary when targeting netstandard1.3.
910
using System.Net.Http.Internal;
11+
#endif
1012
using System.Runtime.Serialization.Json;
1113
using System.Text;
1214
using System.Threading;
@@ -214,20 +216,15 @@ public override object ReadFromStream(Type type, Stream readStream, Encoding eff
214216
{
215217
DataContractJsonSerializer dataContractSerializer = GetDataContractSerializer(type);
216218

217-
// JsonReaderWriterFactory is internal, CreateTextReader only supports auto-detecting the encoding
218-
// and auto-detection fails in some cases for the netstandard1.3 project. In addition, DCS encodings are
219-
// limited to UTF8, UTF16BE, and UTF16LE. Convert to UTF8 as we read.
220-
Stream innerStream = string.Equals(effectiveEncoding.WebName, Utf8Encoding.WebName, StringComparison.OrdinalIgnoreCase) ?
219+
#if NETSTANDARD1_3 // Unreachable when targeting netstandard1.3. Return just to satisfy the compiler.
220+
return null;
221+
#else
222+
// DCS encodings are limited to UTF8, UTF16BE, and UTF16LE. Convert to UTF8 as we read.
223+
Stream innerStream =
224+
string.Equals(effectiveEncoding.WebName, Utf8Encoding.WebName, StringComparison.OrdinalIgnoreCase) ?
221225
new NonClosingDelegatingStream(readStream) :
222226
new TranscodingStream(readStream, effectiveEncoding, Utf8Encoding, leaveOpen: true);
223227

224-
#if NETSTANDARD1_3
225-
using (innerStream)
226-
{
227-
// Unfortunately, we're ignoring _readerQuotas.
228-
return dataContractSerializer.ReadObject(innerStream);
229-
}
230-
#else
231228
// XmlDictionaryReader will always dispose of innerStream when we dispose of the reader.
232229
using XmlDictionaryReader reader =
233230
JsonReaderWriterFactory.CreateJsonReader(innerStream, Utf8Encoding, _readerQuotas, onClose: null);
@@ -314,10 +311,8 @@ private void WriteObject(Stream stream, Type type, object value)
314311
{
315312
DataContractJsonSerializer dataContractSerializer = GetDataContractSerializer(type);
316313

314+
#if !NETSTANDARD1_3 // Unreachable when targeting netstandard1.3.
317315
// Do not dispose of the stream. WriteToStream handles that where it's needed.
318-
#if NETSTANDARD1_3
319-
dataContractSerializer.WriteObject(stream, value);
320-
#else
321316
using XmlWriter writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Utf8Encoding, ownsStream: false);
322317
dataContractSerializer.WriteObject(writer, value);
323318
#endif
@@ -328,15 +323,26 @@ private DataContractJsonSerializer CreateDataContractSerializer(Type type, bool
328323
{
329324
Contract.Assert(type != null);
330325

326+
#if NETSTANDARD1_3 // XsdDataContractExporter is not supported in netstandard1.3
327+
if (throwOnError)
328+
{
329+
throw new PlatformNotSupportedException(Error.Format(
330+
Properties.Resources.JsonMediaTypeFormatter_DCS_NotSupported,
331+
nameof(UseDataContractJsonSerializer)));
332+
}
333+
else
334+
{
335+
return null;
336+
}
337+
#else
338+
331339
DataContractJsonSerializer serializer = null;
332340
Exception exception = null;
333341

334342
try
335343
{
336-
#if !NETSTANDARD1_3 // XsdDataContractExporter is not supported in netstandard1.3
337344
// Verify that type is a valid data contract by forcing the serializer to try to create a data contract
338345
FormattingUtilities.XsdDataContractExporter.GetRootElementName(type);
339-
#endif
340346

341347
serializer = CreateDataContractSerializer(type);
342348
}
@@ -362,6 +368,7 @@ private DataContractJsonSerializer CreateDataContractSerializer(Type type, bool
362368
}
363369

364370
return serializer;
371+
#endif
365372
}
366373

367374
/// <summary>

Diff for: src/System.Net.Http.Formatting/Formatting/MediaTypeFormatterCollection.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,11 @@ private static IEnumerable<MediaTypeFormatter> CreateDefaultFormatters()
255255
return new MediaTypeFormatter[]
256256
{
257257
new JsonMediaTypeFormatter(),
258-
new XmlMediaTypeFormatter(),
258+
new XmlMediaTypeFormatter()
259+
#if NETSTANDARD1_3 // XsdDataContractExporter is not supported in netstandard1.3. Cannot use DCS.
260+
{ UseXmlSerializer = true }
261+
#endif
262+
,
259263
new FormUrlEncodedMediaTypeFormatter()
260264
};
261265
}

Diff for: src/System.Net.Http.Formatting/Formatting/XmlMediaTypeFormatter.cs

+19-3
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,23 @@ public object InvokeGetSerializer(Type type, object value, HttpContent content)
511511
private object CreateDefaultSerializer(Type type, bool throwOnError)
512512
{
513513
Contract.Assert(type != null, "type cannot be null.");
514+
515+
#if NETSTANDARD1_3 // XsdDataContractExporter is not supported in netstandard1.3
516+
if (!UseXmlSerializer)
517+
{
518+
if (throwOnError)
519+
{
520+
throw new PlatformNotSupportedException(Error.Format(
521+
Properties.Resources.XmlMediaTypeFormatter_DCS_NotSupported,
522+
nameof(UseXmlSerializer)));
523+
}
524+
else
525+
{
526+
return null;
527+
}
528+
}
529+
#endif
530+
514531
Exception exception = null;
515532
object serializer = null;
516533

@@ -522,13 +539,12 @@ private object CreateDefaultSerializer(Type type, bool throwOnError)
522539
}
523540
else
524541
{
525-
#if !NETSTANDARD1_3 // XsdDataContractExporter is not supported in netstandard1.3
526-
// REVIEW: Is there something comparable in WinRT?
542+
#if !NETSTANDARD1_3 // Unreachable when targeting netstandard1.3.
527543
// Verify that type is a valid data contract by forcing the serializer to try to create a data contract
528544
FormattingUtilities.XsdDataContractExporter.GetRootElementName(type);
529-
#endif
530545

531546
serializer = CreateDataContractSerializer(type);
547+
#endif
532548
}
533549
}
534550
catch (Exception caught)

Diff for: src/System.Net.Http.Formatting/Properties/Resources.Designer.cs

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/System.Net.Http.Formatting/Properties/Resources.resx

+6
Original file line numberDiff line numberDiff line change
@@ -357,4 +357,10 @@
357357
<data name="ObjectDisposed_StreamClosed" xml:space="preserve">
358358
<value>Cannot access a closed stream.</value>
359359
</data>
360+
<data name="JsonMediaTypeFormatter_DCS_NotSupported" xml:space="preserve">
361+
<value>Unable to validate types on this platform when {0} is 'true'. Please reset {0} or move to a supported platform, one where the 'netstandard2.0' assembly is usable.</value>
362+
</data>
363+
<data name="XmlMediaTypeFormatter_DCS_NotSupported" xml:space="preserve">
364+
<value>Unable to validate types on this platform when {0} is 'false'. Please set {0} or move to a supported platform, one where the 'netstandard2.0' assembly is usable.</value>
365+
</data>
360366
</root>

0 commit comments

Comments
 (0)