Skip to content

Commit 08edbad

Browse files
authored
fix: Restore HttpClientRequestAdapter constructor compatibility between .NET 5+ and .NET Standard/Framework
2 parents d970e8e + f972713 commit 08edbad

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
33
<Suppressions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4-
<Suppression>
5-
<DiagnosticId>CP0002</DiagnosticId>
6-
<Target>M:Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.#ctor(Microsoft.Kiota.Abstractions.Authentication.IAuthenticationProvider,Microsoft.Kiota.Abstractions.Serialization.IParseNodeFactory,Microsoft.Kiota.Abstractions.Serialization.ISerializationWriterFactory,System.Net.Http.HttpClient,Microsoft.Kiota.Http.HttpClientLibrary.ObservabilityOptions,System.Version)</Target>
7-
<Left>lib/netstandard2.1/Microsoft.Kiota.Http.HttpClientLibrary.dll</Left>
8-
<Right>lib/net5.0/Microsoft.Kiota.Http.HttpClientLibrary.dll</Right>
9-
</Suppression>
104
</Suppressions>

src/http/httpClient/HttpClientRequestAdapter.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.Collections.Generic;
7+
using System.ComponentModel;
78
using System.Diagnostics;
89
#if NET5_0_OR_GREATER
910
using System.Diagnostics.CodeAnalysis;
@@ -40,15 +41,13 @@ public class HttpClientRequestAdapter : IRequestAdapter, IDisposable
4041
private readonly bool createdClient;
4142
private readonly ObservabilityOptions obsOptions;
4243
private readonly ActivitySource activitySource;
43-
#if !NET5_0_OR_GREATER
44-
private readonly Version httpVersion;
45-
#endif
44+
private readonly Version? httpVersion;
4645
#if NETSTANDARD2_1_OR_GREATER
4746
private static readonly Version defaultHttpVersion = HttpVersion.Version20;
4847
#elif NETSTANDARD2_0 || NETFRAMEWORK
4948
private static readonly Version defaultHttpVersion = HttpVersion.Version11;
5049
#endif
51-
#if NET5_0_OR_GREATER
50+
5251
/// <summary>
5352
/// Initializes a new instance of the <see cref="HttpClientRequestAdapter"/> class.
5453
/// <param name="authenticationProvider">The authentication provider.</param>
@@ -57,8 +56,15 @@ public class HttpClientRequestAdapter : IRequestAdapter, IDisposable
5756
/// <param name="httpClient">The native HTTP client.</param>
5857
/// <param name="observabilityOptions">The observability options.</param>
5958
/// </summary>
60-
public HttpClientRequestAdapter(IAuthenticationProvider authenticationProvider, IParseNodeFactory? parseNodeFactory = null, ISerializationWriterFactory? serializationWriterFactory = null, HttpClient? httpClient = null, ObservabilityOptions? observabilityOptions = null)
61-
#else
59+
[EditorBrowsable(EditorBrowsableState.Never)]
60+
public HttpClientRequestAdapter(IAuthenticationProvider authenticationProvider, IParseNodeFactory? parseNodeFactory, ISerializationWriterFactory? serializationWriterFactory, HttpClient? httpClient, ObservabilityOptions? observabilityOptions)
61+
: this(authenticationProvider, parseNodeFactory, serializationWriterFactory, httpClient, observabilityOptions, httpVersion: null)
62+
{
63+
// Constructor without HttpVersion for runtime backwards compatibility. Adding a new
64+
// optional parameter provides *compile-time* backwards compatibility but throws a
65+
// MissingMethodException at runtime.
66+
}
67+
6268
/// <summary>
6369
/// Initializes a new instance of the <see cref="HttpClientRequestAdapter"/> class.
6470
/// <param name="authenticationProvider">The authentication provider.</param>
@@ -69,7 +75,6 @@ public HttpClientRequestAdapter(IAuthenticationProvider authenticationProvider,
6975
/// <param name="httpVersion">The HTTP version.</param>
7076
/// </summary>
7177
public HttpClientRequestAdapter(IAuthenticationProvider authenticationProvider, IParseNodeFactory? parseNodeFactory = null, ISerializationWriterFactory? serializationWriterFactory = null, HttpClient? httpClient = null, ObservabilityOptions? observabilityOptions = null, Version? httpVersion = null)
72-
#endif
7378
{
7479
authProvider = authenticationProvider ?? throw new ArgumentNullException(nameof(authenticationProvider));
7580
createdClient = httpClient == null;
@@ -79,7 +84,9 @@ public HttpClientRequestAdapter(IAuthenticationProvider authenticationProvider,
7984
sWriterFactory = serializationWriterFactory ?? SerializationWriterFactoryRegistry.DefaultInstance;
8085
obsOptions = observabilityOptions ?? new ObservabilityOptions();
8186
activitySource = ActivitySourceRegistry.DefaultInstance.GetOrCreateActivitySource(obsOptions.TracerInstrumentationName);
82-
#if !NET5_0_OR_GREATER
87+
#if NET5_0_OR_GREATER
88+
this.httpVersion = httpVersion;
89+
#else
8390
this.httpVersion = httpVersion ?? defaultHttpVersion;
8491
#endif
8592
}
@@ -620,7 +627,7 @@ private HttpRequestMessage GetRequestMessageFromRequestInformation(RequestInform
620627
Method = new HttpMethod(requestInfo.HttpMethod.ToString().ToUpperInvariant()),
621628
RequestUri = requestUri,
622629
#if NET5_0_OR_GREATER
623-
Version = client.DefaultRequestVersion,
630+
Version = httpVersion ?? client.DefaultRequestVersion,
624631
VersionPolicy = client.DefaultVersionPolicy
625632
#else
626633
Version = httpVersion

tests/http/httpClient/RequestAdapterTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,44 @@ public async Task HttpVersionDefaultShouldBeHttp11()
11491149
Assert.Equal(HttpVersion.Version11, requestMessage.Version);
11501150
}
11511151
#endif
1152+
1153+
[Fact]
1154+
public void ConstructorOverloadsWorkCorrectlyForCompatibility()
1155+
{
1156+
// This test verifies the fix for the MissingMethodException issue
1157+
// when code compiled against netstandard2.1 runs on newer frameworks
1158+
1159+
// Arrange - Test the constructor without Version parameter (matches NET5+ signature)
1160+
var authProvider = new AnonymousAuthenticationProvider();
1161+
var mockParseNodeFactory = new Mock<IParseNodeFactory>();
1162+
var mockSerializationWriterFactory = new Mock<ISerializationWriterFactory>();
1163+
using var httpClient = new HttpClient();
1164+
var observabilityOptions = new ObservabilityOptions();
1165+
1166+
// Act & Assert - Both constructor overloads should work
1167+
using var adapter1 = (HttpClientRequestAdapter?)Activator.CreateInstance(
1168+
typeof(HttpClientRequestAdapter),
1169+
authProvider,
1170+
mockParseNodeFactory.Object,
1171+
mockSerializationWriterFactory.Object,
1172+
httpClient,
1173+
observabilityOptions);
1174+
1175+
using var adapter2 = (HttpClientRequestAdapter?)Activator.CreateInstance(
1176+
typeof(HttpClientRequestAdapter),
1177+
authProvider,
1178+
mockParseNodeFactory.Object,
1179+
mockSerializationWriterFactory.Object,
1180+
httpClient,
1181+
observabilityOptions,
1182+
new Version(1, 1));
1183+
1184+
// Verify both adapters are created successfully
1185+
Assert.NotNull(adapter1);
1186+
Assert.NotNull(adapter2);
1187+
Assert.NotNull(adapter1.SerializationWriterFactory);
1188+
Assert.NotNull(adapter2.SerializationWriterFactory);
1189+
}
11521190
}
11531191

11541192
public enum TestEnum

0 commit comments

Comments
 (0)