How to send a POST in UWP c# - c#

I need to send a POST method but it says invalid JSON content, do somebody knows what im doing wrong in the JSON format ¿?, ill apreciate a lot.
Uri resourceAddress;
if (!Helpers.TryGetUri(pcHost + pcPort + "/api/code/scan", out resourceAddress))
{
rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);
return;
}
try
{
terminalRef = "1";
//code = "Uc0E17G4nW";
IHttpContent jsonContent = new HttpJsonContent(JsonValue.Parse("{\"code\":\"" + code +
",\"ref\" : \""+ terminalRef +
"\"}"));
HttpResponseMessage response = await httpClient.PostAsync(resourceAddress, jsonContent).AsTask(cts.Token);
Debug.WriteLine(".");
//await Helpers.DisplayTextResultAsync(response, cts.Token);
rootPage.NotifyUser("Completed", NotifyType.StatusMessage);
}
catch (Exception ex)
{
rootPage.NotifyUser("Error: " + ex.Message, NotifyType.ErrorMessage);
String errorMessage = ex.Message.ToString();
}

Noted that your string is not correctly formatted. Can you try the parsing below string,
"{\"code\" : \"" + code + "\", \"ref\" : \"" + terminalRef + "\"}"

The first way was as the Jaliya Udagedara's suggestion, you would need to check your json string's format to make sure that it's correct.
Another a simple way is using the Newtownsoft.Json to convert a c# object.
For example:
string jsonstring = JsonConvert.SerializeObject(new {code="code", Ref = "terminalRef" });
IHttpContent jsonContent = new HttpStringContent(jsonstring, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(resourceAddress, jsonContent).AsTask(cts.Token);

After multiple failures i found how to make it works ( at least for me) hope it can help people working with Windows 10 iot in Universal Windows Platform (UWP) i know how difficult can be to fin proper documentation.
Uri resourceAddress;
if (!Helpers.TryGetUri(Host + Port + "/XXX/YYY/directory", out resourceAddress))
{
return;
}
IHttpContent jsonContentCoordinates = new HttpJsonContent(JsonValue.Parse("{\"zzz\": \"" + something
+ "\", \"xxx\": \"" + somethingXXX
+ "\",\"yyy\": \"" + somethingYYY
+ "\" }"));
HttpResponseMessage httpResponseCoordinates = new HttpResponseMessage();
string httpResponseBodyCoordinates = "";
try
{
httpResponseCoordinates = await httpClient.PostAsync(resourceAddress, jsonContentCoordinates).AsTask(cts.Token);
httpResponseBodyCoordinates = await httpResponseCoordinates.Content.ReadAsStringAsync();
httpResponseCoordinates.EnsureSuccessStatusCode();
FlagInternetNotConnected = false;
}
catch (Exception)
{
//Catch it if it fails.
}

Related

Retrieve PHP data on separate text block in window Phone 8.1

$query = "SELECT * FROM user";
$result = sqli_query($con,$query);
while(cvt=sqli_fetch_assoc($result))
{
echo $cvt['name'];
echo $cvt['age'];
echo $cvt['blood_group'];
echo ",";
}
PHP file which show information about user. It works correctly.
This is my Windows Phone 8.1 C# function which retrieves this data from PHP file.
public async void sndandrec(string feedingaddress, HttpResponseMessage response, TextBlock tblock, HttpClient myhttpClient, int work)
{
try
{
response = await myhttpClient.GetAsync(resourceUri);
response.EnsureSuccessStatusCode();
responseText = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
// Need to convert int HResult to hex string
tblock.Text = "Error = " + ex.HResult.ToString("X") +
" Message: " + ex.Message;
responseText = "";
}
tblock.Text = response.StatusCode + " " + response.ReasonPhrase;
tblock.Text = responseText.ToString();
}
This function also works correctly. It show the response from PHP file in tblock.Text.
The problem is that all the text are show in one text block. Is there a way to show the name,age and block group in separate text block.
The response from the above file is
adam23B+,david30AB+ .......
I want to separate them like
Nametexbock:adma
Agetextblock:23
BlockGptextblock:B+
I recommend you to use json_encode to pass data from one application to another
Replace this code
while(cvt=sqli_fetch_assoc($result)){
echo $cvt['name'];
echo $cvt['age'];
echo $cvt['blood_group'];
echo ",";
}
with
while(cvt=sqli_fetch_assoc($result)){
$d[] = array('Nametexbock'=>$cvt['name'],'Agetextblock'=>$cvt['age'],'BlockGptextblock'=>$cvt['blood_group'])
}
echo json_encode($d);

Why mozilla changes the characters when i use the .net mvc statement redirect?

I'm trying to redirect to an external website when everything is done, but firefox changes the http word on the url for a weird set of characters. This is my server side code:
[HttpPost]
public ActionResult Postular(INFO_BASE_POSTULACION_model pInfoPostulacion) {
string rutMD5 = Request["rutMD5"];
int idRegion = Convert.ToInt32(Request["idRegion"]);
int idInstrumento = Convert.ToInt32(Request["idInstrumento"]);
string urlDestino = "";
try
{
#region VALIDACION DE DATOS
if (!ModelState.IsValid) {
TempData["ModelState"] = ModelState;
return RedirectToAction("Index", new { data = Utilidades.Base64Encode(rutMD5 + ";" + idRegion + ";" + idInstrumento) });
}
#endregion
INFO_BASE_POSTULACION nuevaInfoBasePostulacion = new INFO_BASE_POSTULACION();
nuevaInfoBasePostulacion = pInfoPostulacion.modeloToDTO(pInfoPostulacion);
nuevaInfoBasePostulacion.TOKEN = Utilidades.GenerarStringUnico();
nuevaInfoBasePostulacion.INFO_REGISTRO_ELIMINADO = false;
nuevaInfoBasePostulacion.FECHA_CREACION = DateTime.Now;
Boolean todoOK = new InfoBasePostulacionBO().Agregar(nuevaInfoBasePostulacion);
if (!todoOK)
{
ModelState.AddModelError(String.Empty, "Ocurrió un error al intentar guardar la información.");
TempData["ModelState"] = ModelState;
return RedirectToAction("Index", new { data = Utilidades.Base64Encode(rutMD5 + ";" + idRegion + ";" + idInstrumento) });
}
string token = nuevaInfoBasePostulacion.TOKEN;
string idFormulario = Convert.ToString(nuevaInfoBasePostulacion.ID_FORMULARIO_POSTULACION);
string nombreParamToken = ConfigurationManager.AppSettings["ProActiveOffice-paramNombre-Token"];
string nombreParamIdFormulario = ConfigurationManager.AppSettings["ProActiveOffice-paramNombre-IdFormulario"];
urlDestino = ConfigurationManager.AppSettings["ProActiveOffice-URL"] + "?" + nombreParamToken + "=" + token + "&" + nombreParamIdFormulario + "=" + idFormulario;
//Here i had yo use the uriBuilder because i couldn't make it work on any other way.
UriBuilder uri = new UriBuilder(urlDestino.Trim());
//Here i redirect to an external website.
return Redirect(uri.Uri.ToString());
}
catch (Exception ex)
{
log.Error("Error al intentar guardar info base de postulación", ex);
ModelState.AddModelError(String.Empty, "Ocurrió un error al intentar guardar la información.");
TempData["ModelState"] = ModelState;
return RedirectToAction("Index", new { data = Utilidades.Base64Encode(rutMD5 + ";" + idRegion + ";" + idInstrumento) });
}
}
Here you can see the debug:
1-Here you can see the url string that i have (i had to remove the "http://" because it wasn't working correctly with the uri builder):
2-Here you see the value of the uri builder with the string url in it:
3-Here you see the toString() method apply to the uri (I have already use the absolute uri property):
4-And now finally the error. The http word has been change for a set of characters:
I have had lots of problems with the redirection. These code is currently working on Chrome, but on firefox gives me these error.
What could it be ?
By the way i am using visual studio 2013 + .NET Framerowk 4.5 + MVC4
%E2%80%8B is a URL-encoded, UTF-8 encoded ZERO-WIDTH SPACE character. You likely have one hiding in your application setting file for the ProActiveOffice-URL value. It was maybe pasted in that way, if you copied the URL from somewhere.

web client PUT method in MVC

I am trying to do PUT method for API service
Here is the code:
WebClient box = new WebClient();
var uuid = "40922d72-57dd-4fa6-bd64-f406f444dbb6";
if (HttpContext.Current.Session["JSESSIONCOOKIE"] != null)
{
}
else
{
return null;
}
box.Headers["Cookie"] = HttpContext.Current.Session["JSESSIONCOOKIE"].ToString();
string sampleJson = "{" + "autoPresetTimes" + ":" + "{" + "0" + ":" + "Night" + "}}".ToString();
string json = new JavaScriptSerializer().Serialize(sampleJson);
Uri uri = new Uri("https://my.zipato.com:443/zipato-web/v2/thermostats/" + uuid + "/config");
box.UploadString(uri, "PUT", json);
My problem is that this above gives me error 500 from server. I think because i dont send my body like this:
{"autoPresetTimes": {
"0": "Night"
}
}
On API page it says Parameter content type: application/json so i guess i should send my response o look like this above.
Any thoughts on this?
The json that you are creating looks incorrect. You need to put your keys within double quotes.
string json =
"{" + "\"autoPresetTimes\"" + ":" + "{" + "\"0\"" + ":" + "\"Night\"" + "}}";
Uri uri =
new Uri("https://my.zipato.com:443/zipato-web/v2/thermostats/" + uuid + "/config");
box.UploadString(uri, "PUT", json);
Note: You do not need to specify port 443 in your url. The default port for https is 443

How can I structure a try/catch with a variable definition

Writing in C# and I'm getting JSONReaderExceptions here:
var container = JsonConvert.DeserializeObject<HistoryResponseContainer> (responseData);
It's always something like a unterminated line or unrecognized character.
I know I need to catch and throw these errors, but it breaks if I try and define "container" inside a try/catch statement. Here's the whole method.
foreach (String StationID in StationIDList) {
string url = #"http://api.wunderground.com/api/" + wundergroundkey + "/history_" + Date + "/q/pws:" + StationID + ".json";
Uri uri = new Uri (url);
WebRequest webRequest = WebRequest.Create (uri);
WebResponse response = webRequest.GetResponse ();
StreamReader streamReader = new StreamReader (response.GetResponseStream ());
String responseData = streamReader.ReadToEnd ();
var container = JsonConvert.DeserializeObject<HistoryResponseContainer> (responseData);
foreach (var observation in container.history.observations) {
CurrentData.Write (StationID + " ");
// This makes easier access to the date. not perfect, but better.
DateTime date = observation.date.Value;
DateTime utc = observation.utcdate.Value;
// whatever you want to do with each observation
if (date.Minute == 0 || date.Minute % 5 == 0) {
CurrentData.Write (date.Hour + ":" + date.Minute + " " + observation.wdird + " " + observation.wspdi);
}//end if
CurrentData.Write ("\n");
} //End foreach observation
} //end foreach station
Put your second foreach loop inside try (because you're using your "container"). Otherwise it won't be defined if an exception is raised and you only "try/catch" your container instanciation:
foreach (String StationID in StationIDList)
{
string url = #"http://api.wunderground.com/api/" + wundergroundkey + "/history_" + Date + "/q/pws:" + StationID + ".json";
Uri uri = new Uri (url);
WebRequest webRequest = WebRequest.Create (uri);
WebResponse response = webRequest.GetResponse ();
StreamReader streamReader = new StreamReader (response.GetResponseStream ());
String responseData = streamReader.ReadToEnd ();
try
{
var container = JsonConvert.DeserializeObject<HistoryResponseContainer> (responseData);
foreach (var observation in container.history.observations)
{
CurrentData.Write (StationID + " ");
DateTime date = observation.date.Value;
DateTime utc = observation.utcdate.Value;
if (date.Minute == 0 || date.Minute % 5 == 0)
{
CurrentData.Write (date.Hour + ":" + date.Minute + " " + observation.wdird + " " + observation.wspdi);
}
CurrentData.Write ("\n");
}
}
catch(JsonReaderException ex)
{
// ...
}
}
I know I need to catch and throw these errors,
No you need just catch and handle these errors.
but it pukes if I try and define "container" inside a try/catch statement.
What do you mean here ? You need this:
try
{
// your code that throws exception
}
catch(JsonReaderException ex)
{
// handle your exception
}

Twitter POST problems using api 1.1

We've just changed to Twitter api 1.1, and now Tweeting doesn't work & returns an error "The remote server returned an error: (400) Bad Request." Researching on SO about this suggests that it's something to do with authentication, but we are sending the accessToken & secret which we've just got from the login page. It all worked fine with api 1.0. The code is -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.Append("POST&");
sb.Append(Uri.EscapeDataString(_postUrl));
sb.Append("&");
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
string timeStamp = MakeTimestamp();
var dict = new SortedDictionary<string, string>
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", timeStamp },
{ "oauth_token", _accessToken },
{ "oauth_version", "1.0" },
};
foreach (var keyValuePair in dict)
{
sb.Append(Uri.EscapeDataString(string.Format("{0}={1}&", keyValuePair.Key, keyValuePair.Value)));
}
string encodedMessage = EscapeAdditionalChars(Uri.EscapeDataString(message));
sb.Append(Uri.EscapeDataString("status=" + encodedMessage));
string signatureBaseString = sb.ToString();
// create the signature
string signatureKey = Uri.EscapeDataString(_oAuthConfig.ConsumerSecret) + "&" + Uri.EscapeDataString(_accessTokenSecret);
var hmacsha1 = new HMACSHA1(new ASCIIEncoding().GetBytes(signatureKey));
string signatureString = Convert.ToBase64String(hmacsha1.ComputeHash(new ASCIIEncoding().GetBytes(signatureBaseString)));
// create the headers
string authorizationHeaderParams = String.Empty;
authorizationHeaderParams += "OAuth ";
authorizationHeaderParams += "oauth_consumer_key=\"" + _oAuthConfig.ConsumerKey + "\", ";
authorizationHeaderParams += "oauth_nonce=\"" + oauthNonce + "\", ";
authorizationHeaderParams += "oauth_signature=\"" + Uri.EscapeDataString(signatureString) + "\", ";
authorizationHeaderParams += "oauth_signature_method=\"" + "HMAC-SHA1" + "\", ";
authorizationHeaderParams += "oauth_timestamp=\"" + timeStamp + "\", ";
authorizationHeaderParams += "oauth_token=\"" + _accessToken + "\", ";
authorizationHeaderParams += "oauth_version=\"" + "1.0" + "\"";
string messageToPost = EscapeAdditionalChars(SpacesToPlusSigns(message));
// initialise the WebClient
WebClient client = new WebClient();
client.Headers [HttpRequestHeader.Authorization] = authorizationHeaderParams;
client.UploadDataCompleted += (s, eArgs) =>
{
if (eArgs.Error == null)
response(DefaultSuccessMessage());
else
response(eArgs.Error.Message);
};
try
{
Uri uri = new Uri(_postUrl);
try
{
client.UploadDataAsync(uri, "POST", Encoding.UTF8.GetBytes("status=" + messageToPost));
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
Basically, I'd like to be able to Tweet without using any 3rd party libraries such as Twitterizer (even TweetStation seems to be broken with api 1.1) - surely it can't be that difficult!
Any help much appreciated, as it feels a bit like a brick wall at the moment - I'm also fairly new to c#, which doesn't help...
Edited to show code which wasn't clear previously.
Finally found the solution, as usual with most of these things, it was pretty simple. Code below -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat ("status={0}", PercentEncode(message));
string content = sb.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_postUrl);
request.Headers.Add("Authorization", AuthorizeRequest(_accessToken, _accessTokenSecret, "POST", new Uri(_postUrl), content));
request.ContentType = "application/x-www-form-urlencoded";
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
try
{
try
{
using (Stream stream = request.GetRequestStream())
{
Byte[] streamContent = Encoding.UTF8.GetBytes("status=" + PercentEncode(message));
stream.Write(streamContent, 0, streamContent.Length);
}
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
string contents = "";
using (Stream stream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
contents = reader.ReadToEnd();
}
Console.WriteLine("Twitter response: " + contents);
response(DefaultSuccessMessage());
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
private string AuthorizeRequest(string oauthToken, string oauthTokenSecret, string method, Uri uri, string data)
{
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var headers = new Dictionary<string, string>()
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", MakeTimestamp() },
{ "oauth_token", oauthToken },
{ "oauth_verifier", PercentEncode(_authorizationVerifier) },
{ "oauth_version", "1.0A" }
};
var signatureHeaders = new Dictionary<string,string>(headers);
// Add the data and URL query string to the copy of the headers for computing the signature
if (data != null && data != "")
{
var parsed = HttpUtility.ParseQueryString(data);
foreach (string k in parsed.Keys)
{
signatureHeaders.Add(k, PercentEncode(parsed [k]));
}
}
var nvc = HttpUtility.ParseQueryString(uri.Query);
foreach (string key in nvc)
{
if (key != null)
signatureHeaders.Add(key, PercentEncode(nvc [key]));
}
string signature = MakeSignature (method, uri.GetLeftPart(UriPartial.Path), signatureHeaders);
string compositeSigningKey = MakeSigningKey(_oAuthConfig.ConsumerSecret, oauthTokenSecret);
string oauth_signature = MakeOAuthSignature(compositeSigningKey, signature);
headers.Add ("oauth_signature", PercentEncode(oauth_signature));
return HeadersToOAuth(headers);
}
private static string PercentEncode (string s)
{
var sb = new StringBuilder ();
foreach (byte c in Encoding.UTF8.GetBytes (s))
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~')
sb.Append ((char) c);
else
{
sb.AppendFormat ("%{0:X2}", c);
}
}
return sb.ToString ();
}
private static string MakeTimestamp ()
{
return ((long) (DateTime.UtcNow - _unixBaseTime).TotalSeconds).ToString ();
}
private static string MakeSignature (string method, string base_uri, Dictionary<string,string> headers)
{
var items = from k in headers.Keys orderby k
select k + "%3D" + PercentEncode (headers [k]);
return method + "&" + PercentEncode (base_uri) + "&" +
string.Join ("%26", items.ToArray ());
}
private static string MakeSigningKey (string consumerSecret, string oauthTokenSecret)
{
return PercentEncode (consumerSecret) + "&" + (oauthTokenSecret != null ? PercentEncode (oauthTokenSecret) : "");
}
private static string MakeOAuthSignature (string compositeSigningKey, string signatureBase)
{
var sha1 = new HMACSHA1 (Encoding.UTF8.GetBytes (compositeSigningKey));
return Convert.ToBase64String (sha1.ComputeHash (Encoding.UTF8.GetBytes (signatureBase)));
}
private static string HeadersToOAuth (Dictionary<string,string> headers)
{
return "OAuth " + String.Join (",", (from x in headers.Keys select String.Format ("{0}=\"{1}\"", x, headers [x])).ToArray ());
}
With Twitter api 1.0, I used a WebClient to post, that doesn't work with api 1.1, and it seems that the reason for this is that you can't set the ContentType or the ServicePoint.Expect100Continue properties - without these set as I've set them, the request is sent back as (401) unauthorized. Nothing to do with encoding problems in the end.
Thanks to others for the various helper methods.
I had exactly the same problem:
This is exactly what you need to do here:
Authenticate and request a user's timeline with Twitter API 1.1 oAuth
I have created a project for this at : https://github.com/andyhutch77/oAuthTwitterTimeline
It also includes an MVC, Web app and console demo.
I ran into this problem, or at least one striking similiar (from my noob perspective), recently for an app I am building. What seemed to solve it for me (after looking at the tool at dev.twitter.com) was simply to get rid of the quotes around the parameter names, so that (in your case):
I notice that you do in fact not have quotes around your parameter names. However, it confuses me that you send authentication details twice (hence my wrongheaded post.) It works for me without doing this, and I googled it briefly and found: https://dev.twitter.com/discussions/12322#comment-27120, which confirms this can be a problem generating an Authetication Error.
400 means you are not authenticated. I recommend getting user context.
https://dev.twitter.com/docs/auth/oauth#user-context

Categories