HttpClient failing

2019-09-07 05:32发布

问题:

When I run my app on the emulator for iOS it works fine. When I run it on a device the first call to HttpClient fails. My class containing the HttpClient calls is in a PCL. It looks like an instance of this bug.

However, the documented workarounds of adding the following to your iOS project app.config does not work for me (the system.net.http addition);

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    ......
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="2.0.5.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

EDIT:

With this in my app.config, the following method successfully retrieves the data from the server, but fails to read it. The bottom line containing ReadAsAsync(..) fails and throws an exception. The exception is 'null' and nothing is output to the terminal either. It works fine on the emulator, but not the device.

    public async Task<List<ExternalLoginViewModel>> GetExternalLoginsAsync()
    {
        using (var client = GetNewHttpClient(false))
        {
            client.DefaultRequestHeaders.Remove("Authorization");

            var response = await client.GetAsync("api/account/externalLogins?returnUrl=/&generateState=true");

            response.EnsureSuccessStatusCode();

             return await response.Content.ReadAsAsync<List<ExternalLoginViewModel>>();
        }
    }

回答1:

Your assembly binding redirection is wrong. Your iOS project should have an app.config file with this content:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="2.0.5.0" />
        </dependentAssembly>

    </assemblyBinding>
  </runtime>
</configuration>

The reason for the redirect is that the Microsoft.Net.HttpClient packages contains the System.Net.HttpClient namespace but that already exists on iOS and Android (with slightly different features even). At runtime it will resolve to the wrong assembly and not use the (Xamarin-)native iOS one.

You can find a demo project for iOS, Android and WP8 based on HttpClient in a PCL at my Github repo.



回答2:

This was resolved by uninstalling the "Microsoft HTTP Client Libraries" nuget package from both the PCL and the iOS project. Then reinstalling on both. The iOS project has references now to 'System.Net.Http.Extensions' and to 'System.Net.Http.Primatives' but does not contain one to 'System.Net.Http'. The following binding redirect is used in the app.config file in the iOS project as well;

<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />