简体   繁体   中英

How do I use JavaScript to properly call a HttpPost method from .NET Core 3.1 avoiding the 400 error

Experimenting in .NET Core 3.1

I am clearly missing a KEY element of the HttpPost in Core. I would like to pass JSON to the controller and get what I need from the JSON in code behind. Running this always supplies 400 (Bad Request) never making it into the function so i am lead to believe it is a basic thing. I have also tried using the jQuery POST method $.post("/nodes", item, function () { alert("success");}) and that returns a 415 (Unsupported Media Type).

I have tried several action parameters frombody, fromheader, from request. FromBody seems like it should be the one. I have added the CORS based on other posts just to eliminate. The pure html file IS in the project if it matters it is not a cshtml. There are no client-side frameworks other than jQuery. I do not want framework specific answers (angular, moo, vue, react, etc.). It seems that if done correctly we should be able to do it at the most basic level. An answer in vanilla javascript or jQuery would get me on my way nicely.

fwiw: The GETs all work.

// Client side JavaScript. 
var item = {
    id: "9f14a706-e750-4b76-8ba5-78d890bbdf0d"
};

$.ajax({
    type: "POST",
    accepts: "application/json",
    url: '/nodes',
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function (jqXHR, textStatus, errorThrown) {
        console.error("Something went wrong!");
        console.error(textStatus);
        console.error(errorThrown);
    },
    success: function (result) {
        console.log('Testing');
    }
});


/// NodesController.cs 
namespace INM.Controllers
{
[Route("[controller]")]
[ApiController]

    public class NodesController : ControllerBase
    {
        [HttpPost]
        public void Post([FromBody] string value)
        {
             var foo = "bar";
        }

        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
            var foo = "bar";
        }
    }
}


    ///StartUp.cs
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        services.AddCors();
        services.AddControllers();
    }

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            DeveloperExceptionPageOptions developerExceptionPageOptions = new DeveloperExceptionPageOptions
            {
                SourceCodeLineCount = 10
            };

            app.UseCors(builder =>
            {
                builder.WithOrigins("http://localhost:61246/")
                       .AllowAnyMethod()
                       .AllowAnyHeader()
                       .AllowAnyOrigin();
                //.AllowCredentials()
            });


            app.UseDeveloperExceptionPage(developerExceptionPageOptions);
        }

        FileServerOptions fileServerOptions = new FileServerOptions();
        fileServerOptions.DefaultFilesOptions.DefaultFileNames.Clear();
        fileServerOptions.DefaultFilesOptions.DefaultFileNames.Add("INM.html");

        app.UseFileServer(fileServerOptions); // combines app.UseDefaultFiles(); & app.UseStaticFiles(); 

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        app.Run(async (context) => 
        {
            //throw new Exception("Some proc err");
            await context.Response.WriteAsync("Hello World from Startup.cs (Configure) ");
        });
    }

UPDATE For the lurkers: Changing the signature in the controller fixed my issues. I knew it was a basic oversight.

[HttpPost]
public object Post([FromBody] object value)
{
    var foo = "bar";
    return value;
}

Also, while writing I was mistaken about the dataType property in a $.ajax call. This refers to the return value vs the data payload sent in the request.

I hope this helps you too.

Problem here, is that your controller is expecting a string, while you are posting an object.

You should test with Postman first, use "9f14a706-e750-4b76-8ba5-78d890bbdf0d" as payload and Content-Type: application/json. If that works, try changing your js like this:

data: JSON.stringify("9f14a706-e750-4b76-8ba5-78d890bbdf0d")

Please write:

/// NodesController.cs 
namespace INM.Controllers
{


  [Route("[controller]")]
   [ApiController]

public class NodesController : ControllerBase
{
    [HttpPost]
    [Route("api/[Controller]/[action]")]
    public void Post([FromBody] string value)
    {
         var foo = "bar";
    }

    [HttpPut("{id}")]
    [Route("api/[Controller]/[action]/:id")]
    public void Put(int id, [FromBody] string value)
    {
        var foo = "bar";
    }
}
}

and in Startup.cs :

services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                   builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader());
        });

and in the Configure method in startup.cs :

  app.UseCors("CorsPolicy");

and add:

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

you are passing the object containing id attribute while on server-side you are receiving only string as a parameter from body so change your code to have one string value in the body like this see if it works for you

var item = "9f14a706-e750-4b76-8ba5-78d890bbdf0d";
$.ajax({
type: "POST",
accepts: "application/json",
url: '/nodes',
contentType: "application/json",
data: JSON.stringify(item),
error: function (jqXHR, textStatus, errorThrown) {
    console.error("Something went wrong!");
    console.error(textStatus);
    console.error(errorThrown);
},
success: function (result) {
    console.log('Testing');
}

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM