IRestGateway upgrade to .net 6 ss 6 in multi-targeted code-bases

I’m upgrading 2 existing projects using ServiceStack to .net 6 and ss 6 and some changes (deprecation of HttpWebRequest) are affecting the classes implementing IRestGateway.

The first project (before upgrade):

    protected virtual void InitRequest(HttpWebRequest req, string method)
    {
        if (method == HttpMethods.Post || method == HttpMethods.Put || method == HttpMethods.Patch)
        {
            req.ContentType = "application/json";
        }
    }

Used by these 2 methods:

    protected virtual string Send(string relativeUrl, string method, string body)
    {
        try
        {
            var url = _baseUrl.CombineWith(relativeUrl);
            
            var response = url.SendStringToUrl(method: method, requestBody: body,
                requestFilter: req => { InitRequest(req, method); });

            return response;
        }
        catch (WebException ex)
        {
            ...
        }
    }

    protected virtual async Task<string> SendAsync(string relativeUrl, string method, string body,
        CancellationToken token = default)
    {
        try
        {
            var url = _baseUrl.CombineWith(relativeUrl);
            
            var response = await url.SendStringToUrlAsync(method: 
                method,
                requestBody: body,
                requestFilter: req => { InitRequest(req, method); }, token: token);

            return response;
        }
        catch (Exception ex)
        {
            ...
        }
    }

I’ve reformated the InitRequest like so:

    protected virtual void InitRequest(HttpRequestMessage req, string method)
    {
        if (method == HttpMethods.Post || method == HttpMethods.Put || method == HttpMethods.Patch)
        {
            req.Content!.Headers.ContentType = new MediaTypeHeaderValue(MimeTypes.Json);
        }
    }

For the second project:

    protected virtual void InitRequest(HttpWebRequest req, string method)
    {
        req.Accept = MimeTypes.Json;
    }

    protected virtual string Send(string relativeUrl, string method, string body)
    {
        try
        {
            var url = BaseUrl.CombineWith(relativeUrl);
            
            url = url.AddQueryParam("api_token", apiKey);
            
            var response = url.SendStringToUrl(method: method, requestBody: body,
                contentType: MimeTypes.Json, accept: MimeTypes.Json,
                requestFilter: req => { InitRequest(req, method); });

            return response;
        }
        catch (WebException ex)
        {
            HandlePipedriveException(ex);

            throw;
        }
    }

I’ve reformated the InitRequest like so:

    protected virtual void InitRequest(HttpRequestMessage req, string method)
    {
        req.Headers.Add(HttpHeaders.Accept, MimeTypes.Json);
    }

Are there any special considerations when upgrading like this?

Also, I’ve read in the documentation (https://docs.servicestack.net/http-utils#uses-httpclient-in-net-6) that there is a way to maintain compatibility with older versions of .net I’m not sure if it’s possible in the above examples. Is this possible and if so is there an example somewhere?

Source compatibility isn’t possible when referencing the deprecated HttpWebRequest class anywhere.

You can achieve compatibility when using the .With() extension method to configure the request, e.g:

protected async Task<string> SendAsync(string relativeUrl, string method, 
    string body, CancellationToken token = default)
{
    try
    {
        var url = _baseUrl.CombineWith(relativeUrl);
    
        var response = await url.SendStringToUrlAsync(method: 
            method,
            requestBody: body,
            requestFilter: req => {
                if (HttpUtils.HasRequestBody(method))
                    req.With(c => c.ContentType = MimeTypes.Json);
            }, token: token);

        return response;
    }
    catch (Exception ex)
    {
        //...
    }
}

Otherwise anywhere that references HttpWebRequest would need to have #if conditional compilation with dual implementations for WebRequest and HttpClient.

1 Like