如何在 .Net Core 中使用请求对象调用一个端点
如何在 .Net Core 中使用请求对象调用一个端点
我在Api 1中有一个如下所示的端点:
[HttpPost] public ActionResult PostSchoolQuery([FromBody] SchoolQueryModel schoolQueryModel, [FromHeader] string authorization) { }
这里是请求模型类:
public class SchoolQueryModel { public ListSchoolIds { get; set; } public List DistrictIds { get; set; } }
当我尝试从Api 2调用PostSchoolQuery端点时,无论如何我都会收到null值:
public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel) { dynamic schoolDetails = null; var requestContent = new JsonSerializer.Serialize(getSchoolsModel); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey); var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", requestContent); if (responseTask.Result.IsSuccessStatusCode) { var readTask = responseTask.Result.Content.ReadAsAsync(); readTask.Wait(); schoolDetails = readTask.Result; } } }
请告诉我如何修复,谢谢。
如何在.Net Core中使用请求对象调用端点
在这个问题中,原因是作者在调用端点时遇到了问题,并提到了一些解决方法。下面是解决方法的整理:
1. 使用async/await
功能。不要直接使用.Result
,可以参考这里的重要信息和建议。
2. 不要为每个请求创建一个HttpClient
,可以参考这里的指南。
下面是一段示例代码:
using System.Text; using System.Text.Json; using Microsoft.AspNetCore.Mvc; namespace AspNetPlayground.Controllers; [ApiController] [Route("[controller]/[action]")] public class TestController : ControllerBase { private readonly HttpClient _httpClient; public TestController(IHttpClientFactory httpClientFactory) => _httpClient = httpClientFactory.CreateClient(); [HttpPost] public Task<bool> IsNotNull([FromBody] SchoolQueryModel? schoolQueryModel) => Task.FromResult(schoolQueryModel is not null); [HttpPost] public async Task<bool> Run() { var getSchoolsModel = new SchoolQueryModel {SchoolIds = new() {Guid.NewGuid()}, DistrictIds = new() {Guid.NewGuid()}}; using var requestContent = new StringContent(JsonSerializer.Serialize(getSchoolsModel), Encoding.UTF8, "application/json"); using var response = await _httpClient.PostAsync("https://localhost:7041/Test/IsNotNull", requestContent); return response.IsSuccessStatusCode && await response.Content.ReadFromJsonAsync<bool>(); } } public class SchoolQueryModel { public List<Guid?> SchoolIds { get; init; } = new(); public List<Guid?> DistrictIds { get; init; } = new(); }
如果遇到了无法解析服务的问题,需要在启动代码中调用AddHttpClient()
方法,该方法来自于Microsoft.Extensions.DependencyInjection
包。
希望这个解决方法对您有帮助。如果仍然存在问题,可能是其他问题,比如授权问题。
问题的出现原因是在调用一个 .Net Core 的端点时,请求对象的值为空。解决方法是使用 `PostAsJsonAsync` 方法来发送 POST 请求,并将请求对象作为参数传递。
下面是一个示例代码,演示了如何调用一个端点并传递请求对象:
public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel) { dynamic schoolDetails = null; using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey); var responseTask = client.PostAsJsonAsync("http://localhost:6200/api/post_school_query", getSchoolsModel); if (responseTask.Result.IsSuccessStatusCode) { var readTask = responseTask.Result.Content.ReadAsAsync(); readTask.Wait(); schoolDetails = readTask.Result; } } }
以上代码中,通过 `PostAsJsonAsync` 方法发送一个 POST 请求,并将请求对象 `getSchoolsModel` 作为参数传递。如果请求成功,将获取到的数据转换为 `JObject` 类型,并将其赋值给 `schoolDetails` 变量。
希望这个解决方法对你有帮助!
问题的原因是在调用.Net Core中的一个端点时,没有正确设置请求头和请求体。解决方法是首先设置请求头的Content-Type为"application/json",然后创建一个StringContent对象来存储序列化后的请求体,并将其作为第二个参数传递给PostAsync方法。
具体的解决方法如下:
首先,在从Api 2发起请求时,设置请求头的Content-Type为"application/json":
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
然后,需要从序列化后的请求体中创建一个StringContent对象,并将其作为第二个参数传递给PostAsync方法。可以按照以下方式进行操作:
var content = new StringContent(requestContent, Encoding.UTF8, "application/json"); var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", content);
因此,你的GetUserSchools方法应该如下所示:
public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel) { dynamic schoolDetails = null; var requestContent = new JsonSerializer.Serialize(getSchoolsModel); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey); var content = new StringContent(requestContent, Encoding.UTF8, "application/json"); var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", content); if (responseTask.Result.IsSuccessStatusCode) { var readTask = responseTask.Result.Content.ReadAsAsync<JObject>(); readTask.Wait(); schoolDetails = readTask.Result; } } }