C#: Make new api calls to get new responses - c#

I'm using text generation API and I want to generate a new response each time, which was not the case in my side.
class Program
{
static void Main(string[] args)
{
//make a request to URI
var request = (HttpWebRequest)WebRequest.Create("https://api-inference.huggingface.co/models/gpt2");
//Input data
var postData = "My name is Thomas and my main";
//encoding the input to type byte
var data = Encoding.ASCII.GetBytes(postData);
//send a POST request to the api
request.Method = "POST";
// Set the content length of the string being posted
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
// get the stream of the request
var response = (HttpWebResponse)request.GetResponse();
//Print the generated text of "generated-text"
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write(responseString);
}
}
So as far as I understood the call is getting cached.
How can I stop this from happening ? So that I get a new response each time I call the api

Related

Setting ContentLength on HttpWebRequest gives me a timeout error

I am creating an android app that connects to my website's api using C# and xamarin. After debugging for a while I realised that when I set the ContentLength the apps seams to hang and then throws an TIMEOUT exception.
I have tried to not set the ContentLength but then the body seams to not send with the request.
public void Post(object data, string route){
string JSON = JsonConvert.SerializeObject(data);
var web = (HttpWebRequest)WebRequest.Create("http://httpbin.org/post");
//web.ContentLenfth = JSON.length;
web.ContentType = "application/json";
web.Method = "POST";
try{
var sw = new StreamWriter(webRequest.GetRequestStream());
sw.Write(JSON);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var sr = new StreamReader(webResponse.GetResponseStream());
var result = sr.ReadToEnd();
...
}
...
}
If ContentLengt is set the app hangs until the timeout function is called
else the test-url I am posting to tells me that I did not send a body
What do I have to do in order to send a successful POST request ?
You should set the length to be the length of the byte array you are sending (not the length of the string)
You can get the byte array from the json string by doing:
var bytes = Encoding.UTF8.GetBytes(JSON);
Then you can set the content length:
web.ContentLength = bytes.length;
And send the bytes:
using (var requestStream = web.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}

How can I simultaneously pass args and upload a file to a Web API Controller Method?

I decided that my question here isn't really what I want to do - the XML I need to send is a lot longer, potentially, than I really want to send in a URI.
It didn't "feel" right doing that, and this unsealed the deal.
I need to send both a couple of args AND a file to my Web API app from a client (handheld/CF) app.
I may have found the code for receiving that, from here [
http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2]
Specifically, Wasson's Controller code here looks like it very well might work:
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
...but now I need to know how to send it; other calls from the client are of the form:
http://<IPAddress>:<portNum>/api/<ControllerName>?arg1=Bla&arg2=Blee
but how does the file I need to send/attach get passed along? It is a XML file, but I don't want to append the whole thing to the URI, as it can be quite large, and doing so would be horrendously weird.
Does anybody know how to accomplish this?
UPDATE
Following the crumbs tvanfosson dropped below, I found code here which I think I can adapt to work on the client:
var message = new HttpRequestMessage();
var content = new MultipartFormDataContent();
foreach (var file in files)
{
var filestream = new FileStream(file, FileMode.Open);
var fileName = System.IO.Path.GetFileName(file);
content.Add(new StreamContent(filestream), "file", fileName);
}
message.Method = HttpMethod.Post;
message.Content = content;
message.RequestUri = new Uri("http://localhost:3128/api/uploading/");
var client = new HttpClient();
client.SendAsync(message).ContinueWith(task =>
{
if (task.Result.IsSuccessStatusCode)
{
//do something with response
}
});
...but that depends on whether the Compact Framework supports MultipartFormDataContent
UPDATE 2
Which it doesn't, according to How can i determine which .Net features the compact framework has?
UPDATE 3
Using the Bing Search Code for C# extension, I mashed "h", chose "How do I", entered "send file via http" and got this:
WebRequest request = WebRequest.Create("http://www.contoso.com/PostAccepter.aspx ");
request.Method = "POST";
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
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();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
reader.Close();
dataStream.Close();
response.Close();
As I need to add a couple of string args in addition to the file (which I assume I can add via the postData byte array), can I do that by adding more calls to dataStream.Write()? IOW, is this sensible (first and third lines differ):
WebRequest request = WebRequest.Create("http://MachineName:NNNN/api/Bla?str1=Blee&str2=Bloo");
request.Method = "POST";
string postData = //open the HTML file and assign its contents to this, or make it File postData instead of string postData?
// the rest is the same
?
UPDATE 4
Progress: This, such as it is, is working:
Server code:
public string PostArgsAndFile([FromBody] string value, string serialNum, string siteNum)
{
string s = string.Format("{0}-{1}-{2}", value, serialNum, siteNum);
return s;
}
Client code (from Darin Dimitrov in this post):
private void ProcessRESTPostFileData(string uri)
{
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var data = "=Short test...";
var result = client.UploadString(uri, "POST", data);
//try this: var result = client.UploadFile(uri, "bla.txt");
//var result = client.UploadData()
MessageBox.Show(result);
}
}
Now I need to get it sending a file instead of a string in the [FromBody] arg.
You should look into using multipart/form-data with a custom media type formatter that will extract both the string properties and the uploaded XML file.
http://lonetechie.com/2012/09/23/web-api-generic-mediatypeformatter-for-file-upload/

