StreamReader reads \u00fc but Postman reads OK - unicode

Probably duplicate question but I couldn't find an answer for my problem. I have this code to call a web service:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://172.21.122.1:5001/autocomplete");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//tried this too: httpWebRequest.Accept = "gzip, deflate";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write("{ \"message\" : \"mü\" }");
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
response = "";
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
response = streamReader.ReadToEnd();
}
But no matter what Encoding I tried with StreamReader() c'tor, I get this response or worse: {"words":["m\u00fc\u015fteri","m\u00fc\u015fterisiyim""]}
When I use Postman or SoapUI to call the same service with the same request: {"message": "mü"},
response looks ok: {"words": ["müşteri","müşterisiyim"]}
Strange thing is: The same code works OK with many other services. It is only this specific service that the reponse is not correctly encoded. We believe there is a programming error with the service, but what I wonder is how Postman or SoapUI handles this. There should be a control in their code and if the response contains "\uxxxx", then Postman or SoapUI decodes it again.
I've checked all request / response headers in Postman and SoapUI with no luck. What can be the reason?

You have to make sure that your request is encoded correctly:
Set the Content Type to:
httpWebRequest.ContentType = "application/json;charset=UTF-8";
Check if request body is also UTF-8 encoded. Set the StreamWriter encoding to UTF-8 as well:
...
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream(), Encoding.UTF8))
...
If you are getting the request content from other source, make sure to read it also using UTF-8 encoding.

Regex.Unescape(response) worked like a charm, thanks JosefZ!

Related

Calling API from Saleforce is giving error code 500

I have a REST API to callout from Salesforce.
The authorization of the API is through access token.
I am able to get the access token through POST request in Salesforce. Also tested from Postman through that token and able to get a successful response.
I am using the below code to callout the API using the access token:
String endpoint_x = '*****';//Putting my endpoint here
Http httpObject;
HttpResponse response;
String accessToken;
accessToken = MyUtilityClass.getAccessToken();
jsonBody = json.serializePretty('', true);//Yes, My JSON is empty
HttpRequest request = new HttpRequest();
request.setEndpoint(endpoint_x);
request.setHeader('Authorization', 'Bearer '+accessToken);
request.setMethod('POST');
request.setBody(jsonBody);
httpObject = new Http();
response = httpObject.send(request);
System.debug('Response=' + response);
Getting Response value as below:
System.HttpResponse[Status=Internal Server Error, StatusCode=500]
I have tried putting '{}' in the Jsonbody. Added 'Content-Type' in header but nothing worked.
Where should I lookout for this?
In the Postman, I was not putting anything in the body, and getting a successful response.
To get the same behaviour, I was using empty string in Apex, like this:
jsonBody = json.serializePretty('', true);
But the parser was not working correctly.
To solve this, I created a class without any field:
class ClassForEmptyBody{
}
And used object of that class in the serializer:
ClassForEmptyBody classForEmptyBodyObject = new ClassForEmptyBody();
jsonBody = json.serializePretty(classForEmptyBodyObject , true);
Why are you passing json body if nothing is in there. Just skip setbody code and try.

REST Hammock not adding content to post body

