Sign in to follow this  
shuma-gorath

Problem sending POST requests to Microsoft Translator

Recommended Posts

I originally wrote a similar question on the developer forums for this API, with no luck, so I came here.

I'm trying to send a POST request to Microsoft Translator using their HTTP API, using C++. The code I'm using is as follows:


HINTERNET internet=InternetOpen(PROG_NAME,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);

HINTERNET http=InternetConnect(internet,"api.microsofttranslator.com",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RESYNCHRONIZE,NULL);

char *accepted_types[2]={"text/xml",NULL};
HINTERNET request=HttpOpenRequest(http,"POST","TranslateArray?appId=APP_ID",NULL,"/V2/Http.svc/",(LPCTSTR*)accepted_types,INTERNET_FLAG_RESYNCHRONIZE|INTERNET_FLAG_NO_COOKIES,NULL);

char payload[]="<TranslateArrayRequest><AppId>APP_ID</AppId><From>en</From><Texts><string>one</string><string>two</string></Texts><To>es</To></TranslateArrayRequest>";
HttpSendRequest(request,NULL,0,payload,strlen(payload)+1)





NOTE: In the above, APP_ID expands to a valid appID in the actual code.

All of the function calls succeed, but the server response that results from the HttpSendRequest call gives me a 415: Unsupported media type. Network Monitor tells me that the reason is: "Missing content type." I've tried all sorts of values for accepted_types, even leaving it NULL, but that doesn't work either.

I've even tried different combos for the lpszObjectName and lpszReferer arguments of HttpOpenRequest.


The XML format I'm using follows the example shown here.

What could be wrong?

(For those interested, sample C# code can be found in the documentation for TranslateArray.)

[Edited by - shuma-gorath on December 8, 2010 12:22:15 PM]

Share this post


Link to post
Share on other sites
The example XML you linked to contains ContentType tags:

<TranslateArrayRequest>
<AppId>String content</AppId>
<From>String content</From>
<Options>
<Category xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</Category>
<ContentType xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</ContentType>
<ReservedFlags xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</ReservedFlags>
<State xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</State>
<Uri xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</Uri>
<User xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">String content</User>
</Options>
<Texts>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">String content</string>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">String content</string>
</Texts>
<To>String content</To>
</TranslateArrayRequest>

Share this post


Link to post
Share on other sites
What about the "Content-Type" HTTP header, have you set that? It appears to relate to the second and third arguments of HttpSendRequest(). Accepted-type indicates what you will accept as a response, the content-type header indicates what you are sending to the server.

The C# example specifies a "text/xml" content type.

Share this post


Link to post
Share on other sites
Quote:
Original post by shuma-gorath
What could be wrong?

Quote:
http://msdn.microsoft.com/en-us/library/aa384233(v=vs.85).aspx
lplpszAcceptTypes
A pointer to a null-terminated array of strings that indicates media types accepted by the client

Your array doesn't terminate with a NULL entry.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
What about the "Content-Type" HTTP header, have you set that? It appears to relate to the second and third arguments of HttpSendRequest(). Accepted-type indicates what you will accept as a response, the content-type header indicates what you are sending to the server.

The C# example specifies a "text/xml" content type.

The following...

HttpSendRequest(request,"Content-Type: text/xml",-1,payload,strlen(payload)+1);






results in a 405(verb not allowed).

However, the following...

HttpSendRequest(request,NULL,0,payload,strlen(payload)+1);






results in a 415 (unsupported media type).


Quote:
Original post by adeyblue
Quote:
Original post by shuma-gorath
What could be wrong?

Quote:
http://msdn.microsoft.com/en-us/library/aa384233(v=vs.85).aspx
lplpszAcceptTypes
A pointer to a null-terminated array of strings that indicates media types accepted by the client

Your array doesn't terminate with a NULL entry.

This link (second code sample) on Microsoft's site, confirms this, so, thanks. No visible effect, though. Code above has been updated with this change.

If it helps, here's the (validated) markup I'm currently sending as the payload in a more-readable form, where APP_ID is a valid appID (By the way, why isn't XML supported in the "source" tag?):

<TranslateArrayRequest>
<AppId>APP_ID</AppId>
<From>en</From>
<Options>
<Category xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
<ContentType xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">text/plain</ContentType>
<ReservedFlags xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
<State xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
<Uri xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
<User xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2"/>
</Options>
<Texts>
<string>one</string>
<string>two</string>
</Texts>
<To>es</To>
</TranslateArrayRequest>

Changing the markup also has no visible effect. All it's supposed to do is convert "one" and "two" to the spanish equivalents.

[Edited by - shuma-gorath on December 8, 2010 12:48:59 PM]

Share this post


Link to post
Share on other sites
Since I've been busy, I didn't want to spend too much development time on this and actually experimented with a competing API. However, I finally was able to get it working today and wanted to bring resolution this thread. As mentioned before, I tried different combinations, but I just couldn't get the right one.

The code should have been:


HINTERNET http=InternetConnect(internet,"api.microsofttranslator.com",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RESYNCHRONIZE,NULL);
LPSTR accepted_types[2]={"text/xml", NULL};
HINTERNET request=HttpOpenRequest(http,"POST","/V2/Http.svc/TranslateArray?appId=APP_ID",NULL,NULL,(LPCTSTR*)accepted_types,0,NULL); //Referrer should've been NULL

char payload[]="<TranslateArrayRequest><AppId>APP_ID</AppId><From>en</From><Texts><string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">one</string><string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">two</string></Texts><To>es</To></TranslateArrayRequest>";

/*The header needed both "Content-Length" and "Content-Type." Also, I probably was using the wrong delimiter before.*/
char header[256];
strcpy(header,"Content-Type: text/xml\r\nContent-Length: ");
strcat(header,dtoa(strlen(payload))); //(NOTE: dtoa() just converts nums to c-strings)

HttpSendRequest(request,header,-1L,payload,strlen(payload)); //The last arg here was off by one before










The payload I highlighted above in the post above was correct, but a minimum version could have been:

<TranslateArrayRequest>
<AppId>APP_ID</AppId>
<From>en</From>
<Texts>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">one</string>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">two</string>
</Texts>
<To>es</To>
</TranslateArrayRequest>









Thanks to all who helped.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this