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?
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).
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.