方法不允许 405 POST ASP.NET CORE 5.0 WEB API

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

我同时在 运行 两个项目中,在我的 mvc 项目中调用 PaymentServiceAsync() 方法时,当它到达行 response.EnsureSuccessStatusCode() 时,变量 responseMethod not allowed (405) 如果我设置正确,我似乎无法弄清楚为什么会这样。

这是我的 PaymentServiceAsync() 方法:

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

            response.EnsureSuccessStatusCode();

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

            return result;
        }

现在在我的 asp.net 核心网络 api 项目中,这是我调用的控制器:

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

您尝试在代码中尝试“获取”动词操作,而不是“Post”方法。

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

根据您的要求,这些是与付款相关的代码,如果您真的考虑安全性,请使用 POST 方法而不是 GET。

这里我们创建了"IServiceProvider"(ASP.NET核心提供了一个内置的服务容器,IServiceProvider。)实例"_serviceProvider"。 =35=] 通过构造函数依赖注入。这是如何在 ASP.NET 核心应用程序中调用 POST 方法的示例之一。

在 ASP.Net 核心应用程序中使用 IHttpClientFactory 而不是 HttpClient,在启用 DI 的应用程序中使用 IHttpClientFactory 避免:

  • 池化 HttpMessageHandler 实例导致资源耗尽问题。
  • 通过定期循环 HttpMessageHandler 实例来解决陈旧的 DNS 问题 间隔。

试试这个:

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

参考:

  1. IHttpClientFactory Docs

因为您正在使用获取请求,从 api

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

并修复请求

//--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)
{
.....
}

或者你也可以尝试post方法,在这种情况下尝试使用action

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

和代码

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