ASPC C# - (500) Internal Server Error when posting JSON - json

I am trying to POST some JSON data to a remote server and read JSON response back from the remote server. My code is jumping in to the catch exception block with the error ex = {"The remote server returned an error: (500) Internal Server Error."} when it gets to this line near the bottom:
var httpResponse = (HttpWebResponse)request.GetResponse();
I have read a few posts on this forum and tried the code other suggest but I don't understand/can't get it to work.
Please can you help me understand what I am doing wrong? You can see my previous attempt which is commented out near the bottom of the code block.
using System;
using System.Text;
using System.Net;
// include
using System.IO;
using System.Web.UI.WebControls;
using HobbsDPDJSONLibrary;
using System.Web;
using Newtonsoft.Json;
namespace DPDAPILibrary
{
public class DPD_API
{
#region public class variables
private static string dpdapiun = "xxx";
private static string dpdapipw = "xxx";
private static string dpdAccountNumber = "xxx";
private static string dpdapihost = "api.dpd.co.uk";
private static string dpdapiinserttestshipment = "https://api.dpd.co.uk/shipping/shipment?test=true";
private static string dpdapiinsertshipment = "https://api.dpd.co.uk/shipping/shipment";
#endregion
/// <summary>
/// Send consignment data to the DPD API to create a shipment and return a consignment number (if successful).
/// </summary>
/// <param name="geoClientData"></param>
/// <param name="JSONData"></param>
/// <returns></returns>
public Boolean insertShipment(string geoSession, bool test, out string JSONdata)
{
try
{
// default output values
JSONdata = "";
bool returnValue = false;
#region create new insert shipment object
// a large block of code here that serialises a class into JSON, this bit works so I have omitted it to reduce the code I post on the forum
#endregion
string InsertShipmentData = JsonConvert.SerializeObject(NewShipmentObject);
// convert the 'insert shipment' JSON data to byte array for posting
//byte[] postBytes = Encoding.UTF8.GetBytes(InsertShipmentData);
// set the target uri for the insert shipment request (defaults to test, or switch to live as per input parameter)
Uri targetURI = new Uri(dpdapiinserttestshipment);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(dpdapiinserttestshipment);
if(!test)
{
targetURI = new Uri(dpdapiinsertshipment);
request = (HttpWebRequest)WebRequest.Create(dpdapiinsertshipment);
}
// add headers to the web request for inserting a new shipment
request.Host = dpdapihost;
request.ContentType = "application/json";
request.Accept = "application/json";
request.Method = "POST";
request.Timeout = 30000;
request.KeepAlive = true;
request.AllowAutoRedirect = false;
request.Headers["GEOClient"] = "thirdparty/" + dpdAccountNumber;
request.Headers["GeoSession"] = geoSession;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(InsertShipmentData);
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
//// run the request and read the response header
//using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
//{
// using (var sr = new StreamReader(response.GetResponseStream()))
// {
// JSONdata = Convert.ToString(sr.ReadToEnd());
// }
// // check if OK (status 200) returned
// if (response.StatusCode.ToString() == "OK")
// {
// returnValue = true;
// }
// else
// {
// returnValue = false;
// }
// return returnValue;
//}
return returnValue;
}
catch (Exception ex)
{
JSONdata = Convert.ToString(ex);
return false;
}
}
}
}

Related

http://localhost:3000/api/forge/designautomation/workitems 500 (Internal Server Error) jquery.min.js:2 POST

