'Unable to Extend HttpContent Class

There seems to be something I am missing when trying to extend HttpContent so can anyone let me know if they have been successful in the past at doing this?

The documentation for HttpContent seems to show that its possible to extend and make your own HttpContent Extension, however oddly enough it will never call SerializeToStreamAsync() which is odd considering it calls TryComputeLength().


Given this example extension

public sealed class HttpContentExtension : HttpContent
{

    public ChunkedStringContent()
    {
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    {
       // Not called When HttpClient.SendAsync() is called.. which it should according to the source code
    }


    protected override bool TryComputeLength(out long length)
    {
        length = -1L;
        return false;
    }
}

Oddly enough as well if I extend String Content TryComputeLength() is not called

public sealed class HttpContentExtension : StringContent
{

    public ChunkedStringContent()
    {
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    {
       // Not called When HttpClient.SendAsync() is called.. which it should according to the source code
    }

  
    protected override bool TryComputeLength(out long length)
    {
        // Not Called when extends StringContent
    }
}

If you dig a little into the source they have this one comment that made me curious, they actually have a internal virtual method

// TODO #9071: Expose this publicly.  Until it's public, only sealed or internal types should override it, and then change
// their SerializeToStreamAsync implementation to delegate to this one.  They need to be sealed as otherwise an external
// type could derive from it and override SerializeToStreamAsync(stream, context) further, at which point when
// HttpClient calls SerializeToStreamAsync(stream, context, cancellationToken), their custom override will be skipped.
internal virtual Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
            SerializeToStreamAsync(stream, context);

What is really interesting is that if you look at internal extensions of HttpContent you see this override, here is ByteArrayContent for example but all pretty much look like this.

internal override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
    // Only skip the original protected virtual SerializeToStreamAsync if this
    // isn't a derived type that may have overridden the behavior.
    GetType() == typeof(ByteArrayContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) :
    base.SerializeToStreamAsync(stream, context, cancellationToken);

In conclusion this leads me to believe that it actually is simply not possible to extend this and the only thing barring them from internalizing this is because its publicly referenced on HttpClient

Does anyone have any examples of this working they would be willing to share, or have places they may have seen me misstep?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source