Unauthorized when calling Google GCM - c#

I trying to use Google GCM for sending push notifications. But get a WebException that says that the remote server returns 401 unautorized. I can't foung why it doen't work.
Anyone that knows why it doesn't work?
Here is my code:
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
Request.Method = "POST";
Request.KeepAlive = false;
string postData = "{ 'registration_ids': [ '"+registrationId+"' ], 'data': {'message': '"+message+"'}}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
Request.ContentType = "application/json";
//Request.ContentLength = byteArray.Length;
//Request.Headers.Add(HttpRequestHeader.Authorization, "GoogleLogin auth=" + AuthString);
Request.Headers.Add(HttpRequestHeader.Authorization, "Authorization: key=AIzaSyCEygavdzrNM3pWNPtvaJXpvW66CKnjH_Y");
//-- Delegate Modeling to Validate Server Certificate --//
//-- Create Stream to Write Byte Array --//
Stream dataStream = Request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//-- Post a Message --//
WebResponse Response = Request.GetResponse();
HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
{
var text = "Unauthorized - need new token";
}
else if (!ResponseCode.Equals(HttpStatusCode.OK))
{
var text = "Response from web service isn't OK";
}
StreamReader Reader = new StreamReader(Response.GetResponseStream());
string responseLine = Reader.ReadLine();
Reader.Close();

Daniel - Dude there is an issue with the GCM documentation ! Use Browser key as the authorization key at the place of Server API key . It will work.

OK, i am just shooting in the dark here. Take a look at this line:
Request.Headers.Add(HttpRequestHeader.Authorization, "Authorization: key=AIzaSyCEygavdzrNM3pWNPtvaJXpvW66CKnjH_Y");
Shouldn't it be:
Request.Headers.Add(HttpRequestHeader.Authorization, "key=AIzaSyCEygavdzrNM3pWNPtvaJXpvW66CKnjH_Y");
Since you're telling it this is a Authorization header, there's no need to add 'Authorization: ' again, does it?
Also, make sure the string constant 'HttpRequestHeader.Authorization' is 'Authorization'.

Related

c# PayPal Acess Token does not return anything although connection is "OK"

I am using .net to connect to PayPal to get access token. I was following the documentary provided on PayPal. https://developer.paypal.com/docs/api/overview/#make-your-first-call
This is what I have so far. Mostly go it from here. Although it connects, it does not return anything back. I tried it on the Postman and I am getting a json object with access token, but nothing is returned here.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.sandbox.paypal.com/v1/oauth2/token");
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(clientId + ":" + clientSecret));
request.Accept = "application/json";
request.Headers.Add("Accept-Language", "en_US");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 10000;
byte[] postBytes = Encoding.ASCII.GetBytes("grant_type=client_credentials");
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
This is what I am getting from on breakpoints.
response.CharacterSet = ""
response.ContentLength = 899
response.StatusCode = OK
Found the answer. The following code provides the json object.
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
Console.WriteLine(responseString); // This will display the answer as JSON, now just parse it.
Follow PayPal's .NET SDK Quick Start guide. You can authenticate and get your access token as follows:
using PayPal.Api;
// Authenticate with PayPal
var config = ConfigManager.Instance.GetProperties();
var accessToken = new OAuthTokenCredential(config).GetAccessToken();

remote server returned an error 500 internal server error

I have to call a method of web service which contains array as part of parameters.
I dont want to pass any value for the parameter of type Array.
I tried passing null,""(empty)but the web Method call returns 'remote server returned an error 500 internal server error 'as error.I am unable to figure out the cause?Need some help.
Here is my code
string post_data = "SessionID=" + sessionID + "&From=" + "" + "&To=" + "" + "&Changed=" + "" ;
// this is where we will send it
string uri = "test.asmx";
// create a request
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
// this is important - make sure you specify type this way
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);

GCM giving error: (401) Unauthorized

I am trying to write the web api in c# to send push notification in android device. which is giving me the 401 unauthorized error. i have follow all the step to send the notification. i am not able to understand why i am not authorize user.
here is my function to send notification.
public String Post(string message, string regId)
{
try
{
WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key=**server-api-key**"));
tRequest.Headers.Add(string.Format("Sender: id=**sender-id**"));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message="
+ message + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + regId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
catch (Exception e)
{
throw;
}
}
Get the api key from
server key 1
and sender id from
Project number
My post function accept the message and regId which is device id.
I don't know C# and may be missing something. It looks like your post data is not in JSON format. I don't see any braces. This SO question has examples of how to post JSON-formated data.
Also, try validating your API key using curl as explained in this example.

why is my String throw error?

I want to target this string type "application/json" for urban airship api. Can you guys help me whats wrong with my string and structure?
string postData = "{"audience":"all","device_types":["android"],"notification":{"alert":"This is a broadcast."}}";
I did tried adding back slash "\" example below:
string postData = "{\"audience\":\"all\",\"device_types\":[\"android\"],\"notification\":{\"alert\":\"This is a broadcast.\"}}";
Below are my full code:
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("https://go.urbanairship.com/api/push/");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "{'audience':'all','device_types':'['android']','notification': {'alert':'This is a broadcast.'}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
//Do a http basic authentication somehow
string username = "Zx5EPSG7Qhu-BvYtz0laTg";
string password = "sIaj2CjASlm27pimHqOfhA";
string usernamePassword = username + ":" + password;
CredentialCache mycache = new CredentialCache();
mycache.Add(new Uri("https://go.urbanairship.com/api/push/"), "Basic", new NetworkCredential(username, password));
request.Credentials = mycache;
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
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();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
I got below error:
400 Bad Request – The request body was invalid, either due to malformed JSON or a data validation error. See the response body for more detail.
This should work:
{
"audience" : "all",
"device_types" : ["android"],
"notification" : {
"alert" : "This is a broadcast."
}
}
You have small type in the first value, an additional ' sign after "all":
{
"audience": "all"',
"device_types": [
"android"
],
"notification": {
"alert": "This is a broadcast."
}
}
In future, you can use online validators for such cases, like JSONLint.

HTTP 401 Error while posting XML to REST

I am trying to post a XML to REST Service. Here's the code I am using:
I am getting following error, while calling the service.
The remote server returned an error: (401) Unauthorized.
I have also tried setting NetworkCredentials directly i.e.
NetworkCredential nc = new NetworkCredential(username, password);
serviceRequest.Credentials = nc;
Thanks for your help.
Uri address = new Uri("https://localhost:30000/restservice/");
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/json";
string data = #"<Sample XML Here>";
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
string usernamePassword = username + ":" + password;
CredentialCache mycache = new CredentialCache();
mycache.Add(address, "Basic", new NetworkCredential(username, password));
request.Credentials = mycache;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
Response.Write(reader.ReadToEnd());
}
Use Fiddler and look in the WWW-Authenticate header that is returned from the server. That will tell you what kind of authentication scheme the server supports.
Couple of things to try:
Change the content type as you're not posting json to it
Not encode the data as its expecting xml, not a binary stream
Hope this helps.
try set Credentials in request like this
request.Credentials = new NetworkCredential(username, password);

Categories