I am trying out the step by step tutorial of design-automation in Revit, to modify-your-models from learn.autodesk.io . This code worked perfectly fine even a few days back but today I am suddenly facing this error. I tried recreating the entire project sample once again as per the tutorial but this error is not going away. Can anyone explain what is causing it?
The error log:
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HM7HP2HS8PF1", Request id "0HM7HP2HS8PF1:00000002": An unhandled exception was thrown by the application.
Autodesk.Forge.Client.ApiException: Error calling UploadObject: Error while copying content to a stream. Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
at Autodesk.Forge.ObjectsApi.UploadObjectAsyncWithHttpInfo(String bucketKey, String objectName, Nullable`1 contentLength, Stream body, String contentDisposition, String ifMatch, String contentType)
at Autodesk.Forge.ObjectsApi.UploadObjectAsync(String bucketKey, String objectName, Nullable`1 contentLength, Stream body, String contentDisposition, String ifMatch, String contentType)
at forgeSample.Controllers.DesignAutomationController.StartWorkitem(StartWorkitemInput input) in E:\Test-2nd_Attempt\forgeSample\Controllers\DesignAutomationController.cs:line 275
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
DesignAutomationController.cs
using Autodesk.Forge;
using Autodesk.Forge.DesignAutomation;
using Autodesk.Forge.DesignAutomation.Model;
using Autodesk.Forge.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Activity = Autodesk.Forge.DesignAutomation.Model.Activity;
using Alias = Autodesk.Forge.DesignAutomation.Model.Alias;
using AppBundle = Autodesk.Forge.DesignAutomation.Model.AppBundle;
using Parameter = Autodesk.Forge.DesignAutomation.Model.Parameter;
using WorkItem = Autodesk.Forge.DesignAutomation.Model.WorkItem;
using WorkItemStatus = Autodesk.Forge.DesignAutomation.Model.WorkItemStatus;
namespace forgeSample.Controllers {
[ApiController]
public class DesignAutomationController: ControllerBase {
// Used to access the application folder (temp location for files & bundles)
private IWebHostEnvironment _env;
// used to access the SignalR Hub
private IHubContext < DesignAutomationHub > _hubContext;
// Local folder for bundles
public string LocalBundlesFolder {
get {
return Path.Combine(_env.WebRootPath, "bundles");
}
}
/// Prefix for AppBundles and Activities
public static string NickName {
get {
return OAuthController.GetAppSetting("FORGE_CLIENT_ID");
}
}
/// Alias for the app (e.g. DEV, STG, PROD). This value may come from an environment variable
public static string Alias {
get {
return "dev";
}
}
// Design Automation v3 API
DesignAutomationClient _designAutomation;
// Constructor, where env and hubContext are specified
public DesignAutomationController(IWebHostEnvironment env, IHubContext < DesignAutomationHub > hubContext, DesignAutomationClient api) {
_designAutomation = api;
_env = env;
_hubContext = hubContext;
}
// **********************************
//
/// <summary>
/// Names of app bundles on this project
/// </summary>
[HttpGet]
[Route("api/appbundles")]
public string[] GetLocalBundles() {
// this folder is placed under the public folder, which may expose the bundles
// but it was defined this way so it be published on most hosts easily
return Directory.GetFiles(LocalBundlesFolder, "*.zip").Select(Path.GetFileNameWithoutExtension).ToArray();
}
/// <summary>
/// Return a list of available engines
/// </summary>
[HttpGet]
[Route("api/forge/designautomation/engines")]
public async Task < List < string >> GetAvailableEngines() {
dynamic oauth = await OAuthController.GetInternalAsync();
// define Engines API
Page < string > engines = await _designAutomation.GetEnginesAsync();
engines.Data.Sort();
return engines.Data; // return list of engines
}
/// <summary>
/// Define a new appbundle
/// </summary>
[HttpPost]
[Route("api/forge/designautomation/appbundles")]
public async Task < IActionResult > CreateAppBundle([FromBody] JObject appBundleSpecs) {
// basic input validation
string zipFileName = appBundleSpecs["zipFileName"].Value < string > ();
string engineName = appBundleSpecs["engine"].Value < string > ();
// standard name for this sample
string appBundleName = zipFileName + "AppBundle";
// check if ZIP with bundle is here
string packageZipPath = Path.Combine(LocalBundlesFolder, zipFileName + ".zip");
if (!System.IO.File.Exists(packageZipPath)) throw new Exception("Appbundle not found at " + packageZipPath);
// get defined app bundles
Page < string > appBundles = await _designAutomation.GetAppBundlesAsync();
// check if app bundle is already define
dynamic newAppVersion;
string qualifiedAppBundleId = string.Format("{0}.{1}+{2}", NickName, appBundleName, Alias);
if (!appBundles.Data.Contains(qualifiedAppBundleId)) {
// create an appbundle (version 1)
AppBundle appBundleSpec = new AppBundle() {
Package = appBundleName,
Engine = engineName,
Id = appBundleName,
Description = string.Format("Description for {0}", appBundleName),
};
newAppVersion = await _designAutomation.CreateAppBundleAsync(appBundleSpec);
if (newAppVersion == null) throw new Exception("Cannot create new app");
// create alias pointing to v1
Alias aliasSpec = new Alias() {
Id = Alias, Version = 1
};
Alias newAlias = await _designAutomation.CreateAppBundleAliasAsync(appBundleName, aliasSpec);
} else {
// create new version
AppBundle appBundleSpec = new AppBundle() {
Engine = engineName,
Description = appBundleName
};
newAppVersion = await _designAutomation.CreateAppBundleVersionAsync(appBundleName, appBundleSpec);
if (newAppVersion == null) throw new Exception("Cannot create new version");
// update alias pointing to v+1
AliasPatch aliasSpec = new AliasPatch() {
Version = newAppVersion.Version
};
Alias newAlias = await _designAutomation.ModifyAppBundleAliasAsync(appBundleName, Alias, aliasSpec);
}
// upload the zip with .bundle
RestClient uploadClient = new RestClient(newAppVersion.UploadParameters.EndpointURL);
RestRequest request = new RestRequest(string.Empty, Method.POST);
request.AlwaysMultipartFormData = true;
foreach(KeyValuePair < string, string > x in newAppVersion.UploadParameters.FormData) request.AddParameter(x.Key, x.Value);
request.AddFile("file", packageZipPath);
request.AddHeader("Cache-Control", "no-cache");
await uploadClient.ExecuteAsync(request);
return Ok(new {
AppBundle = qualifiedAppBundleId, Version = newAppVersion.Version
});
}
/// <summary>
/// Helps identify the engine
/// </summary>
private dynamic EngineAttributes(string engine) {
if (engine.Contains("3dsMax")) return new {
commandLine = "$(engine.path)\\3dsmaxbatch.exe -sceneFile \"$(args[inputFile].path)\" $(settings[script].path)", extension = "max", script = "da = dotNetClass(\"Autodesk.Forge.Sample.DesignAutomation.Max.RuntimeExecute\")\nda.ModifyWindowWidthHeight()\n"
};
if (engine.Contains("AutoCAD")) return new {
commandLine = "$(engine.path)\\accoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\" /s $(settings[script].path)", extension = "dwg", script = "UpdateParam\n"
};
if (engine.Contains("Inventor")) return new {
commandLine = "$(engine.path)\\inventorcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", extension = "ipt", script = string.Empty
};
if (engine.Contains("Revit")) return new {
commandLine = "$(engine.path)\\revitcoreconsole.exe /i \"$(args[inputFile].path)\" /al \"$(appbundles[{0}].path)\"", extension = "rvt", script = string.Empty
};
throw new Exception("Invalid engine");
}
/// <summary>
/// Define a new activity
/// </summary>
[HttpPost]
[Route("api/forge/designautomation/activities")]
public async Task < IActionResult > CreateActivity([FromBody] JObject activitySpecs) {
// basic input validation
string zipFileName = activitySpecs["zipFileName"].Value < string > ();
string engineName = activitySpecs["engine"].Value < string > ();
// standard name for this sample
string appBundleName = zipFileName + "AppBundle";
string activityName = zipFileName + "Activity";
//
Page < string > activities = await _designAutomation.GetActivitiesAsync();
string qualifiedActivityId = string.Format("{0}.{1}+{2}", NickName, activityName, Alias);
if (!activities.Data.Contains(qualifiedActivityId)) {
// define the activity
// ToDo: parametrize for different engines...
dynamic engineAttributes = EngineAttributes(engineName);
string commandLine = string.Format(engineAttributes.commandLine, appBundleName);
Activity activitySpec = new Activity() {
Id = activityName,
Appbundles = new List < string > () {
string.Format("{0}.{1}+{2}", NickName, appBundleName, Alias)
},
CommandLine = new List < string > () {
commandLine
},
Engine = engineName,
Parameters = new Dictionary < string, Parameter > () {
{
"inputFile",
new Parameter() {
Description = "input file", LocalName = "$(inputFile)", Ondemand = false, Required = true, Verb = Verb.Get, Zip = false
}
}, {
"inputJson",
new Parameter() {
Description = "input json", LocalName = "params.json", Ondemand = false, Required = false, Verb = Verb.Get, Zip = false
}
}, {
"outputFile",
new Parameter() {
Description = "output file", LocalName = "outputFile." + engineAttributes.extension, Ondemand = false, Required = true, Verb = Verb.Put, Zip = false
}
}
},
Settings = new Dictionary < string, ISetting > () {
{
"script",
new StringSetting() {
Value = engineAttributes.script
}
}
}
};
Activity newActivity = await _designAutomation.CreateActivityAsync(activitySpec);
// specify the alias for this Activity
Alias aliasSpec = new Alias() {
Id = Alias, Version = 1
};
Alias newAlias = await _designAutomation.CreateActivityAliasAsync(activityName, aliasSpec);
return Ok(new {
Activity = qualifiedActivityId
});
}
// as this activity points to a AppBundle "dev" alias (which points to the last version of the bundle),
// there is no need to update it (for this sample), but this may be extended for different contexts
return Ok(new {
Activity = "Activity already defined"
});
}
/// <summary>
/// Get all Activities defined for this account
/// </summary>
[HttpGet]
[Route("api/forge/designautomation/activities")]
public async Task < List < string >> GetDefinedActivities() {
// filter list of
Page < string > activities = await _designAutomation.GetActivitiesAsync();
List < string > definedActivities = new List < string > ();
foreach(string activity in activities.Data)
if (activity.StartsWith(NickName) && activity.IndexOf("$LATEST") == -1)
definedActivities.Add(activity.Replace(NickName + ".", String.Empty));
return definedActivities;
}
/// <summary>
/// Start a new workitem
/// </summary>
[HttpPost]
[Route("api/forge/designautomation/workitems")]
public async Task < IActionResult > StartWorkitem([FromForm] StartWorkitemInput input) {
// basic input validation
JObject workItemData = JObject.Parse(input.data);
string widthParam = workItemData["width"].Value < string > ();
string heigthParam = workItemData["height"].Value < string > ();
string activityName = string.Format("{0}.{1}", NickName, workItemData["activityName"].Value < string > ());
string browerConnectionId = workItemData["browerConnectionId"].Value < string > ();
// save the file on the server
var fileSavePath = Path.Combine(_env.ContentRootPath, Path.GetFileName(input.inputFile.FileName));
using(var stream = new FileStream(fileSavePath, FileMode.Create)) await input.inputFile.CopyToAsync(stream);
// OAuth token
dynamic oauth = await OAuthController.GetInternalAsync();
// upload file to OSS Bucket
// 1. ensure bucket existis
string bucketKey = NickName.ToLower() + "-designautomation";
BucketsApi buckets = new BucketsApi();
buckets.Configuration.AccessToken = oauth.access_token;
try {
PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey, null, PostBucketsPayload.PolicyKeyEnum.Transient);
await buckets.CreateBucketAsync(bucketPayload, "US");
} catch {}; // in case bucket already exists
// 2. upload inputFile
string inputFileNameOSS = string.Format("{0}_input_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName(input.inputFile.FileName)); // avoid overriding
ObjectsApi objects = new ObjectsApi();
objects.Configuration.AccessToken = oauth.access_token;
using(StreamReader streamReader = new StreamReader(fileSavePath))
await objects.UploadObjectAsync(bucketKey, inputFileNameOSS, (int) streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
System.IO.File.Delete(fileSavePath); // delete server copy
// prepare workitem arguments
// 1. input file
XrefTreeArgument inputFileArgument = new XrefTreeArgument() {
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS),
Headers = new Dictionary < string, string > () {
{
"Authorization",
"Bearer " + oauth.access_token
}
}
};
// 2. input json
dynamic inputJson = new JObject();
inputJson.Width = widthParam;
inputJson.Height = heigthParam;
XrefTreeArgument inputJsonArgument = new XrefTreeArgument() {
Url = "data:application/json, " + ((JObject) inputJson).ToString(Formatting.None).Replace("\"", "'")
};
// 3. output file
string outputFileNameOSS = string.Format("{0}_output_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName(input.inputFile.FileName)); // avoid overriding
XrefTreeArgument outputFileArgument = new XrefTreeArgument() {
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, outputFileNameOSS),
Verb = Verb.Put,
Headers = new Dictionary < string, string > () {
{
"Authorization",
"Bearer " + oauth.access_token
}
}
};
// prepare & submit workitem
// the callback contains the connectionId (used to identify the client) and the outputFileName of this workitem
string callbackUrl = string.Format("{0}/api/forge/callback/designautomation?id={1}&outputFileName={2}", OAuthController.GetAppSetting("FORGE_WEBHOOK_URL"), browerConnectionId, outputFileNameOSS);
WorkItem workItemSpec = new WorkItem() {
ActivityId = activityName,
Arguments = new Dictionary < string, IArgument > () {
{
"inputFile",
inputFileArgument
}, {
"inputJson",
inputJsonArgument
}, {
"outputFile",
outputFileArgument
}, {
"onComplete",
new XrefTreeArgument {
Verb = Verb.Post, Url = callbackUrl
}
}
}
};
WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemAsync(workItemSpec);
return Ok(new {
WorkItemId = workItemStatus.Id
});
}
/// <summary>
/// Input for StartWorkitem
/// </summary>
public class StartWorkitemInput {
public IFormFile inputFile {
get;
set;
}
public string data {
get;
set;
}
}
/// <summary>
/// Callback from Design Automation Workitem (onProgress or onComplete)
/// </summary>
[HttpPost]
[Route("/api/forge/callback/designautomation")]
public async Task < IActionResult > OnCallback(string id, string outputFileName, [FromBody] dynamic body) {
try {
// your webhook should return immediately! we can use Hangfire to schedule a job
JObject bodyJson = JObject.Parse((string) body.ToString());
await _hubContext.Clients.Client(id).SendAsync("onComplete", bodyJson.ToString());
var client = new RestClient(bodyJson["reportUrl"].Value < string > ());
var request = new RestRequest(string.Empty);
// send the result output log to the client
byte[] bs = client.DownloadData(request);
string report = System.Text.Encoding.Default.GetString(bs);
await _hubContext.Clients.Client(id).SendAsync("onComplete", report);
// generate a signed URL to download the result file and send to the client
ObjectsApi objectsApi = new ObjectsApi();
dynamic signedUrl = await objectsApi.CreateSignedResourceAsyncWithHttpInfo(NickName.ToLower() + "-designautomation", outputFileName, new PostBucketsSigned(10), "read");
await _hubContext.Clients.Client(id).SendAsync("downloadResult", (string)(signedUrl.Data.signedUrl));
} catch {}
// ALWAYS return ok (200)
return Ok();
}
/// <summary>
/// Clear the accounts (for debugging purpouses)
/// </summary>
[HttpDelete]
[Route("api/forge/designautomation/account")]
public async Task < IActionResult > ClearAccount() {
// clear account
await _designAutomation.DeleteForgeAppAsync("me");
return Ok();
}
}
/// <summary>
/// Class uses for SignalR
/// </summary>
public class DesignAutomationHub: Microsoft.AspNetCore.SignalR.Hub {
public string GetConnectionId() {
return Context.ConnectionId;
}
}
}
This error is from a [Storage API][1]. I can imagine that it may had a temporary issue. Can you retry to see if it works now?

How to generate refresh and access token for Windows phone app

I have a windows phone 8 app and I'm trying to do Google Auth.
I get to the sign-in page and after signing in it takes me to the consent page.
After Clicking on Allow access, I am not getting the access token and refresh token in response.
Response that I am getting is as below:
{
"error" : "invalid_request",
"error_description" : "Missing header: Content-Type"
}
StatusCode is Bad Request.
Here is my Code:
private void webBrowserGooglePlusLogin_Navigating(object sender, NavigatingEventArgs e)
{
if (e.Uri.Host.Equals("localhost"))
{
webBrowserGooglePlusLogin.Visibility = Visibility.Collapsed;
e.Cancel = true;
int pos = e.Uri.Query.IndexOf("=");
code = pos > -1 ? e.Uri.Query.Substring(pos + 1) : null;
}
if (string.IsNullOrEmpty(code))
{
// OnAuthenticationFailed();
}
else
{
var request = new RestRequest(this.TokenEndPoint, Method.POST);
request.AddParameter("code", code);
request.AddParameter("client_id", this.ClientId);
request.AddParameter("client_secret", this.Secret);
request.AddParameter("redirect_uri", "http://localhost");
request.AddParameter("grant_type", "authorization_code");
//request.AddHeader("Content-type", "json");
client.ExecuteAsync<AuthResult>(request, GetAccessToken);
}
}
void GetAccessToken(IRestResponse<AuthResult> response)
{
if (response == null || response.StatusCode != HttpStatusCode.OK
|| response.Data == null || string.IsNullOrEmpty(response.Data.access_token))
{
// OnAuthenticationFailed();
}
else
{
}
}
Any help is appreciated.
The content type needs to be set
request.ContentType = "application/x-www-form-urlencoded";
This is my .net sample not sure if it all works on windows-phone but it might help
class TokenResponse
{
public string access_token { get; set; }
public string token_type { get; set; }
public string expires_in { get; set; }
public string refresh_token { get; set; }
}
/// <summary>
/// exchanges the authetncation code for the refreshtoken and access token
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public static string exchangeCode(string code)
{
string url = "https://accounts.google.com/o/oauth2/token";
string postData = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code", code, Properties.Resources.clientId, Properties.Resources.secret);
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create(url);
// Set the Method property of the request to POST.
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// 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();
TokenResponse tmp = JsonConvert.DeserializeObject<TokenResponse>(responseFromServer);
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
return tmp.refresh_token;
}
Oauth simple

How to perform POST operation on Windows Phone 8.1

I am struggling to successfully implement a POST operation within Windows Phone 8.1.
PostMessage method executes without any exceptions being caught.
However, the POST method within MessagesController never gets invoked.
How do I perform a POST for Windows Phone 8.1?
The code is below:
internal async Task PostMessage(string text)
{
Globals.MemberId = 1;
int memberId = 2;
// server to POST to
string url = #"http://localhost:17634/api/messages";
try
{
// HTTP web request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "text/plain; charset=utf-8";
httpWebRequest.Method = "POST";
// Write the request Asynchronously
using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,
httpWebRequest.EndGetRequestStream, null))
{
//create some json string
var message = new Message() { FromId = Globals.MemberId, ToId = memberId, Content = text, Timestamp = DateTime.Now };
var json = string.Format("{0}{1}", "action=", JsonConvert.SerializeObject(message));
// convert json to byte array
byte[] jsonAsBytes = Encoding.UTF8.GetBytes(json);
// Write the bytes to the stream
await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
}
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public class MessagesController : ApiController
{
public HttpResponseMessage Post(Message message)
{
throw new NotImplementedException();
}
}
public class Message
{
public int MessageId { get; set; }
public int FromId { get; set; }
public int ToId { get; set; }
public DateTime Timestamp { get; set; }
public string Content { get; set; }
}
The following link resolved my issue.
The updated client is as follows:
using (var client = new System.Net.Http.HttpClient())
{
// New code:
client.BaseAddress = new Uri(Globals.URL_PREFIX);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var message = new Message() { MessageId = 0, FromId = Globals.MemberId, ToId = memberId, Content = text, Timestamp = DateTime.Now };
var json_object = JsonConvert.SerializeObject(message);
var response = await client.PostAsync("api/messages", new StringContent(json_object.ToString(), Encoding.UTF8, "application/json"));
Debug.Assert(response.StatusCode == System.Net.HttpStatusCode.Accepted);
}
This works fine for me. The function accepts an payload of type T. The server accepts a JSON object and returns a JSON response.
public async static Task SendRequestPacket<T>(object payload)
{
Uri theUri = new Uri("the_uri");
//Create an Http client and set the headers we want
HttpClient aClient = new HttpClient();
aClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
aClient.DefaultRequestHeaders.Host = theUri.Host;
//Create a Json Serializer for our type
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(T));
// use the serializer to write the object to a MemoryStream
MemoryStream ms = new MemoryStream();
jsonSer.WriteObject(ms, payload);
ms.Position = 0;
//use a Stream reader to construct the StringContent (Json)
StreamReader sr = new StreamReader(ms);
StringContent theContent = new StringContent(sr.ReadToEnd(), Encoding.UTF8, "application/json");
//Post the data
HttpResponseMessage aResponse = await aClient.PostAsync(theUri, theContent);
if (aResponse.IsSuccessStatusCode)
{
string content = await aResponse.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(content);
}
else
{
// show the response status code
}
}
Just dont use HttpWebRequest if you are not forced to in any way.
This example is using HttpClient() and it is good to always have the client created once and not every time you make a request.
So in your class add:
private static HttpClient _client;
public static Uri ServerBaseUri
{
get { return new Uri("http://localhost:17634/api"); }
}
public ClassConstructor()
{
_client = new HttpClient();
}
internal async Task<ResponseType> PostMessage(string text)
{
Globals.MemberId = 1;
int memberId = 2;
try
{
var js = "{ JSON_OBJECT }";
var json = new StringContent(js);
json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await Client.PostAsync(new Uri(ServerBaseUri, "/messages"), json);
var reply = await response.Content.ReadAsStringAsync();
} catch (Exception)
{
return null;
}
}
More on HttpClient.

How to access Soundcloud JSON data

I'm experimenting with the soundcloud API and try to extract all playlist titles from my JSON object, to make a list with references. Actually I don't have many experience with JSON and therefore I just can't manage to call any variable form the decoded JSON array...
http://api.soundcloud.com/users/55607614/playlists.json?client_id=YOUR_CLIENT_ID
I already did take a look on the structure via http://jsonviewer.stack.hu/ but it didn't really help me out...
$json = json_decode(file_get_contents("http://api.soundcloud.com/users/55607614/playlists.json?client_id=YOUR_CLIENT_ID"));
echo $json[??][??]...;
Any ideas? Thanks!
private SCPlaylistObject playListObject, plTestObject;
public string TrackList;
private List<SCTrackObjects> TListTest;
/// <summary>
/// Deserializes JSON data into object from string
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonString"></param>
/// <returns>json object</returns>
public static T Deserialize<T>(string jsonString)
{
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
MemoryStream MemStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));
T result = (T)deserializer.ReadObject(MemStream);
return result;
}
public async Task<string> GetUserTracks() // Async Call to get user id
{
try
{
responseText = await GetjsonStream();
SCUserID = userObject.id;
TrackList = await GetTracks();
TList = Deserialize<List<SCTrackObjects>>(TrackList);
return TrackList;
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
return ex.Message;
}
public async Task<string> GetTracks() //Function to read from given url
{
HttpClient client = new HttpClient();
string url = SCLink + SCAPIUsers + SCUserID + "/tracks?client_id=" + soundcloudAPI;
HttpResponseMessage response = await client.GetAsync(url);
HttpResponseMessage v = new HttpResponseMessage();
return await response.Content.ReadAsStringAsync();
}
}
public async Task<string> GetjsonStream() //Function to read from given url
{
HttpClient client = new HttpClient();
string url = SCLink + SCAPIUsers + SCNameField + ".json?client_id=" + soundcloudAPI;
HttpResponseMessage response = await client.GetAsync(url);
HttpResponseMessage v = new HttpResponseMessage();
return await response.Content.ReadAsStringAsync();
}

passing values to url using http get

i need to pass 2 string json parameters to a url and i need to get the json response. how can i pass parameters in get method. Here is my code
public void get()
{
HttpConnection con = null;
String url = "my url";
try
{
URLEncodedPostData data = new URLEncodedPostData("UTF-8", false);
data.append("method", "session.getToken");
data.append("phonenumber:=", "1212345687");
data.append("PIN:=", "1234");
url = url + data.toString();
con = (HttpConnection)Connector.open(url);
con.setRequestMethod(HttpConnection.GET);
res = con.getResponseMessage();
res1 = Integer.toString(con.getResponseCode());
screen.add(new RichTextField("Reponce Message: "+res));
screen.add(new RichTextField("Reponce Code: "+res1));
}
catch(Exception ex)
{
screen.add(new RichTextField(""+ex));
}
}
Depending on your server-side language, you can pass the json parameters by adding parameter as a string e.g
For passing parameters to a PHP server-side
String url = "http://www.test.com/test.php?";
url += "method=" + session.getToken;
url += "&phonenumber:=1212345687";
url += "&PIN:=1234";
For your response.. try this
public void get()
{
HttpConnection connection = null;
String results;
byte responseData[] = null;
try {
connection = (HttpConnection) new
ConnectionFactory().getConnection(URL).getConnection();
int len = (int) connection.getLength();
responseData = new byte[len];
DataInputStream dis;
dis = new DataInputStream(connection.openInputStream());
dis.readFully(responseData);
results = new String(responseData);
screen.add(new RichTextField("Reponce Message: "+results));
} catch (Exception e) {
// TODO Handle exception
screen.add(new RichTextField(""+e));
}
}