Search code examples
c#asp.net-coreasp.net-core-mvcasp.net-core-webapi

Method not allowed 405 POST ASP.NET CORE 5.0 WEB API


I am running two projects at the same time, on my mvc project when I call my PaymentServiceAsync() method, when it hits the line response.EnsureSuccessStatusCode() it the variable response says Method not allowed (405) I can't seem to figure out why it is doing so if I have it set correctly.

Here is my PaymentServiceAsync() method:

        public async Task<string> PaymentServiceAsync()
        {
            var response = await _httpClient.GetAsync("api/paymentservices/payment");

            response.EnsureSuccessStatusCode();

            var result = await response.Content.ReadAsStringAsync();

            return result;
        }

Now in my asp.net core web api project this is my controller that it calls:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Nest;
using Microsoft.Extensions.Configuration;
using System.Data.SqlClient;
using PaymentService.API.Models;
using Microsoft.Extensions.Logging;

namespace PaymentService.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PaymentServicesController : ControllerBase
    {
        private String _connectionString;
        private IElasticClient _elasticClient = new ElasticClient();
        private readonly ILogger<PaymentServicesController> _logger;

        public PaymentServicesController(IConfiguration configuration, ILogger<PaymentServicesController> logger)
        {
            _connectionString = configuration.GetConnectionString("Default");
            _logger = logger;
        }


        // POST api/<PaymentServices>
        [HttpPost]
        [Route("payment")]
        public async Task<int> Post([FromBody] string value)
        {
            _logger.LogInformation("Payment method involked!");
            using (SqlConnection connection = new SqlConnection(_connectionString))
            {
                Console.WriteLine("\nOpening connection...");

                SqlCommand command = new SqlCommand("insert into applog(ElkLog_id, CorrelationId, DateCreated, MessageTemplate, Message) values(@elk_id, @cid, @dt, @mt, @m)", connection);

                string indexName = "customer-simulation-es-app-logs*";
                var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200"));
                connectionSettings.DefaultIndex(indexName);
                connectionSettings.EnableDebugMode();
                _elasticClient = new ElasticClient(connectionSettings);


                // this will tell us how much hits/results there is based on the following criteria 
                var countResponse = _elasticClient.Count<EsSource>(c => c
                     .Query(q => q
                         .Bool(b => b
                             .Should(
                                   m => m
                                   .Match(ma => ma
                                       .Field(fa => fa.level)
                                       .Query("Error")),
                                   m => m
                                   .Match(ma => ma
                                       .Field(fa => fa.level)
                                       .Query("Information")))
                             .Filter(f => f.DateRange(dr => dr
                             .Field("@timestamp")
                                 .GreaterThanOrEquals("2021-06-18T16:34:45.701-05:00")
                                 .LessThanOrEquals("2021-07-18T16:34:45.701-05:00")))
                             .MinimumShouldMatch(1)))).Count;


                Console.WriteLine($"\nDocuments in index: {countResponse}");

                Console.WriteLine($"Open new pit");
                var openPit = await _elasticClient.OpenPointInTimeAsync(indexName, d => d.KeepAlive("1m"));
                var pit = openPit.Id;

                Console.WriteLine($"Read all docs from index ..");
                // we will start reading docs from the beginning
                var searchAfter = DateTimeOffset.MinValue;


                var elkLogId = "";
                var correlationId = "";
                var dateCreated = default(DateTimeOffset);
                var messageTemplate = "";
                var message = "";
                int numrows = 0;

                try
                {
                    connection.Open();

                    Console.WriteLine("\nConnection successful!");

                    while (true)
                    {
                        ........

                       

                        numrows = await command.ExecuteNonQueryAsync();

                        

                        command.Parameters.Clear();

                        

                    }

                    Console.WriteLine("\nAll logs have been recorded to the database successfully!");

                    connection.Close();
                    Console.WriteLine("\nConnection closed....");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    Console.WriteLine($"Close pit");
                    var closePit = await _elasticClient.ClosePointInTimeAsync(d => d.Id(pit));
                }

                return numrows;
            }
        }

       
    }
}

appsettings.json

{
  "ConnectionStrings": {
    "Default": "Data Source=.\\SQLExpress;Database=ElasticSearchService;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Solution

  • Since you are using get request remove [post] from api

    [Route("~api/paymentservices/payment/{value}")]
     public async Task<int> Post(string value)
    

    and fix the request

    //--init http client with base url
    
    var baseUri= @"http:...";
        
        using HttpClient client = new HttpClient { BaseAddress = new Uri(baseUri) };
    client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    .....
    string value="test"; //replace with your value
    
    var response = await client.GetAsync("api/paymentservices/payment/"+value);
    
    if (response.IsSuccessStatusCode)
    {
    .....
    }
    

    or you can try post method as well, in this case try to use action

    [Route("~api/paymentservices/payment")]
     public async Task<int> Post(string value)
    

    and code

    var baseUri= @"http:....";
        
        using HttpClient client = new HttpClient { BaseAddress = new Uri(baseUri) };
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        string value="test"; //replace with your value
    
        Dictionary<string, string> packet = new Dictionary<string, string>();
        packet.Add("value", value);
        
    
        var content = new StringContent(JsonConvert.SerializeObject(packet), UTF8Encoding.UTF8, "application/json");
    
        
        var response = await client.PostAsync("api/paymentservices/payment", content);
        
        if (response.IsSuccessStatusCode)
        {
            var stringData = await response.Content.ReadAsStringAsync();
            .....
        }