0

Good Morning, iam using the casablanca REST SDK.

Is there any simple way to convert a json string in an object and back as shown in this example? (http://www.newtonsoft.com/json/help/html/serializingjson.htm)

Update I found a little function that could do what i need. When i use the function i get errors as shown in the picture. Have someone a solution for that?

User GetUser(http_request *Reques)
{
     return Request->body().extract<User>().get();
}

Error

greetings cazza

Cazzador
  • 33
  • 2
  • 9
  • See response http://stackoverflow.com/a/39904347/606515 for JSON to/from C++ object conversion lib. – kola Oct 06 '16 at 20:49

3 Answers3

0

There is no Simple Way as the is no Reflection in C++. You must write serializing function all on your own.

However there are some tricks that may allow you to write your (de)serializing function by a list of members within macro, but Casablanca don't have any of help doing so.

Arpegius
  • 5,817
  • 38
  • 53
0

Fortunately, C++ offers no simple way of blurring the line between network communication content and the source code of your program. Something like all those terrible reflection-based JSON libraries out there cannot happen to C++. Coincidentally, while I cannot speak for C#, reflection-based JSON libraries in Java are a huge violation of best practices outlined in Joshua Bloch's renowned Effective Java book. See Item 53, Prefer interfaces to reflection:

As a rule, objects should not be accessed reflectively in normal applications at runtime

In C++, we do not need such a guideline because there is no reflection. That's mostly a good thing.

Now, that's not to say that you have to write your own JSON parser, of course. While JSON parsing is not part of the standard library, 3rd-party alternatives exist. For example, have a look at JSON for Modern C++.

Whatever library you use, you will have to explicitly read from and write to your class members in one way or the other.

That is, if you have the following class (which more or less matches the C# example you linked):

struct Product
{
    std::string name;
    int price;
    std::vector<std::string> sizes;
};

Then with the aforementioned library, you'd have to turn a Product object into JSON like this:

json j = {
    { "name", product.name },   // explicit relationship between "name" and "name"
    { "price", product.price }, // explicit relationship between "price" and "price"
    { "sizes", product.sizes }  // explicit relationship between "sizes" and "sizes"
};

std::cout << j << "\n";

And reading:

json j;
std::cin >> j;

Product product;
product.name = j["name"];   // explicit relationship between "name" and "name"
product.price = j["price"]; // explicit relationship between "price" and "price"
product.sizes = j["sizes"]; // explicit relationship between "sizes" and "sizes"

Such an approach is also called non-intrusive serialisation/deserialisation. An intrusive approach, on the other hand, with member or friend functions, would be the only way to go if you need access to private member variables.

Things to keep in mind:

  • Run-time reflection is dangerous and error-prone in languages which support it.
  • C++ has no run-time reflection.
  • C++ encourages you to cleanly separate two concerns: (1) Parsing of JSON, (2) Serialisation/deserialisation of a class.
  • Free 3rd-party libraries for JSON parsing exist.
Cœur
  • 37,241
  • 25
  • 195
  • 267
Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
0

And here the snipped

 bool User::LoadNewUser(json::value user)
{
    try{
        this->SetName(utility::conversions::to_utf8string(user[L"UserName"].as_string()));
        this->SetMail(utility::conversions::to_utf8string(user[L"Email"].as_string()));
        this->SetScreenName(utility::conversions::to_utf8string(user[L"ScreenName"].as_string()));


UserResponse Usermanagement::CreateNewUser(http_request *Request)
{
    UserResponse Resp;

    if (this->LoadNewUser(Request->extract_json().get()))
Cazzador
  • 33
  • 2
  • 9