Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonHandler not removable as described in documentation #105

Open
Taldrit78 opened this issue Nov 16, 2021 · 3 comments
Open

JsonHandler not removable as described in documentation #105

Taldrit78 opened this issue Nov 16, 2021 · 3 comments

Comments

@Taldrit78
Copy link

Taldrit78 commented Nov 16, 2021

I tried to unset the DefaultJsonHandler like described by this link:
https://restclient.dalsoft.io/docs/default-pipeline/
But this:
Config config = new Config()
{
UseDefaultHandlers = false
}.UseFormUrlEncodedHandler().UseMultipartFormDataHandler();
creates a config with all three handlers:
{DalSoft.RestClient.Handlers.DefaultJsonHandler},
{DalSoft.RestClient.Handlers.FormUrlEncodedHandler} and
{DalSoft.RestClient.Handlers.MultipartFormDataHandler}

But it is written, that UseDefaultHandlers = false would remove the DefaultJsonHandler from the list, so it should be done. Right? ;)

p.s.: I tried also
Config config = new Config().UseFormUrlEncodedHandler().UseMultipartFormDataHandler().UseNoDefaultHandlers();
But to the same result.

@DalSoft
Copy link
Owner

DalSoft commented Nov 16, 2021

Hi,

Your correct it doesn't remove it from the list - I'll get that changed in the docs.

But it does skip the functionality
https://github.com/DalSoft/DalSoft.RestClient/blob/master/DalSoft.RestClient/Handlers/DefaultJsonHandler.cs

  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
  {
          request.SetConfig(_config);
          
          if (_config.UseDefaultHandlers)
          {
              request.Content = GetContent(request);
              
              if (!request.Headers.Accept.Any())
                  request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(Config.JsonMediaType));

              request.ExpectJsonResponse(true);
          }
          
          return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
  }

So it won't add the json headers or try to process the response as json.

Are you getting a specific issue that I can help with?

@Taldrit78
Copy link
Author

Yes. I tried to read an "octet-stream" and the default Json Handler destroys the streams inside the octet-stream. I built another handler.
This is my "OctetStreamHandler":

internal class OctetStreamHandler : DelegatingHandler
{
    internal byte[] ContentBytes { get; set; } = null;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (IsOctetStreamContentType(request))
        {
            HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
            if (response.Content != null)
            {
                ContentBytes = await response.Content.ReadAsByteArrayAsync();
            }

            return response;
        }

        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); //next in the pipeline
    }

    private static bool IsOctetStreamContentType(HttpRequestMessage request)
    {
        return request.Headers.Accept.Contains(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
    }
}

And I use it like this:
_restClient = new RestClient(serviceUrl, new Headers(new { UserAgent = userAgent }), new Config().UseFormUrlEncodedHandler().UseMultipartFormDataHandler().UseHandler(mOctetStreamHandler));

and later:

      dynamic result = await _restClient
                          .Headers(new { Authorization = InstanceToken })
                          .Headers(new { Accept = "application/octet-stream" })
                          .Get($"documents/{documentId}");

        HttpResponseMessage hrm = result;
        if (hrm.StatusCode != HttpStatusCode.OK)
            throw new RestException(string.Format(RestClientStrings.Error_RestException, $"GET documents/{documentId}", (int)hrm.StatusCode), hrm.StatusCode);

        byte[] fileData = mOctetStreamHandler.ContentBytes;
        mOctetStreamHandler.ContentBytes = null;

        return fileData;

I found no other way to get a correct octet-stream from the rest client. And I found nothing in the documentation. I first tried to take the hrm.Content and cast that to a byte array, but it was already disposed (from the JsonHandler I think), so I couldn't get the array and casting the result directly wasn't helpful. Maybe you could give an example in the documentation for idiots to come (like me :D).

@DalSoft
Copy link
Owner

DalSoft commented Nov 27, 2021

Hi,

I'll take a further look. Your correct the response stream is disposed of, this is to stop any memory leaks, but I see it's a hindrance in your case. I feel like I need to add a helper to get the response in the handler like I do with the request. Which is exactly the workaround you have had to do.

I also feel getting a stream is something I should support so I'll add both features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants