File Upload using Chatter REST API - c#

I read documentation of Salesforce Chatter REST API and started to implement code in c#.
See following code:
System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
req.Method = "POST";
req.Headers.Add("Authorization: OAuth " + accessToken);
req.ContentType = "application/x-www-form-urlencoded";
string par =
"fileName=" + fileName +
"&feedItemFileUpload="
+ #"D:\\MyFiles\\NewTextDocument.txt" +
"&desc=" + desc+
"&text=" + text;
byte[] byteArray = Encoding.UTF8.GetBytes(par);
req.ContentLength = byteArray.Length;
Stream dataStream = req.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
System.Net.WebResponse resp = req.GetResponse();
I am gettig error on response
The remote server returned an error: (400) Bad Request.
If i see response of error, i got following message:
Please specify a file to upload. Type in the path to the file, or use the \"Browse\" button to locate it in your local filesystem.
I have already defined the file path and name. I tried with and without # sign before path string but getting same error. Let me know if anything is missing.

You can easily use Fiddler to see what's going on.
You are posting a simple form where fileName and feedItemFileUpload are just like desc and text, in other words, plain simple text!
What you need to do is send the file as a stream.
I can see that you're using Hanselman's code, but that's only for text parameters
for more information on using it for files, see this answer
Upload files with HTTPWebrequest (multipart/form-data)

Related

Do I need to post every request header when simulating a webpage log in through C#?

I am working on getting information that is behind a log in page, and using this as my starting point.
Looking at the Network tab, I looked at the form data and saw there were 3 additional values than just client/password (csrf, time, hash).
I attempted to log into the site as follows.
string formUrl = "mysite_loginaction";
string formParams = string.Format("client_id={0}&password={1}", "client", "password");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
When I print out the resp to my console, it shows my the log in page, when i was expecting the next page after login (google 2f page).
Do I need to post a csfr, time, and hash values as well to get a successful login?
Like it has been mentioned in your link, there is a concept of sessionid token. If you do want to stay logged in, you need to pass that token everytime for the following http requests.
Also, the CSRF token will always be different each time you do the request, but you do need to pass it along your next request to be successful.
To know more about CSRF, I should redirect you to this link
You're going to have to mess around with it. Most of the time you don't need all the headers, but I would assume that hash is required.

API woes with .Net in C#

I am new to .net and APIs and am currently using .Net 4.5 to connect to an API using rest. The problem I am having is I get an exception thrown back in the return xml that says "Cannot forward request to server with name", "Cannot read data from connection", Connection reset", full error below.
What is odd is this script works fine on smaller datasets but when the response is large enough, I get that exception from the server thrown back. What has helped setting the keep alive to true, using httpversion10, and specifying gzip and sendchunked. I am using advanced rest client to test the server in chrome addins and it returns data fine on there with these larger dataset. It will not with the script below. I am suspecting there is a difference in the way I am telling the server to handle my response verses the chrome add in. Any suggestions on how I improve the performance of this?
This is what the advanced rest client settings look like that work for the Chrome add in.
This is the code I have which appears to need changes to make it handle the request/response better.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(#"magicalwebsite");
req.KeepAlive = true;
req.ProtocolVersion = HttpVersion.Version10;
req.ServicePoint.ConnectionLimit = 24;
req.Timeout = 2000000000;
req.Method = "Post";
req.Accept = "*/*";
req.SendChunked = true;
req.AutomaticDecompression = DecompressionMethods.GZip;
//Xml request file for data
string postData = System.IO.File.ReadAllText(#"C:\Users\yo\Desktop\testtest.txt");
//sending header and content
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
req.ContentType = "text/xml";
req.ContentLength = byteArray.Length;
req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("xxxx:xxxxx"));
Stream dataStream = req.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//Requesting response of data
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
//Grabbing response
using (Stream stream = resp.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
String responseString = reader.ReadToEnd();
}
This is the exception I am getting in the xml being thrown back.
<?xml version="1.0" encoding="UTF-8"?>
<response success="false">
<messages>
<message key="exception-caught">Caught Exception: Caught Exception:
Cannot forward request to server with name=prod-euapp01
com.magicalpony.exception.APException: Cannot forward request to server with name=prod-euapp01
at com.magicalpony.webservices.APIForwarder.forward(APIForwarder.java:105)
at com.magicalpony.webservices.APIServlet.forwardRequest(APIServlet.java:270)
at com.magicalpony.webservices.APIServlet.wrongServer(APIServlet.java:253)
at com.magicalpony.webservices.APIServlet.service(APIServlet.java:124)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:210)
at com.magicalpony.system.WebServiceMonitor.doFilter(WebServiceMonitor.java:61)
at org.apache.catalina.core.
ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.magicalpony.system.HitTracer.doFilter(HitTracer.java:133)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:303)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:183)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:169)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.magicalpony.exception.APException:
Cannot read data from connection
at com.magicalpony.webservices.NetUtil.readData(NetUtil.java:61)
at com.magicalpony.webservices.APIForwarder.forward(APIForwarder.java:102)
... 26 more
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at
java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1323)
at com.magicalpony.webservices.NetUtil.readData(NetUtil.java:58)
... 27 more</message>
</messages>
</response>
The problem is with DNS resolution.
Step 1: Enter your domain name in a browser and see if Server is available.
Step 2: If server is available with domain name then you got to fix the IP Address or DNS resolution.
You can fix this by updating the IP Address in your PC (Follow steps below)
Go to a folder: C:\Windows\System32\drivers\etc
Copy and paste "hosts" file to desktop.
Update your host file with your IP Address and domain name.
Step 3: Copy and Paste hosts file in original folder (C:\Windows\System32\drivers\etc).
Step 4: Test your API.

Microsoft Live custom C# REST API error 415

I'm trying to get data from the Microsoft Live API. However, when I try to get the access_token, I instead get a 415(Unsupported Media Type) error message. I have looked pretty much everywhere, but I can't find any answer (that worked for me).
Here is my (partial) code that tries to get the token (dataToWrite is cut-up for readability, it's one line in the actual code):
WebRequest request;
request = WebRequest.Create("https://login.live.com/oauth20_token.srf");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var dataToWrite = "code=[code]&
client_id=[client_id]&
client_secret=[client_secret]&
redirect_uri=[redirect_uri]&
grant_type=authorization_code";
var buffer = Encoding.ASCII.GetBytes(dataToWrite);
request.ContentLength = buffer.Length;
var dataStream = request.GetRequestStream();
dataStream.Write(buffer, 0, buffer.Length);
dataStream.Close();
var response = request.GetResponse();
var responseStream = response.GetResponseStream();
Where the '[]' are:
[code] is a string, given by Microsoft after user logs in (this part of the code works);
[client_id] is a string, given by Microsoft, representing my client id;
[client_secret] is a string, given by Microsoft, representing my client secret;
[redirect_uri] is the URL of the site's return location (same as the URL used in the code for the user consent(see [code]))
According to the manual of Microsoft Live API(http://msdn.microsoft.com/en-us/library/live/hh243647.aspx) this should work. However, the documentation isn't very detailed.
Does anyone know why I keep getting the error?
Thanks!
Never mind, I'm an idiot...
It does work after all. I did another request after this one. And that one failed because I did not include the parameters there.

obtain rss response

how would I be able to do something like http://myanimelist.net/modules.php?go=api#verifycred
aka "curl -u user:password http://myanimelist.net/api/account/verify_credentials.xml"
I wish to option the id
my code so far is
string url = "http://myanimelist.net/api/account/verify_credentials.xml";
WebRequest request = WebRequest.Create(url);
request.ContentType = "xml";
request.Method = "GET";
request.Credentials = new NetworkCredential(username, password);
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("xml/user/id"); // i think this line?
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
but I get a error on "reqstr.Write(buffer, 0, buffer.Length)"
Cannot send a content-body with this verb-type, I have tried googling but with no prevail, I am using c#
Your snippet is trying to send a GET request with request data (you're calling GetRequestStream and then writing some data to the request stream). The HTTP protocol does not allow this - you can only send data with POST request.
However, the API that you are trying to call is actually doing something different - you do not need to send it the XML data. The XML data (with user ID and user name) is the response that you get when you successfully login.
So, instead of calling GetRequestStream and writing the XML data, you need to call GetResponse and then GetResponseStream to read the XML data!

How to post data to a website

I need to post data to a website. So I created a small app in C#.net where I open this website and fill in all the controls (radio buttons, text boxes, checkboxes etc) with the values from my database. I also have a click event on the SUBMIT button. The app then waits for 10-15 seconds and then copies the response from the webpage to my database.
As you can see, this is really a hectic process. If there are thousands of records to upload, this app takes much longer (due to fact that it waits 15s for the response).
Is there any other way to post data? I am looking for something like concatenating all the fields with its value and uploading it like a stream of data. How will this work if the website is https and not http?
You can use HttpWebRequest to do this, and you can concatenate all the values you want to post into a single string for the request. It could look something like this:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.yoursite.com");
request.Method = "POST";
formContent = "FormValue1=" + someValue +
"&FormValue2=" + someValue2 +
"&FormValue=" + someValue2;
byte[] byteArray = Encoding.UTF8.GetBytes(formContent);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = HttpUtility.UrlDecode(reader.ReadToEnd());
//You may need HttpUtility.HtmlDecode depending on the response
reader.Close();
dataStream.Close();
response.Close();
This method should work fine for http and https.
MSDN has a great article with step-by-step instructions detailing how you can use the WebRequest class to send data. Link below:
http://msdn.microsoft.com/en-us/library/debx8sh9.aspx
Yes, there is a WebClient class. Look into documentation. There're some usful method to make GET and POST requests.

Categories

Resources