Results 1 to 9 of 9

Thread: MSGraph @odata.nextLink

  1. #1
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160

    MSGraph @odata.nextLink

    Hoi,

    Even iets waar ik niet uit geraak, ophalen van afspraken uit MS graph via rest componenten.

    Ik heb een class structuur, het hoofd deel:

    TMSCalendarEventsResponse = class
    private
    [JSONName('@odata.context')]
    Fodatacontext: String;
    [JSONName('@odata.nextLink')]
    Fodatanextlink: String;
    Fvalue: TMSCalendarEvents;
    procedure Setvalue(const Value: TMSCalendarEvents);
    public
    property odatacontext: String read Fodatacontext write Fodatacontext;
    property odatanextlink: String read Fodatanextlink write Fodatanextlink;
    property Value: TMSCalendarEvents read Fvalue write Setvalue;
    end;

    Na het uitvoeren van de TRestRequest ik in de json 3 properties kan terugkrijgen die met een '@' beginnen, "@odata.context" ,"@odata.nextLink" en "@odata.deltaLink".

    Nu kan je in Delphi in een Class geen property maken die begint met @ of met '.' tussen, volgens een collega moet het dan zoals hierboven maar ik krijg in mijn object, van die class, geen waarden in die properties odatacontext en odatanextlink.
    Alle andere waarden worden wel correct ingevuld.

    Heeft iemand dit zelfde probleem reeds gehad en weet een mogelijke oplossing?
    Ik kan ze natuurlijk manueel uit de json halen met TJsonValue en zo maar vraag me af waarom deze niet in het object ingevuld worden na uitvoeren van JsonToObject.

    Zie ook https://docs.microsoft.com/en-us/gra...-1.0&tabs=http

  2. #2
    Op StackOverflow wordt er nog een extra attribuut toegevoegd:

    Code:
    [JSONMarshalled(True)]
    Als ik het goed begrijp is dat eigenlijk alleen nodig voor velden zonder 'F', maar helemaal duidelijk wordt dat niet dus je kan het proberen.
    Overigens vind ik de Json (de-)serialisatie van Delphi bedroevend in elkaar zitten, en het zou me ook niets verbazen als de deserializer gewoon niets snapt van die @, en het daarom overslaat.
    1+1=b

  3. #3
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Bedankt, ik probeer het straks even uit.
    *edit* nee dat maakt dus ook geen verschil, die properties in de class blijven gewoon leeg.
    Last edited by Delphiwizard; 31-Jan-21 at 13:36.

  4. #4
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Dit probleem vind ik dus niet, na teveel tijdverlies een quick en dirty oplossing, na het uitvoeren van de rest request en voor JsonToObject StringReplaces uitgevoerd en het probleem is opgelost.
    StringReplace('@odata.nextLink', 'odatanextlink') etc voor de andere.

    Nu zitten de json waarden mooi in het object.
    Mocht er ooit iemand vinden waarom het niet meteen werkt zoals het was hierboven, zou het graag weten

  5. #5
    Ok, toch eens even gekeken, je class gekopieerd naar een testprojectje, dummy Json gemaakt, en inderdaad, geen data.

    Ik zag wel een compiler hint 'Unknown attribute'. Dat ging over het JsonName attribute. Die is in mijn geval (Rio), gedeclareerd in REST.Json.Types. Zodra ik die unit toevoegde aan de unit waarin TMSCalendarEventsResponse staat, werkte het deserializeren goed. Het is geen compiler error, dus misschien makkelijk over het hoofd te zien? En misschien is dat attribute verplaatst naar een andere unit tussen twee versies in.
    1+1=b

  6. #6
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Oh dat moet ik dan zeker morgen eens proberen, kan je het stukje code van je class hier plaatsen aub?
    Heb je die [JSONMarshalled(True)] dan ook gebruikt of niet?

    Je class ziet er nu identiek uit aan mijn voorbeeld?
    Code:
    TMSCalendarEventsResponse = class
    private
    [JSONName('@odata.context')]
    Fodatacontext: String;
    [JSONName('@odata.nextLink')]
    Fodatanextlink: String;
    Fvalue: TMSCalendarEvents;
    procedure Setvalue(const Value: TMSCalendarEvents);
    public
    property odatacontext: String read Fodatacontext write Fodatacontext;
    property odatanextlink: String read Fodatanextlink write Fodatanextlink;
    property Value: TMSCalendarEvents read Fvalue write Setvalue;
    end;

  7. #7
    Nee, geen JsonMarshalled gebruikt, maar dus wel Rest.Json.Types in de uses gezet.

    Hier is de hele test-unit. Voeg toe aan een lege console application en roep `TestDeserialize` aan.
    Ik ben benieuwd of het dan werkt, en zo niet, of je Compiler Warnings krijgt over dat attribute. Merk op dat ik dit in Rio heb getest, en dat ik TMSCalendarEventsResponse iets aangepast heb voor de test.

    Wellicht ten overvloede, maar ik bedoel dus niet te zeggen dat je jouw code moet vervangen. Ik wil enkel aantonen dat het serializeren van Delphi, en specifiek het gebruik van dat attribute, staat of valt bij het usen van die ene unit!

    Delphi Code:
    1. unit uTestDeserialize;
    2.  
    3. interface
    4.  
    5. uses
    6.   System.Json,
    7.   Rest.Json.Types, // << -- Zonder deze compileert het wel, maar werkt het niet
    8.   Rest.JsonReflect;
    9.  
    10.  
    11. procedure TestDeserialize;
    12.  
    13. function MapJson(Json: String; ConvertToClass: TClass): TObject;
    14.  
    15. type
    16.   TMSCalendarEventsResponse = class
    17.   private
    18.     [JSONName('odata.bork')]
    19.     Fodatabork: String;
    20.     [JSONName('@odata.context')]
    21.     Fodatacontext: String;
    22.     [JSONName('@odata.nextLink')]
    23.     Fodatanextlink: String;
    24.   public
    25.     property odatacontext: String read Fodatacontext write Fodatacontext;
    26.     property odatanextlink: String read Fodatanextlink write Fodatanextlink;
    27.   end;
    28.  
    29. implementation
    30.  
    31. function MapJson(Json: String; ConvertToClass: TClass): TObject;
    32. var
    33.   UnMarshaller: TJSONUnMarshal;
    34.   Dto: TObject;
    35.   JsonObject: TJSONObject;
    36. begin
    37.   UnMarshaller := TJSONUnMarshal.Create;
    38.   JsonObject := TJSONObject.ParseJSONValue(Json) as TJsonObject;
    39.  
    40.   try
    41.     UnMarshaller.TryCreateObject(ConvertToClass, JsonObject, Dto);
    42.     Result := Dto as ConvertToClass;
    43.   finally
    44.     JsonObject.Free;
    45.   end;
    46. end;
    47.  
    48. procedure TestDeserialize;
    49. var
    50.   a: TMSCalendarEventsResponse;
    51. begin
    52.   a := MapJson('{"odata.bork": "bork", "@odata.context": "koe", "@odata.nextLink": "big"}', TMSCalendarEventsResponse) as TMSCalendarEventsResponse;
    53.  
    54.   writeln('Props');
    55.   writeln(a.Fodatabork);
    56.   writeln(a.Fodatacontext);
    57.   writeln(a.Fodatanextlink);
    58.  
    59.   readln;
    60. end;
    61.  
    62. end.
    Last edited by GolezTrol; 08-Feb-21 at 09:44.
    1+1=b

  8. #8
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Bedankt, ik heb het deze morgen eens geprobeerd maar had dan een andere foutmelding, ik bekijk het de komende dagen nog verder

  9. #9
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Het is me dan gisteren alsnog gelukt, bedankt voor de demo en om het uit te zoeken GolezTrol!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •