Эта конечная точка API предназначена для получения сериализованного объекта JSON и передачи его базовому механизму отчетов.
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
namespace Server.Controllers
{
[ApiController]
[Route("[controller]")]
public class ReportingController : ControllerBase
{
[HttpPost("generate")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Consumes("application/json")]
public async Task<ActionResult> Generate([FromBody] string reportModel)
{
try
{
dynamic data = JObject.Parse(reportModel);
string templateName = data.TemplateName;
return Ok(templateName);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
}
Я борюсь с его использованием, как передать строковый объект JSON?
Например:
{ "TemplateName": "myTemplate" }
Покрыл это в модульном тесте. Уже узнал, что начинать и заканчивать нужно двойной кавычкой (").
В приведенном ниже коде метод JsonStringToStringContent
необходимо настроить так, чтобы двойные кавычки внутри JSON также имели правильное экранирование.
В настоящее время контроллер даже не задействован, ASP.NET Core уже заранее возвращает код состояния 400.
Я также не уверен насчет типа носителя application/json
.
Большое спасибо за вашу помощь!
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using System.Text;
namespace TestProject
{
public class UnitTest1(TestServerFixture fixture) : IClassFixture<TestServerFixture>
{
[Fact]
public async Task Test1()
{
var json = "{\"TemplateName\":\"myTemplate\"}";
var jsonStringContent = JsonStringToStringContent(json);
using var content = new StringContent(jsonStringContent, Encoding.UTF8, "application/json");
var server = fixture.Server;
var request = server
.CreateRequest("/Reporting/generate")
.And(req => req.Content = content);
var response = await request.PostAsync();
response.EnsureSuccessStatusCode();
}
private string JsonStringToStringContent(string json)
{
// current result: "{"TemplateName":"myTemplate"}"
// expected result: ?
return $"\"{json}\"";
}
}
public sealed class TestServerFixture : WebApplicationFactory<Server.Program>
{
private HttpClient client;
public HttpClient Client
{
get
{
client ??= Server.CreateClient();
return client;
}
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
FileInfo fileInfo = new(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"));
var configurationBuilder = new ConfigurationBuilder();
var configuration = configurationBuilder.Build();
builder
.UseConfiguration(configuration)
.ConfigureAppConfiguration(builder =>
{
builder.AddJsonFile(fileInfo.FullName);
});
}
}
}
к сожалению, ничего из этого не работает application/json
text/plain
application/octet-stream
```
Раньше у меня был тест на отправку строки json в контроллер. Не могли бы вы помочь проверить эти два случая? Первый показывает, как отправить строку json в контроллер , второй показывает, как преобразовать строку json в JObject. Продолжайте использовать [FromBody] string reportModel
и будет data["TemplateName"]
?
Нет необходимости использовать строковую кавычку ("), я бы предложил получить тело в виде object
, а затем преобразовать его:
public async Task<ActionResult> Generate([FromBody] object reportModel)
{
try
{
dynamic data = JObject.Parse(reportModel.ToString());
string templateName = data.TemplateName;
return Ok(templateName);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
Также, если вы знаете, что тело всегда имеет формат JSON
, вы можете напрямую сопоставить его с JObject
:
public async Task<ActionResult> Generate([FromBody] JObject reportModel)
{
try
{
dynamic data = reportModel;
string templateName = data.TemplateName;
return Ok(templateName);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
В тесте вы устанавливаете contentType как
application/json
, вы пробовали использовать текст?