Parse push REST API error 400 "Bad Request" - ios

I am developing an app for iOS using Xamarin iOS & MonoGame. I want to use Parse's push notifications through their REST API, so first I must create an installation object:
var bundle = new Dictionary<string, object>();
bundle.Add("channels", "");
bundle.Add("deviceType", "ios");
bundle.Add("deviceToken", _deviceToken);
string urlpath = "https://api.parse.com/1/installations";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(urlpath);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("X-Parse-Application-Id", _parseAppID);
httpWebRequest.Headers.Add("X-Parse-REST-API-KEY", _parseRestAPIKey);
httpWebRequest.Method = "POST";
string bundleString = bundle.ToJson();
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes(bundleString);
string result = Convert.ToBase64String(buffer);
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(result, 0, result.Length);
requestWriter.Close();
WebResponse httpResponse = await httpWebRequest.GetResponseAsync();
Stream stream = httpResponse.GetResponseStream();
string json = string.Empty;
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
json += reader.ReadLine();
}
}
JsonObject jsonObject = JsonObject.Parse(json);
_varStorage.Save("ObjectId", jsonObject.Get<string>("objectId"));
The bundleString value is:
"{\"channels\":\"\",\"deviceType\":\"ios\",\"deviceToken\":\"46becd0a165be042eeab5a1ec96b8858065cbea7311479da16c0fd1c9428e2eb\"}"
This code raises a System.Net.WebExceptionStatus.ProtocolError error 400 "Bad Request", and I can't see why.

Channels is supposed to be an array of strings according to the documentation, https://www.parse.com/docs/rest#installations
bundle.Add("channels", new [] { "" });

After more trail and error, I found that replacing this
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes(bundleString);
string result = Convert.ToBase64String(buffer);
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(result, 0, result.Length);
requestWriter.Flush();
requestWriter.Close();
with this
httpWebRequest.ContentLength = bundleString.Length;
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(bundleString);
requestWriter.Flush();
requestWriter.Close();
fixed the problem, I don't know exactly why though.

should you not be calling flush before closing your stream ?
requestWriter.Write(result, 0, result.Length);
requestWriter.Close();

Related

Bad request when posting to OData Data Entity in Dynamics 365

I've created a public Data Entity in dynamics with the following fields:
I keep getting a bad request response, but I'm not sure why.
I've tried to make a POST request in two ways:
1.
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionStatus = "Created" };
string jsonMessage = JsonConvert.SerializeObject(hireAction);
using (HttpClient client = new HttpClient())
{
HttpRequestMessage requestMessage = new
HttpRequestMessage(HttpMethod.Post, "MyDynamicsEnvironmentName/data/HireActions?cross-company=true");
requestMessage.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
requestMessage.Headers.Add("Authorization", AuthResult.AuthorizationHeader);
HttpResponseMessage response = client.SendAsync(requestMessage).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//Logic
}
}
var url = "MyDynamicsEnvironmentName/data/HireActions?cross-company=true";
var req = HttpWebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
req.Headers["Authorization"] = AuthResult.AuthorizationHeader;
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionId = "12345", HireActionStatus = "Created" };
var jsonSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local
};
var postString = "CompanyName='DEMF'" + "&MovieId='DEMF-000000014'" + "&HireActionId=132&HireActionStatus='Created'";
var data = JsonConvert.SerializeObject(postString, jsonSettings);
var bytes = Encoding.Default.GetBytes(postString);
var newStream = req.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
using (var resp = req.GetResponse())
{
var results = new StreamReader(resp.GetResponseStream()).ReadToEnd();
}
Some keypoints:
-Of course you'd replace MyDynamicsEnvironmentName with the URL for the environment. The URL is correct and verified however, by the fact that GET requests do work
-The Authresult.AuthorizationHeader contains a valid token, also validated by working GET requests
As said before, both of these result in a bad request. Does someone know what is wrong or missing?

Transition JIRA issue via API returning a 400

I'm trying to transition issues via the API using .NET but I'm consistently getting a 400 error back. I'm wondering if anyone can see anything obvious that I'm doing wrong?
Code:
string example = #"{
""id"": ""221""
}";
string ticketjson = JsonConvert.SerializeObject(example);
string postUrl = "https://myurl/rest/api/2/issue/" + issueKey + "/transitions";
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.BaseAddress = new System.Uri(postUrl);
byte[] cred = UTF8Encoding.UTF8.GetBytes("username:pwd");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(ticketjson, Encoding.UTF8, "application/json");
var response = client.PostAsync(postUrl, content).Result;
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
return result;
}
else
{
unauth.Text = "There has been a problem submitting your comment. Please try again.";
return response.StatusCode.ToString();
}
The transition exists and when I go to the postUrl I can see it:
Any help would be appreciated!

Why is my HttpWebRequest POST method to my WebAPI server failing?

I've successfully received data from my WebAPI project ("GET"), but my attempt to Post is not working. Here is the relevant server/WebAPI code:
public Department Add(Department item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
departments.Add(item);
return item;
}
...which fails on the "departments.Add(item);" line, when this code from the client is invoked:
const string uri = "http://localhost:48614/api/departments";
var dept = new Department();
dept.Id = 8;
dept.AccountId = "99";
dept.DeptName = "Something exceedingly funky";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "POST";
var deptSerialized = JsonConvert.SerializeObject(dept); // <-- This is JSON.NET; it works (deptSerialized has the JSONized versiono of the Department object created above)
using (StreamWriter sw = new StreamWriter(webRequest.GetRequestStream()))
{
sw.Write(deptSerialized);
}
HttpWebResponse httpWebResponse = webRequest.GetResponse() as HttpWebResponse;
using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
{
if (httpWebResponse.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST failed. Received HTTP {0}", httpWebResponse.StatusCode);
throw new ApplicationException(message);
}
MessageBox.Show(sr.ReadToEnd());
}
...which fails on the "HttpWebResponse httpWebResponse = webRequest.GetResponse() as HttpWebResponse;" line.
The err msg on the server is that departments is null; deptSerialized is being populated with the JSON "record" so...what is missing here?
UPDATE
Specifying the ContentType did, indeed, solve the dilemma. Also, the StatusCode is "Created", making the code above throw an exception, so I changed it to:
using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
{
MessageBox.Show(String.Format("StatusCode == {0}", httpWebResponse.StatusCode));
MessageBox.Show(sr.ReadToEnd());
}
...which shows "StatusCode == Created" followed by the JSON "record" (array member? term.?) I created.
You forgot to set the proper Content-Type request header:
webRequest.ContentType = "application/json";
You wrote some JSON payload in the body of your POST request but how do you expect the Web API server to know that you sent JSON payload and not XML or something else? You need to set the proper Content-Type request header for that matter.

Twitter streaming api hangs

I was able to get this to run without any error being thrown however after it gets to the line "string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();" it just hangs. I have a breakpoint on the next line and still nothing. Am I not using this correctly? This is in a windows forms application. What do I need to do in order to parse this out? How do I grab the data while keeping the stream open?
My goal with this is to be able to grab tweets and sort them based on criteria TBD.
var oAuthToken = "****";
var oAuthTokenSecret = "****";
var oAuthConsumerKey = "****";
var oAuthConsumerSecret = "****";
var oAuthVersion = "1.0";
var oAuthSignatureMethod = "HMAC-SHA1";
var oAuthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oAuthTimeStamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
var resourceURL = "https://stream.twitter.com/1.1/statuses/filter.json";
var locations = "-180,-90,180,90";
var baseFormat = "locations={6}&oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
var baseString = string.Format(baseFormat,
oAuthConsumerKey,
oAuthNonce,
oAuthSignatureMethod,
oAuthTimeStamp,
oAuthToken,
oAuthVersion,
Uri.EscapeDataString(locations)
);
baseString = string.Concat("POST&", Uri.EscapeDataString(resourceURL), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oAuthConsumerSecret),
"&", Uri.EscapeDataString(oAuthTokenSecret));
string oAuthSignature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oAuthSignature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oAuthNonce),
Uri.EscapeDataString(oAuthSignatureMethod),
Uri.EscapeDataString(oAuthTimeStamp),
Uri.EscapeDataString(oAuthConsumerKey),
Uri.EscapeDataString(oAuthToken),
Uri.EscapeDataString(oAuthSignature),
Uri.EscapeDataString(oAuthVersion)
);
//make the request
ServicePointManager.Expect100Continue = false;
var postBody = "locations=" + Uri.EscapeDataString(locations);
resourceURL += "?" + postBody;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resourceURL);
request.Headers.Add("Authorization", authHeader);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
try
{
WebResponse response = request.GetResponse();
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
catch (Exception exception)
{
throw (exception);
}
Well it's a streaming API, so it will stream infinitely. Hence if you are trying to read to the end of stream, it will block forever until you run out of memory or get disconnected due to network error etc.
You need to process the data while connected to the stream. If I were you I'd just use a client library (see https://dev.twitter.com/docs/twitter-libraries).

Blackberry: KSoap2 XmlPullParserException expected:END_TAG error

I'm receiving the following error on my Blackberry app:
org.xmlpull.v1.XmlPullParserException:expected"END_TAG</{http://schemas.xmlsoap.org/soap/envelope/}soap:Fault>#3:181 in java.io.InputStreamReader#d88bc808)
I'm using KSoap2 to create the envelope, when I get the response I use the following code to give me the XML, maybe I shouldn't be (this code is obviously incomplete):
String serviceUrl = WS_URL + Globals.theApp.getConnectionString();
String serviceNamespace = "http://www.mysite.com/";
String soapAction = "http://www.mysite.com/postMessage";
SoapObject rpc = new SoapObject(serviceNamespace, "postMessage");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = rpc;
envelope.dotNet = true;
envelope.encodingStyle = SoapSerializationEnvelope.XSD;
envelope.addMapping("http://www.mysite.com/", "Message", new Message().getClass());
PropertyInfo pinfo = new PropertyInfo();
pinfo.name = "myMessage";
pinfo.namespace = serviceNamespace;
pinfo.type = Message.MESSAGE_CLASS;
rpc.addProperty("Message", message);
HttpTransport ht = new HttpTransport(serviceUrl);
ht.debug = true;
String xmlResponse;
try
{
ht.call(soapAction, envelope);
xmlResponse = envelope.getResponse().toString();
SoapObject myResponse = (SoapObject)envelope.getResponse();
xmlResponse = ht.responseDump;
I'm using ht.responseDump to get me the xml string (because before it wasn't sending back anything in XML.) From there I try to parse xmlResponse etc.....
But I get that error, why?? Is ht.responseDump not the best way to go about this? What does ht.debug do?? Why is my xml getting cut off??
Thanks in advance. I really need some help.

Resources