Skip to content

[Bug]: Methods require explicit [Body] attribute for improved code-gen, implicit is insufficient #2190

Description

@wokket

Describe the bug 🐞

Follow on from #2183. Methods without explicit attributes fail to use the optimised code-gen path.

Step to reproduce

I have a very simple interface method which I've been using for years, note no explicit [Body] attribute:

[Headers("Content-Type: application/json")]
public interface IMyApi
{
	[Post("/v1/somewhere")]
	Task<AuthenticationResponse> AuthMePlease(AuthenticationRequest request, CancellationToken token);
}

This generates the reflection based pipeline:

public async global::System.Threading.Tasks.Task<global::Leapfrog.Common.AuthenticationResponse> AuthMePlease(global::Leapfrog.Common.AuthenticationRequest @request, global::System.Threading.CancellationToken @token)
            {
                var refitArguments = new object[] { @request, @token };
                var refitRequestBuilder = _requestBuilder ?? throw new global::System.InvalidOperationException("This generated Refit method requires a request builder.");
                var refitFunc = refitRequestBuilder.BuildRestResultFuncForMethod("AuthMePlease", ______typeParameters );

                return await ((global::System.Threading.Tasks.Task<global::Leapfrog.Common.AuthenticationResponse>)refitFunc(this.Client, refitArguments)).ConfigureAwait(false);
            }

Update the signature to explicitly include the [Body] (Task<AuthenticationResponse> AuthMePlease([Body]AuthenticationRequest request, CancellationToken token);) and we get a nice reflection-free impl:

public global::System.Threading.Tasks.Task<global::Leapfrog.Common.AuthenticationResponse> AuthMePlease(global::Leapfrog.Common.AuthenticationRequest @request, global::System.Threading.CancellationToken @token)
            {
                var refitSettings = _settings;
                var refitRequest = new global::System.Net.Http.HttpRequestMessage(global::System.Net.Http.HttpMethod.Post, global::Refit.GeneratedRequestRunner.BuildRelativeUri(this.Client, "/v1/somewhere", refitSettings.UrlResolution));
                #if NET6_0_OR_GREATER
                refitRequest.Version = refitSettings.Version;
                refitRequest.VersionPolicy = refitSettings.VersionPolicy;
                #endif
                refitRequest.Content = global::Refit.GeneratedRequestRunner.CreateBodyContent<global::Leapfrog.Common.AuthenticationRequest>(
                    refitSettings,
                    @request,
                    global::Refit.BodySerializationMethod.Default,
                    !refitSettings.Buffered);
                global::Refit.GeneratedRequestRunner.SetHeader(refitRequest, "Content-Type", "application/json");
                global::Refit.GeneratedRequestRunner.AddConfiguredRequestOptions(refitRequest, refitSettings, typeof(global::Leapfrog.WVI.SrsWebApi.IMyApi));
                return global::Refit.GeneratedRequestRunner.SendAsync<global::Leapfrog.Common.AuthenticationResponse, global::Leapfrog.Common.AuthenticationResponse>(
                    this.Client,
                    refitRequest,
                    refitSettings,
                    false,
                    true,
                    refitSettings.Buffered,
                    @token);
            }

Reproduction repository

https://github.com/reactiveui/refit

Expected behavior

I was hoping to not have to add explicit attributes to all my API functions, and that they'd 'just work' as currently written.

Screenshots 🖼️

No response

IDE

Rider Windows

Operating system

Windows 11

Version

No response

Device

No response

Refit Version

13

Additional information ℹ️

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions