I need to convert the following code from Java to C# when I'm using restAPI in C#.
In java :
HttpGet statusGet = new HttpGet(fileUrl);
statusGet.setHeader("X-API-TOKEN", API_TOKEN);
HttpResponse response = httpClient.execute(statusGet);
// Extract exported file
ZipInputStream zs = new ZipInputStream(response.getEntity().getContent());
In C# this is what I have:
var client1 = new RestClient(fileUrl);
var request1 = new RestRequest(Method.GET);
request1.AddHeader("X-API-TOKEN", "API_TOKEN");
request1.AddHeader("content-type", "application/json");
request1.AddParameter("application/json", "{\n\t\"format\" : \"csv\",\n\t\"surveyId\" : \"_surveyId\"\n}", ParameterType.RequestBody);
IRestResponse responsedata = client1.Execute(request1);
var download=client1.DownloadData(request1);
MemoryStream stream = new MemoryStream(download);
ZipInputStream zs = new ZipInputStream(stream);
using (ZipFile zip1 = ZipFile.Read(zs))
I have no clue how to implement response.getEntity().getContent(). I believe it is getting the Stream(Containing a zip file?)
Updated: So I get the byte array from client1.DownloadData(request1), looks like it is not right to convert it to stream (has readtimeout exception). and it will not be able to read from zipfile.read
Thank you so much for your help
Are you getting any specific errors? It looks like you are implementing this using RestSharp. Have you followed their examples and read through their documentation?
I have not personally used this third-party solution, but immediately on their front page they have the following example that does exactly what you are trying to do:
var client = new RestClient("http://example.com");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("resource/{id}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("id", "123"); // replaces matching token in request.Resource
// easily add HTTP Headers
request.AddHeader("header", "value");
// add files to upload (works with compatible verbs)
request.AddFile(path);
// execute the request
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
// or automatically deserialize result
// return content type is sniffed but can be explicitly set via RestClient.AddHandler();
RestResponse<Person> response2 = client.Execute<Person>(request);
var name = response2.Data.Name;
// easy async support
client.ExecuteAsync(request, response => {
Console.WriteLine(response.Content);
});
// async with deserialization
var asyncHandle = client.ExecuteAsync<Person>(request, response => {
Console.WriteLine(response.Data.Name);
});
// abort the request on demand
asyncHandle.Abort();
It looks like you would want to access the IRestResponse.Content property, or to deserialize using the RestClient.Execute<T>(RestRequest request) function.
Related
Here is the code snippet where I am trying to upload a document with some custom metadata using AWS S3 pre signed URL.
try (CloseableHttpClient httpClient = HttpClients.createSystem()) {
var tempFile = File.createTempFile(document.getName(), FilenameUtils.getExtension(document.getOriginalFilename()));
document.transferTo(tempFile);
var fileEntity = new FileEntity(tempFile);
var httpPut = new HttpPut(url);
// Here 403 httpPut.setHeader("x-amz-meta-title", "Test Title");
httpPut.setEntity(fileEntity);
var response = httpClient.execute(httpPut);
log.info("HTTP response code {}", response.getStatusLine().getStatusCode());
} catch (IOException e) {
log.error("Oops! Error", e);
}
Unfortunately setting a custom header as above throws 403. It works fine when I take out the header. Even works okay when you add an irrelevant metadata key say "abc" - Obviously not adding metadata, but returns 200 OK. The issue seems only when you specify "x-amz-meta-".
Any thoughts?
The metadata of a presigned url are set, when you create it. They are prefilled and can't be modified by the client.
The only thing you can do is set an expected value and optionally a condition. In the condition you can specify to reject the upload, if the expected meta-data value isn't supplied.
Just what the title says, if it helps in any way I have this java code (multipart consists of json object and file):
// Construct a MultiPart
MultiPart multiPart = new MultiPart();
multiPart.bodyPart(new BodyPart(inParams, MediaType.APPLICATION_JSON_TYPE));
multiPart.bodyPart(new BodyPart(fileToUpload, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// POST the request
final ClientResponse clientResp = resource.type("multipart/mixed").post(ClientResponse.class, multiPart);
(using com.sun.jersey.multipart ) and I want to create the same in .NET (C#)
So far I managed to POST the json object like this:
Uri myUri = new Uri("http://srezWebServices/rest/ws0/test");
var httpWebRequest = (HttpWebRequest)WebRequest.Create(myUri);
httpWebRequest.Proxy = null;
httpWebRequest.Accept = "application/json";
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
Console.Write("START!");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())){
string json = new JavaScriptSerializer().Serialize(new
{
wsId = "0",
accessId = "101",
accessCode = "x#ds!2"
});
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
But I want to send the file together. The content type has to be "multipart/mixed" because that's what the web service gets. I tried to find some package that supports multiparts but I found nothing except maybe this http://www.example-code.com/csharp/mime_multipartMixed.asp (which is not free so I can't use it).
I finally managed to do it like this:
HttpContent stringStreamContent = new StringContent(json);
stringStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpContent fileStreamContent = new StreamContent(fileStream);
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Construct a MultiPart
// 1st : JSON Object with IN parameters
// 2nd : Octet Stream with file to upload
var content = new MultipartContent("mixed");
content.Add(stringStreamContent);
content.Add(fileStreamContent);
// POST the request as "multipart/mixed"
var result = client.PostAsync(myUrl, content).Result;
I am working with the Snapchat API to make a Java Client. I am using an endpoint which takes the following parameters from an HTTP POST:
{
username: snapchat username,
timestamp: UNIX timestamp,
media_id: random string,
type: 0,
req_token: request token,
data: encrypted data
}
I have no problem generating the params hash, and I have the data as a File object.
In Python I have confirmed that the following works:
f = open('encrypted.jpg')
params = { ... all params besides data ... }
files = { 'data' : f }
r = requests.post(path, params, files=files)
That Python code gets me a 200. I am using tokens and data/files generated by Java code, so the data sent is identical.
In Java I am doing the following with UniRest:
Map<String, Object> params = ... same params ...;
File f = new File('encrypted.jpg');
HttpRequestWithBody req = Unirest.post(path);
req.fields(params);
req.field("data", f);
HttpResponse<String> resp = req.asString();
However this gives me a 500 response from the server. How can I write Java that emulates the Python exactly? Or how can I snoop my own network traffic to see the difference in what the code for each is doing? Seems crazy to me that one works and the other does not.
try to chain methods, i.e.
req = Unirest.post(path).fields(params).field("data", f);
or change the lines:
req = req.fields(params);
req = req.field("data", f);
My Goal is to request GoogleTaskAPI for TASKLIST with specified no.of result.
It works fine, If I m passing no requestBody. But I need to pass request parameter to specific number of results to be returned. When I do that, it creates new Tasklist, Instead of listing. So how to do this?
My Code:
GoogleAccessProtectedResource access = new GoogleAccessProtectedResource(accessToken, httpTransport, jsonFactory, clientId, clientSecret, refreshToken);
HttpRequestFactory rf = httpTransport.createRequestFactory(access);
String endPointUrl = "https://www.googleapis.com/tasks/v1/users/#me/lists";
String requestBody = "{\"maxResults\":3}";
GenericUrl endPoint = new GenericUrl(endPointUrl);
ByteArrayContent content = new ByteArrayContent("application/json", requestBody.getBytes());
//Try 0: Works, But Retrieving all of my Tasklist, I need only 3
//HttpRequest request = rf.buildGetRequest(endPoint);
//-------
//Try 1: Fails to retrieve
//HttpRequest request = rf.buildGetRequest(endPoint);
//request.setContent(content);
//request.getContent().writeTo(System.out);
//-------
//Try 2: Fails to retrieve
HttpRequest request = rf.buildRequest(HttpMethod.GET, endPoint, content);
request.getContent().writeTo(System.out);
//-------
HttpResponse response = request.execute();
String str = response.parseAsString();
utils.log(str);
maxResults is a query parameter, not a request parameter, so you can just put it in the url:
String endPointUrl = "https://www.googleapis.com/tasks/v1/users/#me/lists?maxResults=3";
You should also consider using the Java client's Tasks interface for making requests; it may be a little easier since it handles the details of the url for you:
http://code.google.com/p/google-api-java-client/wiki/APIs#Tasks_API
I've got XML data in AS3 that needs to be compressed, validated on my Java Google App Engine servlet then saved to a file in Google Cloud Storage. Later that file will be opened and decompressed by the AS3 client. The process works if I do it with plain XML or text, but if I ByteArray#compress the data, it dies during ByteArray#uncompress with "There was an error decompressing the data".
I've tried setting the content type and mime type at various points, as well as encoding with Base64, but every attempt seems to break in a different way and I never get the same XML back that I sent in. Do I need to use multipart? Should I compress on the server? What's the best practice for doing this?
Sending the data from AS3:
// compress xml using zlib
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();
var request:URLRequest = new URLRequest(url);
var urlVariables :URLVariables = new URLVariables();
urlVariables.filename = "somefile.bin";
urlVariables.contents = bytes;
request.data = urlVariables;
request.method = URLRequestMethod.POST;
loader = new URLLoader();
loader.load(request);
Receiving it in the Java servlet and creating the file:
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String filename = req.getParameter("filename");
byte[] contents = req.getParameter("contents").getBytes();
GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
.setBucket("bucketname")
.setKey(filename)
.setAcl("public-read")
.setMimeType("binary/octet-stream");
AppEngineFile writableFile = fileService.createNewGSFile(optionsBuilder.build());
boolean lockForWrite = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(writableFile, lockForWrite);
writeChannel.write(ByteBuffer.wrap(contents));
writeChannel.closeFinally();
}
Opening the new file in AS3:
var url :String = "http://commondatastorage.googleapis.com/bucketname/somefile.bin";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);
protected function handleComplete (event:Event):void {
var bytes:ByteArray = new ByteArray();
bytes.writeObject(event.target.data);
// dies on this line with "There was an error decompressing the data."
bytes.uncompress();
var xml:XML = new XML(new String(bytes));
trace(xml);
}
Here is the code that I use to save an xml. I send the data to PHP but I would think it would work the same way for you... I haven't had any trouble with it.
var createXMLURL:URLRequest = new URLRequest("createXML.php");
createXMLURL.method = URLRequestMethod.POST;
var Variables:URLVariables = new URLVariables();
Variables.xmlString = xml.toXMLString();
Variables.filename = filename;
createXMLURL.data = Variables;
var loader:URLLoader = new URLLoader();
loader.dataFormat = "VARIABLES";
loader.addEventListener(Event.COMPLETE, xmlCreated);
loader.load(createXMLURL);
Let me know if you have any questions about what some of the variables are since I did not include their declarations (I think they are pretty easy to figure out).
Now this doesn't send that data in binary format like you were asking for, but I don't know why you wouldn't be able to convert the string to binary once you receive it in java if you really need the raw bytes.
I would base64 encode before you POST if from the client, store it that way in a TextProerty, then base64 decode / decompress when received back at the client. If you want to store it as binary on GAE, then base64 decode it into a Blob. Here are some code snippets I pieced together using your code, and something similar I do using HttpService -- apologies in advance for not extensively proofing it. HTH.
private var _serviceHttp:HTTPService = new HTTPService;
private function postBytes():void {
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();
var enc:Base64Encoder = new Base64Encoder();
enc.encodeBytes(bytes, 0, bytes.length);
var myObj:Object = new Object();
myObj["bytes"] = enc.toString();
// myObj["other_variables"] = your_other_varaibles;
_serviceHttp.method = "POST";
_serviceHttp.resultFormat = "flashvars";
_serviceHttp.url = your_url_here;
_serviceHttp.addEventListener(ResultEvent.RESULT, urlHandler);
_serviceHttp.addEventListener(FaultEvent.FAULT, urlErrorHandler);
_serviceHttp.send(myObj);
}