Consuming REST service with C# code

I am using the following code to get the json result from the service. It works fine for get methods. But when the method type is POST the request address changes to the previous address.
ie;
on the first call to this method the request.address=XXXXX.com:1234/xxx/oldv1.json (method type is get)
and it returns a json string from which I extract another address:XXXXX.com:1234/xxx/newv1.json
and now I call the makerequest method with this endpoint and method type POST, contenttype="application/x-www-form-urlencoded".
When I put breakpint at using (var response = (HttpWebResponse)request.GetResponse()) and checked the request.address value, it was XXXXX.com:1234/xxx/newv1.json
But after that line is executed, the address changes to XXXXX.com:1234/xxx/oldv1.json and the function returns the same response I got with the first Endpoint(XXXXX.com:1234/xxx/oldv1.json).
Can anybody tell what I am doing wrong here?
Is there any better method to consume the service with POST method?
public string MakeRequest(string EndPoint,string Method, string contentType)
{
var request = (HttpWebRequest)WebRequest.Create(EndPoint);
request.Method = Method;
request.ContentLength = 0;
request.ContentType =contentType;
if ( Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes("username=123&password=123");
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse)request.GetResponse())// request.address changes at this line on "POST" method types
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grab the response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
return responseValue;
}
EDIT: Yesterday I asked THIS Question about consuming the service at client side and many suggested it needs to be done at server side as the other domain might not allow accessing the json result at client side.
The issue was about cookies. As I forgot to set the cookies, the request was getting redirected. I had to set cookie container by using
request.CookieContainer = new CookieContainer();

How to get post data and request header

I am not able to get post data and request header from the below code on button click event.. here i have to pass an url and a string as a post data...
now when i click button i should get response header, request header, post data and content of the url... but i am not able to get the request header and post data from the below code... can any one tell me where i am wrong
private void button1_Click(object sender, EventArgs e)
{
try
{
string url = txtUrl.Text.Trim();
//HttpWebRequest WebRequestObject = (HttpWebRequest)WebRequest.Create(url);
// string result = null;
string postData = "This";
ASCIIEncoding ObjASCIIEncoding = new ASCIIEncoding();
byte[] fileData = ObjASCIIEncoding.GetBytes(postData);
// 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";
// Create POST data and convert it to a byte array.
WebHeaderCollection webh = request.Headers;
txtRequest.Text = webh.ToString();
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-wwww-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = fileData.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// StreamReader r = new StreamReader(dataStream);
// string p = r.ReadToEnd();
// Write the data to the request stream.
dataStream.Write(fileData, 0, fileData.Length);
// Close the Stream object.
dataStream.Close();
//Get the response.
request.Credentials = CredentialCache.DefaultCredentials;
// HttpWebResponse Response = (HttpWebResponse)WebRequestObject.GetResponse();
WebResponse Response = request.GetResponse();
// HttpStatusCode code = Response.StatusCode;
//txtStatus.Text = code.ToString();
txtResponse.Text = Response.Headers.ToString();
// Open data stream:
Stream WebStream = Response.GetResponseStream();
// Create reader object:
StreamReader Reader = new StreamReader(WebStream);
// Read the entire stream content:
txtContent.Text = Reader.ReadToEnd();
// Cleanup
Reader.Close();
WebStream.Close();
Response.Close();
// var request = WebRequest.Create("http://www.livescore.com ");
//var response = request.GetResponse();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
This should get the header keys and values, remember that each key has an array of values:
Request Headers
To add a header call the Add method:
WebRequest request = WebRequest.Create("http://www.google.com");
request.Method = "GET";
request.Headers.Add("MyTestHeader", "My Test Header Value");
foreach (var headerKey in request.Headers.Keys)
{
var headerValues = request.Headers.GetValues(headerKey.ToString());
Trace.TraceInformation("Request Header:{0}, Value:{1}", headerKey, String.Join(";", headerValues));
}
Response Headers
using (WebResponse response = request.GetResponse())
{
foreach (var headerKey in response.Headers.Keys)
{
var headerValues = response.Headers.GetValues(headerKey.ToString());
Trace.TraceInformation("Response Header: {0}, Value: {1}", headerKey, String.Join(";",headerValues));
}
}

WebRequest to POST data but what about hidden fields?

I need to essentially POST some hidden fields to a page, which i need to load in the
browser window.
This is for the SagePay forms integration as per page 6:
http://www.docstoc.com/docs/10745827/Sage-Pay-Form-Protocol-and-Integration-Guidelines
I am already using WebRequest to create the POST but how do I send the 4 hidden fields they require?
Also, how do I then load the returned html into the browser; this html is from SagePay where the customer enters their credit card details?
public string SendRequest(string url, string postData)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var encoding = new UTF8Encoding();
var requestData = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = (300 * 1000); //TODO: Move timeout to config
request.ContentLength = requestData.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
var response = request.GetResponse();
string result;
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
result = reader.ReadToEnd();
}
return result;
}
Just add the 4 hidden fields into the postData string. This can be done on the fly in this method, or in the request.
The "hidden" aspect is only hidden in terms of the GUI in the browser.

Categories

Resources