简体   繁体   中英

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": "*"
}

Instead of "Post" method you are trying to attempt "Get" verbs action in the code.

var response = await _httpClient.GetAsync("api/paymentservices/payment");

As per your requirement these are payment related code and if you are really thinking about security then use POST method instead of GET.

Here we have created "IServiceProvider" (ASP.NET Core provides a built-in service container, IServiceProvider.) instance "_serviceProvider" through constructor dependency injection. This is one of the example of how to call POST method in ASP.NET Core app.

Instead of HttpClient use IHttpClientFactory in ASP.Net Core App, Using IHttpClientFactory in a DI-enabled app avoids:

  • Resource exhaustion problems by pooling HttpMessageHandler instances.
  • Stale DNS problems by cycling HttpMessageHandler instances at regular intervals.

Try this:

using (var scope = _serviceProvider.CreateScope())
        {
            var clientFactory = (IHttpClientFactory)scope.ServiceProvider
             .GetService(typeof(IHttpClientFactory));
            var client = clientFactory.CreateClient();
            //PaymentObject
            string jsonData = JsonConvert.SerializeObject(paymentObject);
            var httpContent = new StringContent(jsonData, Encoding.UTF8, "application/json");
            client.BaseAddress = new Uri("http://localhost:3978/");
            var response = await client.PostAsync("api/paymentservices/payment", httpContent);
       }

Reference:

  1. IHttpClientFactory Docs

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();
        .....
    }

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