Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

How does binding source parameter inference work? #8116

Closed
Robar666 opened this issue Jul 19, 2018 · 2 comments
Closed

How does binding source parameter inference work? #8116

Robar666 opened this issue Jul 19, 2018 · 2 comments
Assignees
Labels

Comments

@Robar666
Copy link

Is this a Bug or Feature request?:

Question, I've also created a SO question.

Steps to reproduce (preferably a link to a GitHub repo with a repro project):

  • Create ApiController (see code below)
  • Make an Ajax request (I used Postman)
// AccountController.cs

[Route("/account"), ApiController]
public class AccountController : ControllerBase {
    [HttpPost("backendLogin"), AllowAnonymous]
    public async Task<ActionResult<LoginResponse>> BackendLogin(LoginRequest lr) {
        await Task.CompletedTask.ConfigureAwait(false); // do some business logic
        return Ok(new LoginResponse {UserId = "123"});
    }

    // Models

    public class LoginRequest {
        public string Email { get; set; }
        public string Password { get; set; }
    }

    public class LoginResponse {
        public string UserId { get; set; }
    }
}

// Startup.cs

public void ConfigureServices(IServiceCollection services) {
    services.AddMvcCore()
                    .AddJsonFormatters(settings => {
                        settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
                        settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
                        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    })
                    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.Configure<ApiBehaviorOptions>(options => {
        // options.SuppressConsumesConstraintForFormFileParameters = true;
        // options.SuppressInferBindingSourcesForParameters = true;
        // options.SuppressModelStateInvalidFilter = true;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    }
    app.UseMvc();
}

Description of the problem:

It seems that the binding source parameter inference isn't working as expected (at least for me). I assumed based on the docs, that complex types (e.g. my LoginRequest) are inferred as [FromBody].

If I change the options.SuppressInferBindingSourcesForParameters in ConfigureServices to true, it seems to work. This is strange, since this setting should disable the binding inference or have I misconceived something? Is this a bug in ASP.NET core or am I missing something?

Btw. it also works if I ommit the ApiController attribute, but I guess this is not the real solution to this problem

PS: I would also suggest to update the documentation for ApiBehaviorOptions.SuppressInferBindingSourcesForParameters. Maybe it is just me, but it was not clear on first sight what this property does based on the documentation. The second paragraph starts with When enabled, ..., I first thought it means when this property is set to true, but I think it really means when the "Binding inference" is enabled.

Version of Microsoft.AspNetCore.Mvc or Microsoft.AspNetCore.App or Microsoft.AspNetCore.All: 2.1.1

@pranavkm
Copy link
Contributor

ApiController is designed for REST-client specific scenarios and isn't designed towards browser based (form-urlencoded) requests. FromBody assumes JSON \ XML request bodies and it'll attempt to serialize it, which is not what you want with form url encoded content. Using a vanilla (non-ApiController) would be the way to go here.

The second paragraph starts with When enabled, ..., I first thought it means when this property is set to true, but I think it really means when the "Binding inference" is enabled.

It does mean when the property is set to true \ when the feature is enabled. We'd be happy to accept PRs to update it if you think it could be worded better.

@Robar666
Copy link
Author

Thank you for the explanation.
I will go for the vanilla controller for now and maybe later change the client calls for JSON bodies.

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

No branches or pull requests

3 participants