XML and Serialization Run-Time Breaking Changes

 
Short Description MarshalByRef should be removed from System.Uri signature
Affected APIs System.Uri Severity Low Compat Switch Available No

 


Description System.Uri mistakenly derived from MarshalByRefObj in V1 and V1.1. This has been the cause of significant customer pushback based on security issues associated with the fact that this type is supposed to be immutable and performance issues both in terms of URI construction time and run-time behavior.

 


User Scenario Scenario(s): User code that is remoting a URI instance by reference.

 


Work Around No workaround for URI construction time. This particular issue has a broad impact because System.Uri is the required way in LAPI to manipulate/parse a URI. The security issue and the run-time behavior can be mitigated by using a string instead of a URI. These two issues are more of a rare case but are still a concern because of the security risk.
 

 

 
Short Description Bug fix for invalid URI construction logic when working with a URI scheme unknown to System.Uri.
Affected APIs Behavioral change to System.Uri Severity Low Compat Switch Available No

 


Description In Version 1.1 the URI "foo:c:\bar" is converted at URI construction time to "foo://c:\bar" because Version 1.1 treats it like a file:// URI. This is incorrect because it prevents schemes that don't use the // from being supported by System.Uri if they have content such as "c:\bar" on the right hand side of the scheme. The behavior change for 2.0 is that no transformation is performed on URI's with unrecognized schemes.

 


User Scenario Construction of a System.Uri instance will no longer insert "//" in cases where the scheme is unknown and the scheme specific part of the URI contains "c:\".

 


Work Around Use string and do your own validation of the URI.
 

 

 
Short Description If a callback function of an asyn delegate throws an exception, the callback will be invoked twice.
Affected APIs All async delegate callbacks throwing exceptions Severity Low Compat Switch Available No

 


Description The problem occurs since the invokation code assumes the exception is thrown by the actual invokation (not the callback). We handle the exception and invoke the callback again to signal the end of the async invokation. The fix is to ignore exceptions thrown from async callbacks.

 


User Scenario If a callback function of an asyn delegate throws an exception, the callback will be invoked twice.

 


Work Around The workaround is for async callbacks to catch all exceptions.
 

 

 
Short Description If a MBR object (which already has an identity) is cloned, the identity is cloned as well, which means any future remote calls to the cloned object get dispatched to the original object
Affected APIs All types that inherit from MBR Severity Low Compat Switch Available No

 


Description The fix is quite easy. MBR needs to implement MemberwiseClone, null the identity and return the cloned object. When the cloned object is being marshalled out, it will be assigned a new identity

 


User Scenario This will only affect users who clone MBR objects and then marshal them out of remoting boundary

 


Work Around The only workaround is for the user to implement is own cloning mechanism (by cloning individual members)
 

 

 
Short Description Invalid nntp and news URI's should not be considered valid by System.Uri.
Affected APIs System.Uri class Severity Low Compat Switch Available No

 


Description nntp:comp.info.com is invalid because the correct syntax is nntp://comp.info.com news://a/b/c is invalid, the correct syntax is news:123455 Both invalid URI's are accepted by version 1.1. In version 2.0, we want to throw a UriFormatException for these URI's so that applications do not attempt to use them.

 


User Scenario Applications that are creating System.Uri instances with invalid news or nttp URI's today will get a UriFormatException in version 2.0. Note that if they are using the invalid URI for anything other than display purposes they will get an error today as well, but just not at URI instance construction time.

 


Work Around Validate the URI directly before passing it to System.Uri. This is unacceptable.
 

 

 
Short Description When creating a WebPermission with Regex people usually go with a simple regex like this: new Regex("https://myhost.com/.*") When user wants to Deny on above created permission, there are many ways to by-pass that user requirement by using a URI string with userinfo and/or expilict port, so the regex won't match. To improve WebPermission story with Deny we want to canonicalize the user URI string by roundtriping it through System.Uri class and also we want to strip userinfo part before calling Regex.Match() . As the result some WebPermission form like using the following Regex will stop working new Regex("https://myhost.com:80/.*"). This is because we strip default port as part of URI string canonicalization so Regex parser will not find it anymore hence won't match
Affected APIs System.Net.WebPermission Severity Low Compat Switch Available No

 


