#c# #casting #asp.net-core-webapi
#c# #Кастинг #asp.net-core-webapi
Вопрос:
Приведение public object Parameters { get; set; }
к ожидаемой структуре объекта request.Parameters as ParametersForA
возвращает нуль.
Я попытался сериализовать request.Parameters
и десериализовать его в ParametersForA
тип с использованием Newtonsoft.Json
, что отлично работает, но это все еще не удовлетворяет меня, поскольку я хотел бы понять предыдущий сбой.
Это код, который я тестирую:
C#
using Microsoft.AspNetCore.Mvc;
namespace ObjectCasting.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromBody]Request request)
{
if (request.OperationCode == "A")
{
var obj = request.Parameters as ParametersForA; // <<< null problem
return Ok(obj);
}
return BadRequest();
}
}
public class Request
{
public string OperationCode { get; set; }
public object Parameters { get; set; }
}
public class ParametersForA
{
public int Age { get; set; }
public string Name { get; set; }
}
}
и это тело запроса HTTP POST json:
json
{
"OperationCode": "A",
"Parameters": {
"Age": 25,
"Name": "Caroline"
}
}
Я хочу понять, почему приведение здесь не работает.
Для указанного, уникального OperationCode
в будущем я буду ожидать разные назначения приведения и Parameters
структуру запроса json соответственно.
Комментарии:
1. Почему бы вам не определить свойство Parameters как ParametersForA . Почему он определен как object?
2.
request.Parameters
кажется, aJToken
. Какой тип указывает отладчик? Та часть, которую вы только что вырезали из скриншота.3. Для указанного, уникального
OperationCode
в будущем я буду ожидать различные назначения приведения и параметры структуры запроса json соответственно.4. @Patrick Hofman
request.Parameters.GetType
в первой строке POST methot указываетNewtonsoft.Json.Linq.JObject
тип.5. Итак, как вы ожидаете, что это будет
ParametersForA
?
Ответ №1:
Проблема заключается в типе Parameters
свойства. Это object
и фактический тип JObject
, когда получен запрос.
Вы должны использовать ToObject<SomeType>()
метод для приведения JObject
к нужному типу:
var obj = (request.Parameters as JObject).ToObject<ParametersForA>();
Для приведения к разным типам на основе OperationCode
:
switch(request.OperationCode)
{
case "1":
// cast to one type and process
case "2":
//cast to another type and process
}
Комментарии:
1. Да, я не ожидаю, что буду привязан к указанному типу, как вы предлагаете @Roman Doskoch
2. это то, что я искал! Только одна вещь, чтобы сделать код компилируемым
var obj = ((JObject)request.Parameters).ToObject<ParametersForA>();
.
Ответ №2:
Приведение следует определенным правилам, для ссылочных типов должна быть иерархия, чтобы можно было преобразовать один тип в другой.
В вашем случае вы не можете его привести, потому что ваш Parameter
фактически является a JToken
, который не может быть приведен непосредственно ParameterA
.
Согласно документации:
Неявные преобразования: специальный синтаксис не требуется, поскольку преобразование является типобезопасным и данные не будут потеряны. Примеры включают преобразования из меньших в большие целочисленные типы и преобразования из производных классов в базовые классы.
Комментарии:
1. @PatrickHofman Плакат просто хочет знать, почему приведение (преобразование) не работает. Это то, что объясняется здесь .
2. Тогда, возможно, он должен, и как только он это сделает, он сможет выяснить, как заставить это работать (или обойти это).
3. @peeyush singh, ваш пост также был ценным, поскольку он напомнил мне основное правило, которое я забыл в пылу битвы.
4. @PatrickHofman возможно, для вас это не имеет значения. Вы можете отметить мой ответ закрытым, если считаете, что он не дает никакой ценности, вместо того, чтобы протестовать и спрашивать, почему люди видят в нем ценность.
5. @peeyushsingh, сейчас нет значения. Но если вы добавите к нему небольшое объяснение (чтобы оно выглядело как ответ) — будет значение. Т.е. «Вы не можете привести его, потому что ваш параметр на самом деле является JToken, который нельзя напрямую привести к ParameterA. Вот документы: »