DTO_FIELD(Int64, time);
};
class ResponseDto : public oatpp::data::mapping::type::Object
{
DTO_INIT(ResponseDto, Object)
DTO_FIELD(HeaderDto::ObjectWrapper, header);
};
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include <iostream>
#include OATPP_CODEGEN_BEGIN(DTO)
class MyBaseDto : public oatpp::data::mapping::type::Object {
DTO_INIT(MyBaseDto, Object)
DTO_FIELD(String, myBaseDtoField);
};
class HeaderDto : public MyBaseDto /* Should also extend a class here */ {
DTO_INIT(HeaderDto, MyBaseDto)
DTO_FIELD(Int64, time);
};
class ResponseDto : public oatpp::data::mapping::type::Object {
DTO_INIT(ResponseDto, Object)
DTO_FIELD(HeaderDto::ObjectWrapper, header) = HeaderDto::createShared(); // Don't forger to initialize object
};
#include OATPP_CODEGEN_END(DTO)
void run() {
auto dto = ResponseDto::createShared();
dto->header->time = 0;
dto->header->myBaseDtoField = "Hello base class";
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
auto json = objectMapper->writeToString(dto);
std::cout << json->c_str() << std::endl;
}
int main() {
oatpp::base::Environment::init();
run();
oatpp::base::Environment::destroy();
return 0;
}
Hello, i have a problem/question with your DTO component of oat++. I try to generate an packet with different types of objects but I can't assign inherited classes. I show you my problem with a little example
...
class Param : public oatpp::data::mapping::type::Object
{
DTO_INIT(Param , Object)
};
class RealParam : public Param
{
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object
{
DTO_INIT(Packet, Object)
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params)
= List<Param::ObjectWrapper>::createShared();
};
...
When I try to add an instance (ObjectWrapper) of type RealParam to the list of Packet, I only get an error message from the compiler that there is no known conversion from RealParam::ObjectWrapper to Param::ObjectWrapper. Is there a way to explicitly cast the object or am I still making a mistake somewhere?
Hello @DF-Dave ,
It is possible to cast ObjectWrapper
using oatpp::data::mapping::type::static_wrapper_cast
, and it will compile:
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
};
class RealParam : public Param {
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params) = List<Param::ObjectWrapper>::createShared();
};
...
auto packet = Packet::createShared();
auto realParam = RealParam::createShared();
realParam->magic = 10;
Param::ObjectWrapper param = oatpp::data::mapping::type::static_wrapper_cast<Param>(realParam);
packet->params->pushBack(param);
But the output will miss the magic
int32 number:
{
"params": [
{}
]
}
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params)
in the Param inside <> brackets is the actual model of the object that should be serialized. Serializer won't know about other fields present in the child.
Not sure if I understand correctly...
The point is that the template parameter in the list should define the exact type of the object that you want to serialize.
You can just do like this:
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
};
class RealParam : public Param {
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
DTO_FIELD(List<RealParam::ObjectWrapper>::ObjectWrapper, params) = List<RealParam::ObjectWrapper>::createShared();
};
Then, your serializer will serialize all the fields taking into account the base class inheritance.
template<class T>
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
DTO_FIELD(T, templateParam);
};
template<class T>
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
typedef List<typename Param<T>::ObjectWrapper> ListOfParams;
typedef typename ListOfParams::ObjectWrapper ListOfParams_ObjectWrapper;
DTO_FIELD(ListOfParams_ObjectWrapper, params) = ListOfParams::createShared();
};
...
auto packet = Packet<oatpp::String>::createShared();
auto param = Param<oatpp::String>::createShared();
param->templateParam = "Hello";
packet->params->pushBack(param);
{
"params": [
{
"templateParam": "Hello"
}
]
}