Description We think that the breaking change is not that harmull because all our components already do URI string canonicalization, hence if a poilcy regex was specified with explicit default port, it should not work even today if using Framework classes.

 


User Scenario The only affected user scenario is when a user reused a WebPermission clas to provide security for his own created component. Means that user component and not framework will call WebPermission.Demand based on the user input string.

 


Work Around Affected Users can adjust regex creation routine as to not include userinfo and explicit defautl port into URI regex pattern. If a user did use WebPermission class with input strings that are NOT valid uris, then such scenarios will continue working because we cannot create Uri type form input string so cannot apply URI canonicalization algorithm.
 

 

 
Short Description Supporting Nullable
Affected APIs Generated code Severity Low Compat Switch Available No

 


Description Version 1.1 app runs fine Customer upgrades to version 2.0 Customer regenarates proxy and re-compiles app run-time errors can occur with misuse of Nullable

 


User Scenario Re-generation of proxy after upgrade to version 2.0 without modifying client code

 


Work Around Change code to use new update proxy correctly.
 

 

 
Short Description Uri.LocalPath returns escaped string for HTTP in version 1.1 but unescapes the string in version 2.0.
Affected APIs Uri.LocalPath Severity Low Compat Switch Available No

 


Description This is related to the Uri.LocalPath property;

 


User Scenario When accessing Uri.LocalPath property; The change does have chances to break compiled version 1.1 applications when run on the version 2.0 runtime.

 


Work Around A broken application most likely needs to remove code that is put around LocalPath property usage. Alternatively it may use AbsoluteUri property to get escaped path output.
 

 

 
Short Description HTTP:acme.org now throws a parsing exception.
Affected APIs Relative URI ctor Severity Low Compat Switch Available No

 


Description HTTP:acme.org now throws a parsing exception. The URI is invalid and we cannot autocorrect it anymore as did in V1.1 because of adopted concept of a relative URI, The above syntax conflicts with relative URI syntax.

 


User Scenario Parsing a URI object out of the input string and then accessing URI properties. The changes do have chances to break compiled version 1.1 applications when run on the version 2.0 runtime.

 


Work Around A broken application will need to do pre-parsing and auto-correct the above URI before passing in the System.Uri ctor.
 

 

 
Short Description MarshalByRef removed from System.Uri signature
Affected APIs System.Uri Severity Low Compat Switch Available No

 


Description System.Uri mistakenly derived from MarshalByRefObj in V1 and V1.1. This has been the cause of significant customer pushback based on security issues associated with the fact that this type is supposed to be immutable and performance issues both in terms of URI construction time and run-time behavior.

 


User Scenario User code that is remoting a URI instance by reference.

 


Work Around No workaround for URI construction time. This particular issue has a broad impact because System.Uri is the required way in LAPI to manipulate/parse a URI. The security issue and the run-time behavior can be mitigated by using a string instead of a URI. These two issues are more of a rare case but are still a concern because of the security risk.
 

 

 
Short Description We throw when generating WSDL if the service has duplicate [WebServiceBinding(Name=...)]
Affected APIs System.Web.Services.Protocols.WebServiceBindingAttribute Severity Low Compat Switch Available No

 


Description Previously, we used to allow multiple bindings with the same name on a service. We just took the first one we got through reflection which is non-deterministic. We have fixed this behavior so that we now throw when there are multiple bindings with the same name. If a Web service has more than one [WebServiceBinding] with the same name, an exception is thrown whereas before the first one was used.

 


User Scenario There are no scenarios disabled due to this change. This was a bug that resulted in non-deterministic behavior. If a customer is affected by this change they have a bug in their code.

 


Work Around Change the binding names to make them unique.
 

 

 
Short Description Breaking Change - [WSS - PD7 - P2] System.Net.WebClient.UploadValues() method adds
Affected APIs empty Severity Low Compat Switch Available No

 


