Parsing x-www-form-urlencoded from Memptr is missing last character - Forum - OpenEdge Development - Progress Community

Parsing x-www-form-urlencoded from Memptr is missing last character

 Forum

Parsing x-www-form-urlencoded from Memptr is missing last character

This question is answered

This morning I was working with a web handler request that needs to receive data with a content type of  "application/x-www-form-urlencoded".  I thought this would be pretty easy, and it was ... until I noticed that I am missing the last character.

I am being sent a string that looks normal enough -> field1=AB&field2=CD

I am parsing the data from the poRequest:Entity using the command

lcData = CAST(poRequest.Entity,OpenEdge.Core.Memptr):GetString(1).  

Using that command, the value in lcData shows as "field1=AB&field2=C".  Notice the 'D' is missing.

Originally the data was coming from a .Net HttpClient call.  I made the same call using Postman, using x-www-form-urlencoded as the body type, and I receive the same result.

To get around the issue for today, I decided to go old school and get the value off of WEB-CONTEXT:FORM-INPUT.  When getting the data from there, the full string is retrieved (including the 'D').

Am I doing something wrong in my assignment?  Is there a 'better' way to get 'x-www-form-urlencoded' data from the poRequest that I've missed?

Verified Answer
  • ContentLength sometimes lies (or isn't 100% accurate).

    Try

    def var body as class OpenEdge.Core.Memptr.

    body = CAST(poRequest:Entity,OpenEdge.Core.Memptr).

    body:GetString(1,body:Size).

All Replies
  • This is a bug in the Memptr's GetString() method. It's fixed in 11.7.3.

    The fix adds the "+ 1" below.

       /** Returns a string/character representation from a given start position,

           for the remainder of the data.

           @param  int64 The start potision

           @return longchar The character/string data requested     */

       method public longchar GetString(input piStartPos as int64):

           return GetString(piStartPos, this-object:Size - piStartPos + 1).

       end.

  • Ok.  That being the case, do you think adding poRequest:ContentLength like this

    CAST(poRequest:Entity,OpenEdge.Core.Memptr):GetString(1,poRequest:ContentLength)

    would be reliable?

  • ContentLength sometimes lies (or isn't 100% accurate).

    Try

    def var body as class OpenEdge.Core.Memptr.

    body = CAST(poRequest:Entity,OpenEdge.Core.Memptr).

    body:GetString(1,body:Size).

  • Thanks Peter.  That appears to work as well.  Just to note,  the AS Memptr is not old-school MEMPTR, but AS OpenEdge.Core.Memptr.

  • Indeed - I updated my reply to reflect that.