How to create http MessageBody body with fields that contain dashes

I would like to create http message bodies with fields that contain dashes. I haven't been able to find a workaround for Matlab disallowing hyphens (dashes) in the var names.
Here is what I'm trying to do - for illustration - I have an underscore in place of a hyphen the "test_var" (below)
Even after generating the RequestMessage (req1 below), you cannot change "test_var" to "test-var" because the RequestMessage is still storing the request as a struct (not as a string which could be modified).
method = matlab.net.http.RequestMethod.POST;
header = matlab.net.http.HeaderField('Content-Type', 'application/json');
header = addFields(header,'User-Agent', 'my-client/99.9');
header = addFields(header,'Accept', 'application/json');
% Struct approach
struct1 = struct('login', 'me', 'password', 'pw123', 'test_var', true)
body1 = matlab.net.http.MessageBody(struct1)
req1 = matlab.net.http.RequestMessage(method,header,body1)
show(req1)
POST
Content-Type: application/json
User-Agent: my-client/99.9
Accept: application/json
{"login":"me","password":"pw123","test_var":true}
req1.Body.Data
ans =
struct with fields:
login: 'me'
password: 'pw123'
test_var: 1

12 Comments

Hi stedst9,
After reading @dpb comments, I modified my comments, you can work around this limitation by using a cell array to store the field names and values, allowing for hyphens in the field names.
Hope this answers your question. If @dpb has some time, he will address this problem by suggesting ideas as well.
@Umar, that just replaces one hyphenated field name with another hyphenated field name; that doesn't solve @stedst9's problem.
I have never done this sort of thing and don't have time at present to delve into it enough to understand the how of what alternative forms there are for building the data packet, but clearly if the field name MUST be one containing a hyphen, then MATLAB isn't going to be able to deal with that.
I woulld presume there's some other way to pass the info or that while the wish for a hyphenated fieldname may be strong that it isn't a hard limit on actually making something work.
"..., you can work around this limitation by using a cell array to store the field names and values, allowing for hyphens in the field names"
But if the object is to pass the struct to matlab.http.MessageBody, that still doesn't help the struct
OP's objective appears to be that struct1 has a hyphenated fieldname as a MATLAB struct. That just ain't a'gonna' happen.
body1 = matlab.net.http.MessageBody(struct1)
In a very quick glance it looked as though there were other ways to build a body content besides using a struct, but it was way more reading than have time for to try to figure out what/how having never looked at any of this before.
@dpb,
How about converting the hyphenated field names to underscores or remove the hyphens altogether. This will make sure that the struct adheres to Matlab's naming conventions and can be successfully passed to matlab.net.http.MessageBody.
@Umar, of course. That is the what his example code used.
But that wasn't @stedst9's question. What we weren't told is exactly why the Q? was raised.
That is, does the other end of the process mandate the fieldname/variable be hyphenated on its end and is unchangeable or does he/she just prefer it that way for aesthetic or other reasons? Hence we do not know whether simply accepting the MATLAB naming convention will provide a working solution that is less than desirable in this one particular or whether it doesn't work at all because the other end of the process expects and requires the name match identically.
I posted to the community to see if someone else has encountred this before and can post a straightforward example of how to correctly create a request MessageBody with "dasherized" keys.
The hyphens in the JSON key names are required by the API server - which are controlled by a third party (so I can't change them to underscores). The keys are in the request and response bodies.
{
"this-key-is-dasherized": "value goes here"
}
In that case the MATLAB struct for the message body is simply not going to be usable.
As noted, this is completely out of my experience base but it looked as though there may be alternate ways to build a message body in the documentation, but it's far too deep of a subject it appears and I didn't see any quickly apparent examples in the time available.
I would suggest this would be worthy of an official support request if you can't find such other techniques in the doc; the chances of there being a change in what is an allowable fieldname in a MATLAB struct any time "real soon now" is nil.
Yes, I agree that using a struct seems nigh impossible.
We're in the same boat as this is outside of my experience as well. And the documentation on alternate ways to build a message body is very thin with no examples.
Will Python support? Maybe there's a way there that could be called from MATLAB. Or, use the .NET stuff directly, maybe? I dunno, I'm just fishing here.
As noted, I'd either send a support request or call directly on this one.
Yes @dpb - I've had the same thought: Python would be a last resort work-around. It seems like such a hack though.
In theory, the Mathworks deverlopers put enough capability into the MessageBody class that there should be at least one way to do it in Matlab. I'm hoping to get a good, clean Matlab solution and maybe some improvements to the online Matlab documentation that show how to use more of the options in the MessageBody class.
Thanks to everyone who chipped in with their thoughts. The solution from Mathworks is solid.
No problem, @stedst9, it’s all teamwork and resolving problems together to help out each other. Glad to know that this problem is resolved.

Sign in to comment.

 Accepted Answer

I contacted Mathworks support and received the following solution - it works:
% Method
method = matlab.net.http.RequestMethod.POST;
% Header
header = matlab.net.http.HeaderField('Content-Type', 'application/json');
header = addFields(header,'User-Agent', 'my-client/99.9');
header = addFields(header,'Accept', 'application/json');
% Body
keySet = {'login', 'password', 'test-var'};
valueSet = {'me', 'pw123', true};
map = containers.Map(keySet, valueSet);
body = matlab.net.http.MessageBody(map);
request = matlab.net.http.RequestMessage(method,header,body);
response = send(request, uri);

More Answers (1)

If Content-Type can be "text/plain" (mislabelling the content-type -- not sure if your API accepts that), then you can use string or char array as the message body:
MessageBody('{"login":"me","password":"pw123","test-var":true}');
If Content-Type must be "application/json", then calling RequestMessage.send will use jsonencode on your message body to generate the payload to send. If your message body contains a struct, you get:
'{"login":"me","password":"pw123","test_var":true}'
else if your message body contains a string, you get:
"{\"login\":\"me\",\"password\":\"pw123\",\"test-var\":true}"
Neither result is the JSON with dashed fields you desired.
If you want both Content-Type "application/json" and dashed field, you may look into this:
"To send arbitrary headers and data in a request message, set Completed to true to prevent the send method from modifying the message."
But in that case, it seems you will have to build and validate the request message yourself. (I have not try this before.)

1 Comment

Samuel,
I'm not permitted to mislabel the content-type. You're right about the struct and string output - you got the same result as me. For the past few hours, I've made several of RequestMessage attempts using request.Completed = true. Still no luck - I'm not through the woods yet.

Sign in to comment.

Asked:

on 20 Jul 2024

Commented:

on 23 Jul 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!