JsonHttpClient vs JsonServiceClient

I had a number of integration test passing using JsonServiceClient and swapped the client to the JsonHttpClient and a couple failed.

The message coming back was “Specified method is not supported.”

Here’s the tests that failed (failed on the Post):

    IServiceClient GetClient()
    {
        return new JsonHttpClient(ListeningOn);
    }

    [TestMethod]
    public void GetDeviceScan_Test()
    {
        var client = GetClient();
        client.Post(new DeviceScanRequest { DeviceId = 0});

        Thread.Sleep(1000);
        var status = client.Get<DeviceScanStatusResponse>(new DeviceScanStatus() { DeviceId = 0});
        Assert.IsTrue(status.Enable);
        Assert.IsTrue(status.Status.Length > 5);
    }

My DTO’s

[Route("/bacnet/devicescan/{deviceId}",HttpMethods.Post)]
public class DeviceScanRequest : IHasVersion
{
    public int DeviceId { get; set; }
    public int Version { get; set; }
}

public class DeviceScanResponse : IHasResponseStatus
{
    public ResponseStatus ResponseStatus { get; set; }
}

What fixed it was I included the IReturn in the DTO. (Also worked if I used client.Post<DeviceScanResponse>)

[Route("/bacnet/devicescan/{deviceId}",HttpMethods.Post)]
public class DeviceScanRequest : IHasVersion, IReturn<DeviceScanResponse>
{
    public int DeviceId { get; set; }
    public int Version { get; set; }
}

I thought the IReturn types were optional on DTO’s, but looks like it isn’t on the new JsonHttpClient.

The Service Clients needs to know what response type to deserialize it into, if you’re not specifying with the IReturn<T> marker than you must specify it on the call-site, e.g:

client.Post<DeviceScanResponse>(new DeviceScanRequest { DeviceId = 0});

If you don’t you’re not calling a IServiceClient API, you’re calling this extension method which returns a .NET WebRequest that the HttpClient doesn’t support.

That makes sense. The “drop in” replacement verbiage in the wiki through me for a loop. Thanks.

It’s only a drop-in replacement when you stick to the IServiceClient interfaces. This is a concrete convenience extension method only meant for .NET WebRequest clients which is historically maintained for backwards-compatibility before we had multiple implementations since no other HTTP Client implementation can implement it.

I’ll deprecate them as it’s not obvious from the call-site it’s returning a HttpWebResponse that needs to be disposed:

using (var webRes = client.Post(new DeviceScanRequest { DeviceId = 0})) {}

In which it’s better to call it with an explicit Response Type so it’s obvious this returns a HttpWebResponse and needs to be disposed, e.g:

using (client.Post<HttpWebResponse>(new DeviceScanRequest { DeviceId = 0})) {}

To mitigate future issues all .NET WebRequest extension methods that return an implicit HttpWebResponse have now deprecated in this commit in favor of the correct usage above.