Description The System.Net.WebClient.UploadValues() method adds

 


User Scenario empty

 


Work Around Some of our RPC have a parameter whose value we ignore, so that parameter can be placed last in the form data set so that the
 

 

 
Short Description ASP.NET Web Service requests always send the AcceptEncoding: gzip HTTP header on v2.0
Affected APIs ASP.NET Web Service proxy types: SoapHttpClientProtocol. Severity High Compat Switch Available No

 


Description In .NET 2.0 the .NET Framework added support in ASP.NET Web Services for decompression, based on HTTP decompression support added on the HttpWebRequest type. The .NET Framework currently by default always send the AcceptEncoding: gzip header with each request, which tells the server that the client will accept GZIP compressed data. The client will also automatically decompress the data. This is a breaking change from v1.1, because v1.1 applications may have implemented their own decompression logic that will now decompress the data twice. The correct behavior is to have the user opt in to using automatic decompression.

 


User Scenario A user wishes to receive compressed data from an ASP.NET Web Service.

 


Work Around The user can derive from the Web Service proxy type and disable automatic decompression on the underlying HttpWebRequest. There is also an EnableDecompression property on the proxy type that the user should be able to just set to false, but unfortunately setting this property to false is currently broken.
 

 

 
Short Description Whenever an HttpWebResponse gets a 404, 500, or other error from the server, we automatically read a portion of the response content into memory and attach it to a WebException.
Affected APIs System.Net.HttpWebRequest Severity Medium Compat Switch Available No

 


Description Whenever an HttpWebResponse gets a 404, 500, or other error from the server, we automatically read a portion of the response content into memory and attach it to a WebException. This can be problematic either for the case that the caller doesn't care about the response (perf) or that the caller does (incomplete response). We have added a MaximumErrorResponseLength to Httpwebrequest and in the configuration settings. If set, HTTP errors would not cause a WebException. Instead, the request would complete normally.

 


User Scenario User creates a HttpWebRequest and gets an error response. The response is read into a WebException. This can be problematic either for the case that the caller doesn't care about the response (perf) or that the caller does (incomplete response).

 


Work Around None
 

 

 
Short Description GlobalProxySelection.Select behaves differently from v1.1 when an empty system.net tag is present in machine.config.
Affected APIs GlobalProxySelection.Select Severity Medium Compat Switch Available No

 


Description In v1.1, if the user specified an empty System.Net element in machine.config, GlobalProxySelection.Select would return an empty web proxy instance, indicating that no proxy would be used. In v2.0, the new default is that the system proxy settings will be used.

 


User Scenario User reuses an v1.1 configuration file after migrating to v2.0.

 


Work Around Modify the machine.config file to disable the default proxy.
 

 

 
Short Description The proxy by pass list now has escaped(regex) significant characters.
Affected APIs system.net.webproxy Severity Medium Compat Switch Available No

 


Description When the framework reads the bypass list in from the registry, it turns it into a regular expression, which requires escaping characters that have meaning within regular-expression syntax. This escaping process was not done in v1.1 and thus caused the proxy by pass feature to not function correctly. This has been fixed in v2.0. However, if someone figured out that this problem existed, they may have changed their IE settings to be regular expression format, which would have broken IE but made v1.1 work. Alternatively, the user could rely on parsing the un-escaped bypass addresses in some way and thus this could break their parsing logic.

 


User Scenario Users relying on the incorrect processing in v1.1 who have changed their IE bypass list to be regular expression syntax could be broken. Users who rely on processing the un-escaped strings in the list of proxy bypass addresses.

 


Work Around Change IE settings to not be in regular expression format. No work around for user scenario (where users rely on processing the un-escaped strings).
 

 

 
Short Description NetworkStream now honours the FileAccess parameter.
Affected APIs System.Net.NetworkStream Severity Medium Compat Switch Available No

 


Description If a network stream is opened with a certain type of access (read/write) we do not ensure that only that type of access is made on the stream in v1.1, this has been changed in v2.0.

 


User Scenario Users that set a FileAccess on a network stream and rely on accessing the stream using a method that is not permitted by the FileAccess type will be broken as the FileAccess is now honored.

 


Work Around none
 

 

 
Short Description The wrong version of assembly may be loaded when deserializing in Simple mode.
Affected APIs BinaryFormatter.Deserialize, SoapFormatter.Deserialize, all Remoting APIs causing deserialization to happen Severity Medium Compat Switch Available No

 


Description run-time serialization may run in one of two modes: Full or Simple. v1.1 behavior: Full—write out full assembly info on serialization, use Assembly.Load() on deserialization Simple—write out partial assembly info on serialization, use Assembly.LoadWithPartialName() on deserialization v2.0 behavior: Full—write out full assembly info on serialization, use Assembly.Load() on deserialization Simple—write out full assembly info on serialization, use Assembly.LoadWithPartialName() on deserialization Change - Version 1 of an object is serialized in Simple mode - The serialized stream is deserialized on a machine that has both version 1 and 2 of that type, in Simple mode. On v1.1, v2 of the type would be loaded; on v2.0, it would be v1.

 


User Scenario - Version 1 of an object is serialized in Simple mode - The serialized stream is deserialized on a machine that has both version 1 and 2 of that type, in Simple mode. On v1.1, v2 of the type would be loaded; on v2.0, it would be v1.

 


Work Around - Use a TypeBinder - Add appropriate version policy in app config
 

 

 
Short Description XML Serialization generates AssemblyResolveEvents in V2.0 but not in V1.1
Affected APIs XmlSerializer constructor Severity Medium Compat Switch Available No

 


Description In V2.0, we've introduced a feature caled SGEN (pre-generated serializers). The XML Serializer will look for a pre-generated serialization assembly, and if it fails to find it then new serialization code will be generated from scratch. In version 1.1, we always generated new serialization code and never looked for a pre-generated assembly. Thus, in version 1.1, we never generated AssemblyResolveEvents during the XML Serialization process. We do in V2.0

 


User Scenario A user is relying on the fact that the Framework will not generate AssemblyResolveEvents other than the ones the user expects

 


Work Around 1) Pre-generate serialization assemblies for the assembly in question so that the assembly load will succeed. OR: 2) Unhook the AssemblyResolveEvent handler while doing XML serialization
 

 

 
Short Description The default for serializing DateTimes is RoundTrip which is breaking
Affected APIs All serialize/deserialize APIs on the XmlSerializer Severity Low Compat Switch Available No

 


Description We now roundtrip DateTime Kind info. That is, when we write, we write using the Z (UTC) format for the "UTC" kind and without a timezone for "Unspecified" kind. When we read, we create a DateTime of the appropriate kind depending on the format in XML. This is different from version 1.1 behavior. The version 2.0 behavior is correct, but there could have been customers who (a) worked around the incorrect version 1.1 behavior in a way that was contrary to our guidance, which was to always use local times or to convert times to strings before serialization, or (b) interoperated with 3rd-party clients/services that serialized time in the UTC format or in a timezone-less format. These consumers will be broken (they will see some incorrect time calculations). A version 2.0 known issue has been submtited for this. TEXT: Date and Time calculations in Web Services or XML Serialization scenarios may be incorrect after migrating to .NET Framework 2.0 .NET Framework 2.0 changes the way dates and times are written to and read from XML. This change mostly affects the following scenarios: - Using times with an unspecified time zone or times in the UTC time zone - Interoperability scenarios with 3rd-party software which writes out time values to XML without specifying a time zone or specifying the UTC time zone The changes may cause certain date and time calculations and comparisons to become incorrect. In these cases, it may be necessary to revert to the earlier date/time behavior. This can be accomplished by applying the following configuration change:

 


User Scenario Upgrading from V1.1 to V2.0, using ASMX web services, and one of the following: - Using times with an unspecified time zone or times in the UTC time zone - Interoperability scenarios with 3rd-party software which writes out time values to XML without specifying a time zone or specifying the UTC time zone

 


Work Around Compat switch: