While uploading tracks to soundcloud(422) Unprocessable Entity) - c#

I would like to try upload a mp3 file to my soundcloud account. I have written this code for this job.
WebClient client = new WebClient();
string postData = "client_id=" + "xxxxx"
+ "&client_secret=" + "xxx"
+ "&grant_type=password&username=" + "xxx" //your username
+ "&password=" + "xxx";//your password :)
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
string tokenInfo = client.UploadString(soundCloudTokenRes, postData);
tokenInfo = tokenInfo.Remove(0, tokenInfo.IndexOf("token\":\"") + 8);
string token = tokenInfo.Remove(tokenInfo.IndexOf("\""));
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks") as HttpWebRequest;
request.CookieContainer = new CookieContainer();
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] { new UploadFile(filePath, "#/" + filePath, "application/octet-stream") };
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "biksad");
form.Add("track[sharing]", "public");
form.Add("oauth_token", token);
form.Add("format", "json");
form.Add("Filename", fileName);
form.Add("Upload", "Submit Query");
string lblInfo;
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
lblInfo = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
lblInfo = ex.ToString();
}
}
When I debug this code part. I get (422) Unprocessable Entity error in catch block. Why I get this error? How can solve this problem?

Check the Soundcloud documentation:
http://developers.soundcloud.com/docs#errors
422 - "The request looks alright, but one or more of the parameters looks a little screwy. It's possible that you sent data in the wrong format (e.g. an array where we expected a string)."

Related

Invalid Client Authorization header when trying to get token from "Here" REST API

I am trying to get a Bearer token to start using HERE REST API,
using (OAuth 2.0 (JSON Web Tokens))
after a lot of struggles, I am stuck with 401202 error:
{"errorId":"ERROR-e0242f30-05da-4df0-9beb-b697062240ce","httpStatus":401,"errorCode":401202,"message":"Invalid
Client Authorization header, expecting signed request
format.","error":"invalid_request","error_description":"errorCode:
'401202'. Invalid Client Authorization header, expecting signed
request format."}
Here is my code:
private void GetToken()
{
try
{
var here_client_id = "b1Ibl7XXXXXXXoZtNKb";
var here_access_key_id = "8DKjlwXXXXXXXXXerGCXPA";
var here_access_key_secret = "tuU-bGMa1ljancfoXXXXXXXXXXXXXXXK8cMlk4o0EGUpS2fmwkAtlltFPDhYQUgytJLL-X_YNIjmdWcOabQ";
var url = "https://account.api.here.com/oauth2/token";
var Parameters = "grant_type=client_credentials&client_id=" + here_client_id + "&oauth_consumer_key=" + here_access_key_secret;
var hmac = new HMACSHA256();
var key = Convert.ToBase64String(hmac.Key);
Guid id = Guid.NewGuid();
// Create a request for the URL.
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var cred = #"OAuth oauth_consumer_key=" + here_access_key_id;
request.Headers.Add("Authorization", cred);
//request.Headers.Add("oauth_consumer_key", here_access_key_id);
request.Headers.Add("oauth_nonce", id.ToString());
request.Headers.Add("oauth_signature_method", "HMAC-SHA256");
request.Headers.Add("oauth_signature", key);
request.Headers.Add("oauth_timestamp", ConvertToUnixTimestamp(DateTime.Now).ToString());
request.Headers.Add("oauth_version", "1.0");
byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
request.ContentLength = byteArray.Length;
Stream postStream = request.GetRequestStream();
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Display the status.
Console.WriteLine(response.StatusDescription);
// Get the stream containing content returned by the server.
Stream 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.
MessageBox.Show(responseFromServer);
// Cleanup the streams and the response.
reader.Close();
dataStream.Close();
response.Close();
}
catch (WebException ex)
{
using (var stream = ex.Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
//MessageBox.Show(reader.ReadToEnd());
textBox1.Text = reader.ReadToEnd();
}
}
}
This is my first cut and is rough but.
var accessKey = "";
var secret = "";
var url = "https://account.api.here.com/oauth2/token";
var nonce = GetNonce();
var timestamp = GetTimeStamp();
var baseString = #"grant_type=client_credentials&oauth_consumer_key=" + accessKey + "&oauth_nonce=" + nonce + "&oauth_signature_method=HMAC-SHA256&oauth_timestamp=" + timestamp + "&oauth_version=1.0";
var workingString = new List<string>();
foreach (var parameter in baseString.Split('&').ToList())
{
workingString.Add(Uri.EscapeDataString(parameter.Split('=')[0] + "=" + parameter.Split('=')[1].Trim()));
}
var urlEncodeParamaterString = String.Join(Uri.EscapeDataString("&"), workingString.ToArray());
var fullBaseString = $"POST&{Uri.EscapeDataString(url)}&{urlEncodeParamaterString}";
var signature = CreateToken(fullBaseString, (Uri.EscapeDataString(secret) + "&"));
var authHeader = "OAuth oauth_consumer_key=\"" + accessKey + "\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"" + timestamp + "\",oauth_nonce=\"" + nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" + Uri.EscapeDataString(signature) + "\"";
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Authorization", authHeader);
var response = await httpClient.PostAsync(url, new StringContent($"grant_type={Uri.EscapeDataString("client_credentials")}",
Encoding.UTF8,
"application/x-www-form-urlencoded"));
var responseContent = response.Content.ReadAsStringAsync();
}
The other Methods are
private string GetNonce()
{
var rand = new Random();
var nonce = rand.Next(1000000000);
return nonce.ToString();
}
private string CreateToken(string message, string secret)
{
secret = secret ?? "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
private string GetTimeStamp()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
At the end I did it without web JSON WEB TOKENS.
According to this API documentation the call was made only with API KEY.
public static string ConvertAddressToCoordinate(string address)
{
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
var apikey = "xxxxxxxxxxxxxxxxxxxxx_xxxxxxxxx";
var url = "https://geocoder.ls.hereapi.com/6.2/geocode.json?apiKey=";
var fullurl = url + apikey + "&searchtext=" + address;
// Create a request for the URL.
WebRequest request = WebRequest.Create(fullurl);
request.Method = "GET";
request.ContentType = "application/json";
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Display the status.
Console.WriteLine(response.StatusDescription);
// Get the stream containing content returned by the server.
Stream 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.
return responseFromServer;
}
catch (WebException ex)
{
return "ERROR " + ex.Message;
}
catch (Exception ex)
{
return "ERROR " + ex.Message;
}
}

The remote server returned an error: (401) Unauthorized when requesting RestApi data

I am triyng to get data from the Rest API. API wants 3 things to give authentication;
first one is "Accept:application/vnd.###.v1.0+json"
second one : "Content Type : application/json"
third one : Base64 encoded "userName:password" string
and I should pass these credentials for validation and authorization in custom header.I know there are a lot of thread on this site about this topic but I couldn't solve the problem from them.
Here is the code block :
public class McAfeeIPSManager
{
String URL = "https://serviceOfApi/sdkapi/session";
public void getWebRequest()
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
String username = "user";
String password = "password1";
var request = HttpWebRequest.Create(URL) as HttpWebRequest;
request.Accept = "application/vnd.###.v2.0+json";
request.Method = "GET";
request.ContentType = "application/json";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization","Basic "+encoded);
try
{
// Get response
using (var response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
using (var responseReader = new StreamReader(response.GetResponseStream()))
{
string responseBody = responseReader.ReadToEnd();
// Console application output
System.Diagnostics.Debug.Write("Response Body ---> " + responseBody);
//Console.WriteLine(responseBody);
}
}
}
catch (WebException ex)
{
System.Diagnostics.Debug.Write("Error : " + ex.Message);
Console.WriteLine("Error: {0}", ex.Message);
}
}
}
How can get data from WebAPI under these conditions?Can anybody help me?
You have no PreAuthenticate and credential ?
I have a code that may help you:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://pwmaffr2:8443/remote/system.delete?names=" + DeviceName + "");
request.Headers.Add("AUTHORIZATION", "Basic YTph");
request.ContentType = "text/html";
request.Credentials = new NetworkCredential(Username, Password);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
request.PreAuthenticate = true;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
);
StreamReader stream = new StreamReader(response.GetResponseStream());
string X = stream.ReadToEnd();
hmm in addition of what i post try deal with this it should work for you hope:
string credentials = String.Format("{0}:{1}", username, password);
byte[] bytes = Encoding.ASCII.GetBytes(credentials);
string base64 = Convert.ToBase64String(bytes);
string authorization = String.Concat("basic ", base64);
request.Headers.Add("Authorization", authorization);

How to handle the 401 Error response using C#?

I have a API which returns the json response.
When I call the API from Fiddler it gives me the json reponse
as shown below:
JSON Response:
Call to API from Web page:
protected void FinalCall()
{
// try
// {
string url = txtdomainURL.Text.Trim();
string apiname = txtAPIname.Text.Trim();
string apiURL = apiname+"/"+txtStoreID.Text.Trim()+"/"+txtSerialNo.Text.Trim(); //"duediligence/1/45523354232323424";// 990000552672620";//45523354232323424";
//duediligence/1/45523354232323424 HTTP/1.1
string storeID = txtStoreID.Text.Trim();//Test Store ID:1 Live Store ID: 2
string partnerID = txtPartnerID.Text.Trim();// "1";
string scretKey = txtSecretKey.Text.Trim();// "234623ger787qws3423";
string requestBody = txtRequestBody.Text.Trim(); //"{\"category\": 8}";
string data = scretKey + requestBody;
string signatureHash = SHA1HashStringForUTF8String(data);
lblSignatureHash.Text = signatureHash;
String userName = partnerID;
String passWord = signatureHash;
string credentials = userName + ":" + passWord;//Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord));
var dataString = JsonConvert.SerializeObject(requestBody); //JsonConvert.SerializeObject(requestBody);
var bytes = Encoding.Default.GetBytes(dataString);
WebClient client = new WebClient();
string base64 = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
client.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
lblBase64.Text = base64;
client.Headers.Add(HttpRequestHeader.Accept, "application/json");
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
//string response = cli.UploadString(url + apiURL, dataString); //"{some:\"json data\"}"
string completeURLRequest = url + apiURL;
//I GET ERROR HERE
var result = client.DownloadString(completeURLRequest);
//CODE below this line is not executed
//Context.Response.TrySkipIisCustomErrors = true;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var jsonObject = serializer.DeserializeObject(result.ToString());
//var result1 = client.UploadData(completeURLRequest, "POST", bytes);
Response.Write(result);
txtwebresponse.Text = jsonObject.ToString();
//}
Now, When the same is executed from a web page it throws exeception '401 Unauthorized Exception'. So, instead of showing error page I want to read the returned JSON error response (as in fiddler) and show to user.
Help Appreciated!
Adapted from this answer to ".Net HttpWebRequest.GetResponse() raises exception when http status code 400 (bad request) is returned" by Jon Skeet:
try
{
using (WebResponse response = request.GetResponse())
{
Console.WriteLine("You will get error, if not do the proper processing");
}
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse) response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
// text is the response body
string text = reader.ReadToEnd();
}
}
}
Slightly changing SilentTremor's answer. Combining the using statements makes the code a little bit shorter.
catch (WebException ex)
{
HttpWebResponse httpResponse = (HttpWebResponse)ex.Response;
using (WebResponse response = ex.Response)
using (Stream data = response.GetResponseStream())
using (StreamReader reader = new StreamReader(data))
{
string errorMessage = reader.ReadToEnd();
}
}

Delete File in SharePoint folder using C#

I am using SharePoint ExcelService to manipulate an excel file and then save it to the Shared Documents folder using
ExcelService.SaveWorkbookCopy()
Now I want to delete those files I saved earlier. What is the best way to achieve this using C# in a Asp.Net MVC Application?
I tried it using the REST Service, but I could not really find any tutorials and as the code is now, I get a WebException "The remote server returned an error: (403) Forbidden."
I tried two versions for my REST URL, neither worked.
var fileSavePath = "http://sharepointserver/Collaboration/workrooms/MyWebSiteName/Shared%20Documents/";
var excelRestPath_1 = "http://sharepointserver/Collaboration/workrooms/MyWebSiteName/_api/web/";
var excelRestPath_2 = "http://sharepointserver/_api/web/";
public static bool DeleteExcelFromSharepoint(int id, string excelRestPath)
{
try
{
string filePath = "/Shared%20Documents/" + id + ".xlsm";
string url = excelRestPath + "GetFileByServerRelativeUrl('" + filePath + "')";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "DELETE";
request.Headers.Add(HttpRequestHeader.IfMatch, "*");
request.Headers.Add("X-HTTP-Method", "DELETE");
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new ApplicationException(String.Format("DELETE failed. Received HTTP {0}", response.StatusCode));
}
return true;
}
}
catch (Exception ex)
{
CustomLogger.Error("Error deleting Excel from Sharepoint", ex);
return false;
}
}
Use nuget package Microsoft.SharePointOnline.CSOM:
using (var sp = new ClientContext("webUrl"))
{
sp.Credentials = System.Net.CredentialCache.DefaultCredentials;
sp.Web.GetFileByServerRelativeUrl(filePath).DeleteObject();
sp.ExecuteQuery();
}
that will ensure that file is removed - if you want to make sure the file existed during removal:
using (var sp = new ClientContext("webUrl"))
{
sp.Credentials = System.Net.CredentialCache.DefaultCredentials;
var file = sp.Web.GetFileByServerRelativeUrl(filePath);
sp.Load(file, f => f.Exists);
file.DeleteObject();
sp.ExecuteQuery();
if (!file.Exists)
throw new System.IO.FileNotFoundException();
}
If you are using REST, you can refer to the link
(https://msdn.microsoft.com/en-us/library/office/dn450841.aspx#bk_File)
My example code is:
string resourceUrl = "https://<BaseURL>/sites/<SubSite>/_api/web/GetFileByServerRelativeUrl('/sites/<SubSite>/Documents/New Folder/xyz.docx')";
var wreq = WebRequest.Create(resourceUrl) as HttpWebRequest;
wreq.Headers.Remove("X-FORMS_BASED_AUTH_ACCEPTED");
wreq.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
wreq.Headers.Add("X-HTTP-Method", "DELETE");
//wreq.Headers.Add("Authorization", "Bearer " + AccessToken);
wreq.UseDefaultCredentials = true;
wreq.Method = "POST";
wreq.Accept = "application/json; odata=verbose";
wreq.Timeout = 1000000;
wreq.AllowWriteStreamBuffering = true;
wreq.ContentLength = 0;
string result = string.Empty;
string JsonResult = string.Empty;
try
{
WebResponse wresp = wreq.GetResponse();}
catch (Exception ex)
{
LogError(ex);
result = ex.Message;
}
Having tried the answers above and but still not getting the files deleted I found this and it works perfectly
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(“FullSharePointURIofDocument“);
request.Timeout = System.Threading.Timeout.Infinite;
request.Credentials = new
System.Net.NetworkCredential(“SharePointUser“,”SharePointUserPassword“);
request.Method = “DELETE“;
var response = (System.Net.HttpWebResponse)request.GetResponse();
thanks to BizTalkBox

oauth/token returns empty body

I am encountering a problem getting the access_token in client application using oauth.
The returned response has empty body though in API I can see the response is not empty.
tokenresponse = {
"access_token":"[ACCESSTOKENVALUE]",
"token_type":"bearer",
"expires_in":"1200",
"refresh_token":"[REFRESHTOKENVALUE]",
"scope":"[SCOPEVALUE]"
}
The method from API that returns the token http://api.sample.com/OAuth/Token:
public ActionResult Token()
{
OutgoingWebResponse response =
this.AuthorizationServer.HandleTokenRequest(this.Request);
string tokenresponse = string.Format("Token({0})", response!=null?response.Body:""));
return response.AsActionResult();
}
The client method that requests the token is:
public string GetAuthorizationToken(string code)
{
string Url = ServerPath + "OAuth/Token";
string redirect_uri_encode = UrlEncode(ClientPath);
string param = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code",code, ClientId, ClientSecret, redirect_uri_encode);
HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
string result = null;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 10000;
request.Headers.Remove(HttpRequestHeader.Cookie);
var bs = Encoding.UTF8.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
if (!string.IsNullOrEmpty(result))
{
TokenData tokendata = JsonConvert.DeserializeObject<TokenData>(result);
return UpdateAuthorizotionFromToken(tokendata);
}
return null;
}
The result variable is empty.
Please let me know if you have any idea what could cause this. Initially I assumed is because of the cookies so I tried to remove them from request.
Thanks in advance.
Dear just create webclient using following code and you will get json info in tokeninfo.I used it and simply its working perfect.
WebClient client = new WebClient();
string postData = "client_id=" + ""
+ "&client_secret=" + ""
+ "&grant_type=password&username=" + "" //your username
+ "&password=" + "";//your password :)
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
string tokenInfo = client.UploadString(soundCloudTokenRes, postData);
You can then use substring that contains only token from tokeninfo.
To upload tracks on sound cloud.
private void TestSoundCloudupload()
{
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks") as HttpWebRequest;
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] { new UploadFile(Server.MapPath("Downloads//0.mp3"), "track[asset_data]", "application/octet-stream") };
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "Some title");
form.Add("track[sharing]", "public");
form.Add("oauth_token", "");
form.Add("format", "json");
form.Add("Filename", "0.mp3");
form.Add("Upload", "Submit Query");
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
Response.Write(reader.ReadToEnd());
}
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}

Categories