I've been fiddling a POST request that isn't working. What I've found is that the content of the request is empty even though I believe I'm adding it correctly (even though there aren't any docs available that I can find).
var json = JsonConvert.SerializeObject(payload);
var client = new RestClient
{
Authority = "",
Credentials = OAuthCredentials.ForProtectedResource(Registration.ClientKey,
Registration.ClientSecret,
AuthorizationToken.Token,
AuthorizationToken.Secret),
Method = WebMethod.Post,
Path = url
};
var request = new RestRequest();
request.AddHeader("Accept", ContentType);
request.AddHeader("Content-Type", ContentType);
request.AddPostContent(Encoding.UTF8.GetBytes(json));
response = client.Request(request);
I'm not having any trouble with authorization. I just kept getting a 400 error. After capturing the request with Fiddler, I noticed that content-length was 0. What am I missing? Do I need to do something in addition to AddPostContent? When I check the request object right before executing, there is content in PostContent, but it's as if Hammock isn't adding it to the request. I am using the latest full nuget (not ClientProfile).

Azure encoding job via REST Fails

I am trying to upload a video and encode it via azure rest service.
I have now hit the step of encoding the video but I am having difficulties with the request.
The following code shows my request:
var joburl = res.RequestMessage.RequestUri + "Jobs";
client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer " + token);
client.DefaultRequestHeaders.Add("x-ms-version", "2.8");
client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0");
client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0");
client.DefaultRequestHeaders.Add("x-ms-date", date);
//accept
t = new NameValueHeaderValue("odata", "verbose");
type = new MediaTypeWithQualityHeaderValue("application/json");
type.Parameters.Add(t);
client.DefaultRequestHeaders.Accept.Add(type);
result = await client.PostAsync(joburl,json);
the url:https://wamsamsclus001rest-hs.cloudapp.net/api/Jobs
the json:
{"Name":"khgfiuydencodingjob","InputMediaAssets":[{"__metadata":{"Uri":"https://wamsamsclus001rest-hs.cloudapp.net/api/Assets('nb%3acid%3aUUID%3ad037b321-cd1c-43a9-9607-c4910fa7a85b')"}}],"Tasks":[{"Configuration":"H264 Adaptive Bitrate MP4 Set 720p","MediaProcessorId":"nb:mpid:UUID:1b1da727-93ae-4e46-a8a1-268828765609","TaskBody":"<?xml version=\"1.0\"encoding=\"utf-8\"?><taskBody><inputAsset>JobInputAsset(0)</inputAsset><outputAsset>JobOutputAsset(0)</outputAsset></taskBody>"}]}
The bearer token works as I use it for other request.
But I get a bad request 400 with the followin error message:
{"error":{"code":"","message":{"lang":"en-US","value":"Parsing request content failed due to: Make sure to only use property names that are defined by the type"}}}
Can anyone spot the error.
Thank you for the help
Okay I got it to work. Needed a odata=verbose in my json/string content - like this:
var jobInJson = JsonConvert.SerializeObject(job);
json = new StringContent(jobInJson, Encoding.UTF8);//,
json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
I tried this earlier however I got a error 500 but now it is working.

How To URLEncode Facebook Post Data in C#

I am rewriting code from http://blog.blackballsoftware.com/2010/11/03/making-a-facebook-wall-post-using-the-new-graph-api-and-c/ to create a class to post to Facebook. The code works as long as I do not URLEncode the post data. For example: If the post data is "message=Test,please ignore" then it works. If I URLEncode the same data into "message%3dTest%2cplease+ignore" then I get the error {"error":{"message":"(#100) Missing message or attachment","type":"OAuthException","code":100}}.
Should the Post data be URLEncoded? I think it should because if I post a message like this, "Test&Message", then only the word Test appears.
Relevant code is below. If postParams = HttpUtility.UrlEncode(postParams); is commented out, then the code works. If not, Facebook returns the error that the message is missing.
postParams = HttpUtility.UrlEncode(postParams);
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(postParams);
webRequest.ContentLength = bytes.Length;
System.IO.Stream os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
var webResponse = webRequest.GetResponse();
}
catch (WebException ex)
{
StreamReader errorStream = null;
errorStream = new StreamReader(ex.Response.GetResponseStream());
error = errorStream.ReadToEnd() + postParams;
}
The answer can be found on Stackoverflow at C# Escape Plus Sign (+) in POST using HttpWebRequest. Use Uri.EscapeDataString and not URLEncode. Encode the parameter value only and not the equals sign after the parameter name. Example: message=Test%2Cplease%26%20ignore works but message%3dTest%2Cplease%26%20ignore does not work because the equals after the parameter name is encoded as %3d.

Strange Status Code From Apple Receipt Verification Sandbox

I make a post request of base64 encoded data to the receipt verification address as follows (this is in C#):
var postSerializer = new JavaScriptSerializer();
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Receipt);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
var temp = new Dictionary<string, string>();
temp.Add("receipt-data", returnValue);
string jsonReceipt = postSerializer.Serialize(temp);
request.Method = "POST";
request.ContentType = "application/json";
byte[] postBytes = System.Text.Encoding.ASCII.GetBytes(jsonReceipt);
request.ContentLength = postBytes.Length;
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(postBytes, 0, postBytes.Length);
// Close the Stream object.
dataStream.Close();
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
I'm pretty sure things are in the right format because I'm not getting any exceptions back
from the apple receipt verification endpoint. The entirety of the response I get back is
{status : -42352}
And I can't find out what this error means anywhere. Does anyone know what this means or if there's an error in my code?
Just solved the same problem. Got the solution from here: Verify receipt for in App purchase
The problem was in post encoding. When I encoded post on my server using
$receipt = json_encode(array("receipt-data" => base64_encode($receiptdata)));
I had the same -42352 status. When I used my own function for encoding on iPhone - everything worked! Magic...