Home > Back-end >  bad request when trying to call POST function from controller class
bad request when trying to call POST function from controller class

Time:12-29

I have problems accessing a POST method from my controller class with Http.PostJsonAsync and always get back Bad request status error.However I have different controller classes with working examples where I do the exact same thing only with different data models and names, but the code is the same. I would be glad if someone can spot the error im doing.

I have the following function call:

private async Task AddAdditionalItem(string valueTest1, string valueDateTest1)
{
    article_list inputSQL = new article_list();
    inputSQL.articlename = valueTest1;
    inputSQL.date = valueDateTest1;

    var x = await Http.PostJsonAsync(baseUrl   "/api/article_list/create", inputSQL);
    Console.WriteLine(x.StatusCode);
}

The console output does return a bad request status code. However I cannot find whats wrong with my controller class:

[Route("api/[controller]")]
[ApiController]
public class article_list_Controller : ControllerBase
{
    private readonly SqlDbContext_test _dbContext;

    public article_list_Controller(SqlDbContext_test dbContext)
    {
      _dbContext = dbContext;
    }

    [HttpPost]
    [Route("Create")]
    public async Task<bool> Create([FromBody] article_list article)
    {
        Console.WriteLine("Create");
        
        if(ModelState.IsValid){

            _dbContext.Add(article);
            try
            {
                await _dbContext.SaveChangesAsync();
                return true;
            }
            catch (DbUpdateException)
            {
                return false;
            }
        }
    }
}

My database context class looks like this:

public class SqlDbContext_test : DbContext
{
    public SqlDbContext_test(DbContextOptions<SqlDbContext_test> options) : base(options)
}
public DbSet<article_list> article_list {get;set;}

protected override void OnModelCreating(ModelBuilder modelbuilder){
    modelBuilder.Entity<article_list>().HasNoKey();
}

And finally my model class:

public class article_list
{
    #nullable enable
    public string? articlename 
    { 
        get; 
        set; 
    }
    public string? date 
    { 
        get; 
        set; 
    }
}

EDIT: this is my customHttpClient Method implementation:

public async Task<HttpResponseMessage> PostJsonAsync<T>(string requestUri, T content)
{
    HttpClientHandler clientHandler = new HttpClientHandler();
    clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

    // Pass the handler to httpclient(from you are calling api)
    HttpClient httpClient = new HttpClient(clientHandler);
    string myContent = JsonConvert.SerializeObject(content);
    StringContent stringContent = new StringContent(myContent, Encoding.UTF8, "application/json");
    var response = await httpClient.PostAsync(requestUri, stringContent);
    httpClient.Dispose();
    return response;
}

CodePudding user response:

Update:2 With Existing Code:

Method:

public async Task<HttpResponseMessage> PostJsonAsync<T>(string requestUri, T content)
        {
            HttpClientHandler clientHandler = new HttpClientHandler();
            clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

            // Pass the handler to httpclient(from you are calling api)
            HttpClient httpClient = new HttpClient();
            string myContent = JsonConvert.SerializeObject(content);
            StringContent stringContent = new StringContent(myContent, Encoding.UTF8, "application/json");
            var response = await httpClient.PostAsync(requestUri, stringContent);
            Console.WriteLine(response.StatusCode);
            Console.WriteLine(await response.Content.ReadAsStringAsync());
            httpClient.Dispose();
            return response;
        }

How I Invoked Method:

            var requestURI = "http://localhost:5094/api/article_list/Create";
            article_list inputSQL = new article_list();
            inputSQL.articlename = "My First Value";
            inputSQL.date = "My Last Value";
            var callMethod = await PostJsonAsync(requestURI, inputSQL);

Final Output:

enter image description here

Note: Please check your did you invocked the method and passed the parameter. These are all of my investigations.

Update: I am calling AddAdditionalItem method as following:

public async Task<IActionResult> Index()
        {
            string param_1 = "First Parameter Value";
            string param_2 = "Second Parameter Value";

            var callAPI = AddAdditionalItem(param_1, param_2);
            return Ok(callAPI);
        }

I have problems accessing a POST method from my controller class with Http.PostJsonAsync and always get back Bad request status error.

Well, based on your shared code snippet I have tried to reproduce your issue. But at the begining I noticed this snippet Http.PostJsonAsync which am not sure, if you are using any 3rd party library. However, I tried to continue with your code and got following compilation error:

enter image description here

I think we should call the API endpoint using HttpClient if I am not mistaken.

Solution:

I have tried to call your article_list_Controller and Create Action and I have successfully got the 200 response along with value I have retured. Here is the demo how I implement that:

AddAdditionalItem Controller:

public async Task AddAdditionalItem(string valueTest1, string valueDateTest1)
        {
            using (var client = new HttpClient())
            {
                // Setting Base address.  
                client.BaseAddress = new Uri($"http://localhost:5094/");
                // Initialization.  
                HttpResponseMessage response = new HttpResponseMessage();

                //Bind Model property
                article_list inputSQL = new article_list();
                inputSQL.articlename = valueTest1;
                inputSQL.date = valueDateTest1;
                //Call Endpoint
                response = await client.PostAsJsonAsync($"api/article_list/Create", inputSQL);
                Console.WriteLine(response.StatusCode);
                Console.WriteLine(await response.Content.ReadAsStringAsync());
                // Verification  
                if (response.IsSuccessStatusCode)
                {
                    // Reading Response.  
                    var result = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(result);
                }


            }


        }

API Controller:

    [Route("api/[controller]")]
    [ApiController]
    public class article_listController : ControllerBase
    {
        [HttpPost]
        [Route("Create")]
        public async Task<bool> Create([FromBody] article_list article)
        {
            Console.WriteLine("Create");

            if (ModelState.IsValid)
            {
                return true;
            }
            return false;
        }
    }

Output:

enter image description here

Note: As per my findings, if you update your PostAsJsonAsync request with HttpClient it would return you expected response. For further details you can check our official document how we can invocked PostAsJsonAsync

CodePudding user response:

The issue was using multiple underscores as class names for my data model and parsing that as a URI which genereated a bad request. For some reason you can only use one underscore and not multiple. I changed my class names in my original code and fixed the problem that way. I only used one underscore in my code examples and thats why the error is not reproducable

  • Related