方法不允许 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()
时,变量 response
说 Method 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);
}
参考:
因为您正在使用获取请求,从 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();
.....
}
我同时在 运行 两个项目中,在我的 mvc 项目中调用 PaymentServiceAsync()
方法时,当它到达行 response.EnsureSuccessStatusCode()
时,变量 response
说 Method 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);
}
参考:
因为您正在使用获取请求,从 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();
.....
}