Skip to content

3.0.0 preview 2 Razor Components: "InputFormatters" is empty when making Web API POST #7438

@EricPalmer22

Description

@EricPalmer22

With a new "Razor Components" project using .NET Core 3.0.0 preview 2, I am trying to make an Http call to a controller on the server to save game data to a SQLite database. But, any POST call that I to do to a controller method with a [FromBody] parameter attribute, I get the following error: `System.InvalidOperationException: 'Microsoft.AspNetCore.Mvc.MvcOptions.InputFormatters' must not be empty. At least one 'Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter' is required to bind from the body.

I see that a JsonInputFormatter should be included by default when I register the MVC services, but for some reason there are no InputFormatters in the context.

To test this, I created a brand new Razor Components project under .NET Core 3.0.0 templates.
I registered MVC and HttpClient services on my Server.Startup class:

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            
            if (!services.Any(x => x.ServiceType == typeof(HttpClient)))
            {
                // Setup HttpClient for server side in a client side compatible fashion
                services.AddScoped<HttpClient>(s =>
                {
                    // Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
                    var uriHelper = s.GetRequiredService<IUriHelper>();
                    return new HttpClient
                    {
                        BaseAddress = new Uri(uriHelper.GetBaseUri())
                    };
                });
            }
            services.AddRazorComponents<App.Startup>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            };
            app.UseMvc();
            app.UseStaticFiles();
            app.UseRazorComponents<App.Startup>();
        }
    }

I created a CounterController class on my Server with a simple test method:

public class CounterController : Controller
    {
        [HttpPost]
        [Route("/api/Counter/Test")]
        public void Test([FromBody]string value)
        {
            var test = value;
        }
    }

And updated the Counter.cshtml file to inject the Httpclient and make a call to our controller:

@page "/counter"
@using System.Net.Http;
@inject HttpClient Client

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
        var stringReq = new StringBody() { value = "test" };
        Client.PostJsonAsync("/api/Counter/Test", stringReq).Wait();
    }

    public class StringBody
    {
        public string value { get; set; }
    }
}

I can use [FromQuery] parameters and everything works fine, but I just cannot get sending JSON to work because of this error. I verified that the request is being made with the correct content type and the body is valid JSON. I'm also learning Blazor as I go here and don't have a solid background with MVC/Razor pages, so it's very possible I'm just doing something wrong. My goal is to have a web game that can persist game data to a database on the server. I figured I would have my EF dbcontext datalayer and my web api controller living on the server to accept client calls for saving/updating game state.

Full stacktrace:

System.InvalidOperationException: 'Microsoft.AspNetCore.Mvc.MvcOptions.InputFormatters' must not be empty. At least one 'Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter' is required to bind from the body.
   at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider.GetBinder(ModelBinderProviderContext context)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderFactory.CreateBinderCoreUncached(DefaultModelBinderProviderContext providerContext, Object token)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderFactory.CreateBinder(ModelBinderFactoryContext context)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.GetParameterBindingInfo(IModelBinderFactory modelBinderFactory, IModelMetadataProvider modelMetadataProvider, ControllerActionDescriptor actionDescriptor, MvcOptions mvcOptions)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.CreateBinderDelegate(ParameterBinder parameterBinder, IModelBinderFactory modelBinderFactory, IModelMetadataProvider modelMetadataProvider, ControllerActionDescriptor actionDescriptor, MvcOptions mvcOptions)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
   at Microsoft.AspNetCore.Mvc.Routing.MvcEndpointDataSource.<>c__DisplayClass22_0.<CreateEndpoint>b__0(HttpContext context)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions