I am saving data on Buddy cloud. Earlier I was saving string data and it was fine. Now I have to save picture but I am getting exception "Bad Request". Actually, they specify that its type should be "file". I don't know how to specify that. Below is the code and I have to do this using API.
documentation: http://dev.buddyplatform.com/Home/Docs/Create%20Picture/HTTP?
byte[] image = File.ReadAllBytes(imagePath);
string url = "https://api.buddyplatform.com/pictures";
// how to specify type below line ? how to correct ?
string parameters = "{data:'" + image + "'}";
HttpWebRequest request = null;
HttpWebResponse response = null;
request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "application/json";
request.ContentType = "application/json";
request.Method = "POST";
request.Headers.Add("Authorization", "Buddy " + SharedData.buddyTOKEN);
// send request
StreamWriter sw = new StreamWriter(await request.GetRequestStreamAsync());
sw.WriteLine(parameters);
sw.Close();
// get response
response = (HttpWebResponse)await request.GetResponseAsync();
You won't be able to create the request body (your parameters string) by concatenating a string with a byte[]. This will end up calling ToString() on a byte[], leaving you with a request that looks like:
{ data:'System.Byte[]' }
Since this is being sent as a JSON request, it's likely that Buddy is expecting a base64 encoded file. This is how you would encode your file in base64 and insert it into the request:
string parameters = "{data:'" + Convert.ToBase64String(bytes) + "'}";
Result:
{data:'FxgZGurnIBlBCtIAIQ[...rest of your file...]'}
Related
I have a user controller created using the hartl tutorial that signs up new users via form with email and password inputs. This is working properly. I am attempting to send an HttpWebRequest from the Unity editor player to my server in order to sign up a new user from a password string created within Unity. I have provided the error response and the code relevant to the attempt below.
WebException: The remote server returned an error: (422) Unprocessable Entity.
System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult) (at ><4b9f316768174388be8ae5baf2e6cc02>:0)
System.Net.HttpWebRequest.GetResponse () (at <4b9f316768174388be8ae5baf2e6cc02>:0)
UnityStandardAssets.Characters.RigidbodyFirstPersonController.RigidbodyFirstPer>sonController.resetScene3 () (at >Assets/Scripts/RigidbodyFirstPersonController.cs:463)
HttpWebRequest Code from RigidbodyFirstPer>sonController.resetScene3 ():
public static string _url = "https://immense-castle-53592.herokuapp.com/signup";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_url);
request.Method = "POST";
request.Headers ["action"] = "/users";
request.Headers ["class"] = "new_user";
request.Headers ["id"] = "new_user";
request.Headers ["utf8"] = "✓";
request.Headers ["authenticity_token"] = "NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=";
request.Headers ["user_email"] = "jakebrantley44#gmail.com";
request.Headers ["user_password"] = passwordUnity;
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Debug.Log("Publish Response: " + (int)response.StatusCode + ", " + response.StatusDescription);
if((int)response.StatusCode == 200)
{
//SetEnvironmentVersion(version);
}
}
Ruby on Rails Users Controller
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
puts params[:password]
if #user.save
log_in #user
flash[:success] = "Welcome to your vault!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:email, :password)
end
end
Routes.rb
Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/demo', to: 'static_pages#demo'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
post '/signup', to: 'users#create'
post '/', to: 'users#create'
get '/show', to: 'users#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end
Update: New code from attempt utilizing Stream.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_url);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
// Add dictionary strings
headers["action"] = "/users";
headers["class"] = "new_user";
headers["id"] = "new_user";
headers["utf8"] = "✓";
headers["authenticity_token"] = "NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=";
headers["user_email"] = "jakebrantley44#gmail.com";
headers["user_password"] = passwordUnity;
byte[] headersByte = UnityWebRequest.SerializeSimpleForm(headers);
// Set the ContentLength property of the WebRequest.
request.ContentLength = headersByte.Length;
Debug.Log( headersByte );
// Get the request stream.
Stream dataStream = request.GetRequestStream ();
// Write the data to the request stream.
dataStream.Write (headersByte, 0, headersByte.Length);
// Close the Stream object.
dataStream.Close ();
// Get the response.
using(HttpWebResponse response = (HttpWebResponse)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);
Debug.Log(responseFromServer);
reader.Close ();
dataStream.Close ();
response.Close ();
Debug.Log("Publish Response: " + (int)response.StatusCode + ", " + response.StatusDescription);
if((int)response.StatusCode == 200)
{
}
}
The ruby code is looking for the params :email and :password, but in the client side, you are adding user_email and user_password to the header instead.
Also based on the updated code, I think you should put
if((int)response.StatusCode == 200)
{
}
before response.Close();.
Solved it!
Changed method of post from Http.Web.Request to UnityWebRequest. Http.Web.Request headers aren't intended to be used for passing parameters.
Changed Ruby/Rails users_controller.rb user_params function to the following. The controller needed to be set to .fetch the parameter values:
def user_params
puts "user_params runs"
unless params["user"].blank?
puts "main state user_params"
params.fetch(:user, {:email => params[:EMAIL], :password => params[:PASSWORD]}).permit(:email, :password)
end
puts "unless state in user_params"
params.fetch(:user, {"email"=>params[:EMAIL], "password"=>params[:PASSWORD]}).permit(:email, :password)
end
I followed this procedure.
https://techlib.barracuda.com/CudaSign/RestEndpointsAPI
This is my C# code to get an access token.
string userData = "username=email#domain.com&password=mypassword&grant_type=password";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://signnow.mydomain.com/api/index.php/oauth2/token");
request.Accept = "application/json";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", "Basic " + userData);
var response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
//JSON output.
}
The following error I got:
The remote server returned an error: (400) Bad Request.
I know this is because of wrong pattern. Can you please help me in getting an access token from sign now?
Thanks in advance!!!
cURL Request:
string data = "username=email#domain.com&password=mypassword&grant_type=password";
WebRequest myReq = WebRequest.Create(myURL + "oauth2/token");
myReq.Method = "POST";
//myReq.ContentLength = data.Length;
myReq.ContentType = "application/x-www-form-urlencoded";
UTF8Encoding enc = new UTF8Encoding();
//myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(enc.GetBytes(data)));
myReq.Headers.Add("Authorization", "Basic " + data);
WebResponse wr = myReq.GetResponse();
As far as I can see, the user data should be sent within the payload and not within the header Authorization. The client credentials (ENCODED_CLIENT_CREDENTIALS) must be something associated to your global account on Barracuda.
I suggest you to test your request using curl since the documentation of the tool use it:
curl -H 'Authorization: Basic ENCODED_CLIENT_CREDENTIALS'
--data 'username=user#test.com&password=test&grant_type=password&scope=user%20documents%20user%2Fdocumentsv2' https://capi-eval.signnow.com/api/oauth2/token
The command parameter --data corresponds to the payload of the request POST.
To fix your problem, you shoud update your code as described below:
string encodedUserCredentials =
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes("user:password")));
string userData = "username=email#domain.com&password=mypassword&grant_type=password";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://signnow.mydomain.com/api/index.php/oauth2/token");
request.Accept = "application/json";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("Authorization", "Basic " + encodedUserCredentials);
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream());
requestWriter.Write(userData);
requestWriter.Close();
var response = request.GetResponse() as HttpWebResponse;
To know what to put within the variable encodedUserCredentials (i.e. values of user and password), see this doc https://techlib.barracuda.com/CudaSign/RestEndpointsAPI#, section "Security and Access Control".
See these two links for more details:
How to pass POST parameters to ASP.Net web request?
How to send authentication header in ASP.Net for set of web request
Hope it helps you,
Thierry
Ok, this may not be the most elegant solution, but I am new to all this. Also I apologize about it being in vb instead of C#
Public Class iqAPI
Public Shared Function postRequest(ByVal url As String, ByVal toSerialize As String, strHeader As String) As DataTable
Dim wHeader As WebHeaderCollection = New WebHeaderCollection
wHeader.Clear()
wHeader.Add(strHeader)
Dim wReq As WebRequest = WebRequest.Create(url)
Dim postData As String = JsonConvert.SerializeObject(toSerialize)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
wReq.Headers = wHeader
wReq.Method = "POST"
wReq.ContentType = "application/x-www-form-urlencoded"
wReq.ContentLength = byteArray.Length
Dim dataStream As Stream = wReq.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim wResp As WebResponse = wReq.GetResponse()
MsgBox(CType(wResp, HttpWebResponse).StatusDescription)
dataStream = wResp.GetResponseStream()
Using reader As New StreamReader(dataStream)
Dim respFromServer As String = reader.ReadToEnd()
Dim dtCudaClient As DataTable = JsonConvert.DeserializeObject(Of DataTable)("[" & respFromServer & "]")
MsgBox(dtCudaClient.Rows(0).ToString)
iqSTAMP.gvCudaClients.DataSource = dtCudaClient
reader.Close()
dataStream.Close()
wResp.Close()
Return dtCudaClient
End Using
Return Nothing
End Function
A couple things to note, I overloaded this to use an object instead of the string for the toSerialize. It seems when you create a user, you have to have it in a json format and when you are getting a Token you use the above method passing a string the way you have it. I couldn't figure out the create user without having an object that got Serialized into json.
As far as the Encoded_Client_Credentials, that is supplied by CudSign. I am currently trying to figure out how to POST a file to them without much luck. Hope you have an easier time than me.
var client = new RestClient("https://api-eval.signnow.com/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("authorization", "Basic BASE64_ENCODED_CLIENT_ID:CLIENT_SECRET");
request.AddParameter("application/x-www-form-urlencoded", "username=EMAIL&password=PASSWORD&grant_type=password", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
It looks like you are hitting the wrong endpoint to me but not 100% sure. I added the code that works for me in getting the correct response, minus some minor info. Let me know if this helps if not I am happy to help get the correct response.
Side note: might need to clear cache if anything could be saved from previous attempts.
Side note: you do not need to specify the scope if you are getting an unrestricted access token.
I've been fiddling quite a bit with my uploading to vimeo.
I've made a ticket request.
I've uploaded the file.
I've checked the file if its uploaded.
I need to run the method DELETE with the complete_uri response i should get from my ticket.
However, im not receiving any complete_URI from the ticket response.
Here is my code:
public static dynamic GenerateTicket()
{
const string apiUrl = "https://api.vimeo.com/me/videos?type=streaming";
var req = (HttpWebRequest)WebRequest.Create(apiUrl);
req.Accept = "application/vnd.vimeo.*+json;version=3.0";
req.Headers.Add(HttpRequestHeader.Authorization, "bearer " + AccessToken);
req.Method = "POST";
var res = (HttpWebResponse)req.GetResponse();
var dataStream = res.GetResponseStream();
var reader = new StreamReader(dataStream);
var result = Json.Decode(reader.ReadToEnd());
return result;
}
This response gives me:
form
ticket_id
upload_link
upload_link_secure
uri
user
In order to finish my upload i need to run step 4 in this guide: https://developer.vimeo.com/api/upload
Sending parameter type=streaming as body:
ASCIIEncoding encoding = new ASCIIEncoding();
string stringData = "type=streaming"; //place body here
byte[] data = encoding.GetBytes(stringData);
req.Method = "PUT";
req.ContentLength = data.Length;
Stream newStream = req.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
At the moment, type=streaming must be sent in the body of the request, not as a url parameter.
This will probably change to allow either option.
the important point is :
"The first thing you need to do is request upload access for your application. You can do so from your My Apps page."
If you get all values without complete_uri, it means: you dont have an upload access token. So go to your apps and make an upload request
i am facing a problem where i try to communicate with a Ruby API from a C# application.
I need to POST some JSON data, with the parameter name "data" but the API return me: '!! Unexpected error while processing request: invalid %-encoding'.
I tried with Content-Type set to 'application/json' and 'application/x-www-form-urlencoded; charset=utf-8'.
My POST data look like this 'data=some_json_string'.
I figure i should escape the json string, so if it is my problem, how to do it with .NET without using a 3rd party library?
Code:
byte[] data = System.Text.ASCIIEncoding.UTF8.GetBytes(sdata);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.Absolute));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
request.ContentLength = data.Length;
Stream reqStream = request.GetRequestStream();
// Send the data.
reqStream.Write(data, 0, data.Length);
reqStream.Close();
Thanks in advance!
Presuming the string sdata coming in is already in JSON format you could do:
using (WebClient wc = new WebClient())
{
string uri = "http://www.somewhere.com/somemethod";
string parameters = "data=" + Uri.EscapeDataString(sdata);
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string result = wc.UploadString(uri, parameters);
}
Depending on the consuming service it may need the Content-type set to application/json?
I've got a problem with creating an HTTP post request in .NET. When I do this request in ruby it does work.
When doing the request in .NET I get following error:
<h1>FOXISAPI call failed</h1><p><b>Progid is:</b> carejobs.carejobs
<p><b>Method is:</b> importvacature/
<p><b>Parameters are:</b>
<p><b> parameters are:</b> vacature.deelnemernr=478
</b><p><b>GetIDsOfNames failed with err code 80020006: Unknown name.
</b>
Does anyone knows how to fix this?
Ruby:
require 'net/http'
url = URI.parse('http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature')
post_args = {
'vacature.deelnemernr' => '478',
}
resp, data = Net::HTTP.post_form(url, post_args)
print resp
print data
C#:
Uri address = new Uri(url);
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Create the data we want to send
StringBuilder data = new StringBuilder();
data.Append("vacature.deelnemernr=" + HttpUtility.UrlEncode("478"));
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
// 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);
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
result = reader.ReadToEnd();
}
return result;
Don't you need the ? after the URL in order to do a post with parameters? I think that Ruby hides this behind the scenes.
I found the problem! The url variable in the C# code was "http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature/"
It had to be "http://www.carejobs.be/scripts/foxisapi.dll/carejobs.carejobs.importvacature" without the backslash.