The 302 redirect is really a redirect to a 404 error page. I suspect that, because you're getting the 302 redirect to a system "404 error" page, the redirection is happening at the route-handling layer: it's possible to get a 404 from deeper down in the stack, but then you'd just get a direct 404 response to your request. The most likely causes, then, are that the D2L app stack can't properly bind your URL (plus a few parameters) to a route handler -- that is, it can't tokenize your request to know which bit of controller code to hand the request off to.
I presume that, when you write
userContext.createAuthenticatedUri("/d2l/api/le/1.0/Orgid/content/modules/moduleid/structure/", "POST")
you are actually putting in the real Orgid
and moduleid
values in that route? Because the string as written would definitely return a 404 -- there's no such route -- and in fact it would likely redirect to the system 404 error page exactly as you describe.
Notice also that when you write
...
"Content-Type: application/json \r\n" +
"{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": \"Test\", \"Type\": 1, \r\n" +
...
I'm not sure that will work. I believe that the relevant standards on multipart HTTP bodies indicate that you're required to mark the separation of a part header from a part data payload with a blank line, and here you're only inerting one carriage return. Your packet will look like this:
Content-Type: application/json
{"IsHidden": false, "IsLocked": false, ...
When it should maybe look like this:
Content-Type: application/json
{"IsHidden": false, "IsLocked": false, ...
You might try fixing those and see what happens.