#c# #.net-core #asp.net-mvc-5 #asp.net-core-webapi #webapi
#c# #.net-ядро #asp.net-mvc-5 #asp.net-core-webapi #webapi
Вопрос:
Я использую .Net Core API 2.1, у меня есть это в моем контроллере:
[Route("Invoke")]
[HttpPost]
public IActionResult Invoke(Student studentDetails)
{
DetailsResponse objResponse;
if(ModelState.IsValid)
{
objResponse= GetDetails(studentDetails);
}
return OK(objResponse);
}
Я пытаюсь вызвать метод действия Invoke из Postman с телом запроса как
{"student": {"name":"John Doe", "age":18, "country":"United States of America"}}
Этот объект всегда имеет значение null в контроллере.
Если я попытаюсь вызвать метод действия из Postman с телом запроса как
{"name":"John Doe", "age":18, "country":"United States of America"}
Здесь объект имеет данные и работает нормально.
Мой вопрос заключается в том, чтобы вызвать действие с корневым узлом, как показано ниже
{"student": {"name":"John Doe", "age":18, "country":"United States of America"}}
Есть ли какая-нибудь возможность добиться этого?
Комментарии:
1. Привет @Rabia Basri, если мой ответ поможет вам решить вашу проблему, не могли бы вы принять его в качестве ответа? См.: Как принять в качестве ответа . Спасибо.
Ответ №1:
в зависимости от вашей структуры вы можете использовать
public IActionResult Invoke([FromBody]Student studentDetails)
Что произойдет, так это то, что привязка модели попытается сопоставить json с указанным вами классом.
Ответ №2:
Дело в том, что ваша вторая попытка полностью имитирует ваш класс Student, поэтому он сопоставляется с Student .
{"name":"John Doe", "age":18, "country":"United States of America"}
Если вы хотите получить объект с полем «student», заполненным Student json, вы можете создать другой класс StudentWrapper или InvokeParameters или что-то в этом роде с полем Student .
Но вам лучше не делать этого, если вам это действительно не нужно. Обычно это не обязательно и должно быть опущено. Это полезно только в том случае, если вы получаете несколько моделей, таких как Student, в вашем действии API.
Ответ №3:
{«имя»: «Джон Доу», «возраст»: 18, «страна»: «Соединенные Штаты Америки»}
Это приемлемый json для model Student
в вашем JsonInputFormatter по умолчанию.То, что вы хотите передать, является неприемлемым json Student
, вам необходимо настроить JsonInputFormatter в соответствии с вашими требованиями:
public class CustomJsonInputFormatter : JsonInputFormatter
{
public CustomJsonInputFormatter(ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool<char> charPool, ObjectPoolProvider objectPoolProvider, MvcOptions options, MvcJsonOptions jsonOptions) : base(logger, serializerSettings, charPool, objectPoolProvider, options, jsonOptions)
{
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var request = context.HttpContext.Request;
using (var reader = new StreamReader(request.Body))
{
string content = await reader.ReadToEndAsync();
JObject jo = JObject.Parse(content);
Student student = jo.SelectToken("student", false).ToObject<Student>();
return await InputFormatterResult.SuccessAsync(student);
}
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
var serviceProvider = services.BuildServiceProvider();
var jsonInputLogger = serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<CustomJsonInputFormatter>();
var jsonOptions = serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value;
var charPool = serviceProvider.GetRequiredService<ArrayPool<char>>();
var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
var customJsonInputFormatter = new CustomJsonInputFormatter(
jsonInputLogger,
jsonOptions.SerializerSettings,
charPool,
objectPoolProvider,
options,
jsonOptions
);
options.InputFormatters.Insert(0, customJsonInputFormatter);
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
Другой способ:
{«студент»: {«имя»: «Джон Доу», «возраст»: 18, «страна»: «Соединенные Штаты Америки»}}
Этот json приемлем для следующей модели:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
public class Test
{
public Student student { get; set; }
}
Экшен:
[HttpPost]
public IActionResult Invoke(Test studentDetails)
{
//...
}
Комментарии:
1. Спасибо вам. Я использовал ваш первый подход к созданию пользовательского средства форматирования ввода Json.