So currently I get a list of images with ID's. When the user then clicks on it, it downloads and displays the image. Everything works, I just need a progress bar to show where it is currently at.
Current code:
var values = new Dictionary<string, string>
{
{ "myPost", "Data" },
};
var client = new System.Net.Http.HttpClient();
var content = new FormUrlEncodedContent(values);
client.DefaultRequestHeaders.Add("test", "header");
var response = await client.PostAsync("myScript.php", content);
var responseString = await response.Content.ReadAsStringAsync();
Since you are using UWP. I would suggest you use the HttpClient provided in Windows.Web.Http. This has post/put and get methods which also provides progress.
See HttpClient for more details specifically HttpProgress in HttpClient.
Hope this helps!
Related
Hello Stackoverflow community. I hope someone here can help me!!
I'm trying to integrate with the Zoopla API that requires the post request to send the following customized content type. (I've got the certificate side of things working fine).
application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json
I've tried the following approaches without any success (they all result in the following error)
System.FormatException: 'The format of value 'application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json' is invalid.'
Initial approach was to set it within the content of the RequestMessage
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"),
Method = HttpMethod.Post,
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json")
};
When that didn't work I tried to set it via the default headers (the client below is from the ClientFactory)
client.DefaultRequestHeaders.Add("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
My final attempt was to set it without validation
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
I've just tried something else which unfortunately didn't work
string header = "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json";
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(header));
I am well and truly stumped!! HELP!! :-)
Content-Type is set on the content, not in DefaultRequestHeaders. You may try using TryAddWithoutValidation on the request content:
var content = new StringContent("hello");
content.Headers.ContentType = null; // zero out default content type
content.Headers.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
var client = new HttpClient(); // note: use IHttpClientFactory in non-example code
var response = await client.PostAsync("https://postman-echo.com/post", content);
Console.WriteLine(response.StatusCode); // OK
Console.WriteLine(await response.Content.ReadAsStringAsync());
// {"args":{},"data":{},"files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-6345b568-22cc353761f361483f2c3157","content-length":"5","content-type":"application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json"},"json":null,"url":"https://postman-echo.com/post"}
I wanted to download the data from https://eauction.ccmc.gov.in/frm_scduled_items.aspx using the date listed in the dropdown.
private async Task Cbetest()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://eauction.ccmc.gov.in");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("ctl00$ContentPlaceHolder1$gridedit$ctl14$ctl02","17/02/2016")
});
var result = await client.PostAsync("/frm_scduled_items.aspx", content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine(resultContent);
}
}
I wanted to download the data shown in the above image
You need to do a little extra work to simulate a post to begin scraping against a ASP.NET WebForms application. Mostly, you're going to need to pass along valid ViewState and EventValidation parameters, which you can retrieve from an initial GET request.
I'm using the HTML Agility Pack to ease with parsing the initial response, I recommend you look into it if you're planning to scrape HTML.
The following seems to get the results you're looking for, though I haven't looked too deeply in the response HTML.
using(var client = new HttpClient())
{
client.BaseAddress = new Uri("https://eauction.ccmc.gov.in");
var initial = await client.GetAsync("/frm_scduled_items.aspx");
var initialContent = await initial.Content.ReadAsStringAsync();
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(initialContent);
var viewState = htmlDoc.DocumentNode.SelectSingleNode("//input[#id='__VIEWSTATE']").GetAttributeValue("value", string.Empty);
var eventValidation = htmlDoc.DocumentNode.SelectSingleNode("//input[#id='__EVENTVALIDATION']").GetAttributeValue("value", string.Empty);
var content = new FormUrlEncodedContent(new Dictionary<string, string>{
{"__VIEWSTATE", viewState},
{"__EVENTVALIDATION", eventValidation},
{"ctl00$ContentPlaceHolder1$drp_auction_date", "17/02/2016"}
});
var res = await client.PostAsync("/frm_scduled_items.aspx", content);
var resContent = await res.Content.ReadAsStringAsync();
Console.WriteLine(resContent);
}
From there you'll want to parse the resulting table to get useful information. If you want to crawl through the DataGrid's pages, you're going to need to get updated EventValidation and ViewState values and simulate additional posts for each page.
I have tried to create a simple console application.
We have a call system from 8x8 that provide a web streaming API but their documentation is very limited and nothing in C#.
The api service streams call statuses in near real time and I would like to get that 'stream' and be able to read and process it in realtime if possible. The response or Content Type is 'text/html'. But the actual body of the response can be declared as json - sample below:
{"Interaction":{"attachedData":{"attachedDatum":[{"attachedDataKey":"#pri","attachedDataValue":100},{"attachedDataKey":"callingName","attachedDataValue":999999999999},{"attachedDataKey":"cha","attachedDataValue":99999999999},{"attachedDataKey":"cnt","attachedDataValue":0},{"attachedDataKey":"con","attachedDataValue":0},{"attachedDataKey":"med","attachedDataValue":"T"},{"attachedDataKey":"pho","attachedDataValue":9999999999},{"attachedDataKey":"phoneNum","attachedDataValue":9999999999},{"attachedDataKey":"tok","attachedDataValue":999999999}]},"event":"InteractionCreated","inboundChannelid":9999999999,"interactionEventTS":9999999,"interactionGUID":"int-15b875d0da2-DJOJkDhDsrh3AIaFP8VkICv9t-phone-01-testist","resourceType":0}}
I have seen several posts concerning httpClient and the GetAsync methods but none of these appear to work as they appear to be for calls when a response is made, not something that constantly has a response.
Using fiddler for the call it does not appear to close so the stream is constantly running, so fiddler does not display any data until a separate user or instance connects.
When I use a browser the content is 'streamed' to the page and updates automatically and shows all the content (as above).
The api contains authentication so when another client connects and retrieves data the connected client closes and finally I am able to see the data that was gathering.
This is the code so and does return the big stream when another client connects but ideally I want a real time response and appears to just get stuck in the GETASYNC method:
var response = await client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = await responseContent.ReadAsStringAsync();
Console.WriteLine(responseString);
}
Hopefully that's enough information for one of you clever people to help me in my predicament.
I was also having an issue consuming their streaming API and the examples I found that worked with the Twitter and CouchBase streaming API's did not work with 8x8. Both Twitter and CouchBase send line terminators in their pushes so the solution relied on ReadLine to pull in the feed. Since 8x8 does not send terminators you'll need to use ReadBlock or better ReadBlockAsync.
The following code shows how to connect using credentials and consume their feed:
private static async Task StreamAsync(string url, string username, string password)
{
var handler = new HttpClientHandler()
{
Credentials = new NetworkCredential {UserName = username, Password = password},
PreAuthenticate = true
};
// Client can also be singleton
using (var client = new HttpClient(handler))
{
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Connection.Add("keep-alive");
using (var response = await client.SendAsync(
request,
HttpCompletionOption.ResponseHeadersRead))
{
using (var body = await response.Content.ReadAsStreamAsync())
{
using (var reader = new StreamReader(body))
{
while (!reader.EndOfStream)
{
var buffer = new char[1024];
await reader.ReadBlockAsync(buffer, 0, buffer.Length);
Console.WriteLine(new string(buffer));
}
}
}
}
}
}
I am having a issue in solving REST api call in windows phone application.
The situation is something :
I want to Pass two parameter named here "session_token" and "userid" as header in rest api call i am using the following code but the expected output is not matched with the postman out put (attached in screen shot)
I have the following code
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(Connection);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-ype", "application/x-www-form-urlencoded");
client.DefaultRequestHeaders.TryAddWithoutValidation("session_token", "sdfsffsdfsdffsfsdfsdfsdfsdf");
client.DefaultRequestHeaders.TryAddWithoutValidation("userid", "sdfsdfsdfsdfsdfsdd");
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("changepasswordinput", "{\"oldpassword\":\"sdfsdfdf\",\"newpassword\":\"sdfsdfsdf\"}"));
HttpContent content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.PostAsync("changepassword", content);
if (response.IsSuccessStatusCode)
{
var outputstring = await response.Content.ReadAsStringAsync();
responseBaseClass = await response.Content.ReadAsAsync<ResponseBaseClass>();
}
}
Please tell me where i am doing wrong.
Thanks in advance.
You are doing it right, the headers are there. Just click on the Headers(2) tab in Postman on the first screenshot and you will see them.
I'am trying to pass values from a controller to another controller in another domain. I'am adding data to a NameValueCollection and pass it to another controller [httppost] method and receiving data there mapped to a Model same as i passed from.
Currently i'am running it locally by opening two instance of VS simultaneously. When the both VS is opened the values are passed correctly and the information is written to db correctly and i receive a response like "{byte[0]}". Now when i try stopping the destination controller Project and try to submit data then it wont work but still i get the same response as "{byte[0]}". Can somebody please help me how to return the response command in this scenario. Is there a way a understand the UploadValues are completed or not completed.
.........
.........
NameValueCollection resumeDetails = new NameValueCollection();
resumeDetails.Add("FirstName", "KRIZTE");
byte[] res = this.Post(ConfigurationManager.AppSettings["RedirectionUrl"].ToString(), resumeDetails);
return View("Index");
}
public byte[] Post(string uri, NameValueCollection resumeDetails)
{
byte[] response = null;
WebClient client = new WebClient();
response = client.UploadValues(uri, resumeDetails);
return response;
}
You should not use the WebClient because of problems like this.
Microsoft implemented HttpClient class as a newer API and it has these benefits:
HttpClient is the newer of the APIs and it has the benefits of
has a good async programming model
1- being worked on by Henrik F Nielson who is basically one of the inventors of HTTP, and he designed the API so it is easy for you to follow the HTTP standard, e.g. generating standards-compliant headers
2- is in the .Net framework 4.5, so it has some guaranteed level of support for the forseeable future
3- also has the xcopyable/portable-framework version of the library if you want to use it on other platforms - .Net 4.0, Windows Phone etc.
so I'm gonna show you an example of using HttpClient:
var uri = "http://google.com";
var client = new HttpClient();
try
{
var values = new List<KeyValuePair<string, string>>();
// add values to data for post
values.Add(new KeyValuePair<string, string>("FirstName", "KRITZTE"));
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
// Post data
var result = await client.PostAsync(uri, content);
// Access content as stream which you can read into some string
Console.WriteLine(result.Content);
// Access the result status code
Console.WriteLine(result.StatusCode);
}
catch(AggregateException ex)
{
// get all possible exceptions which are thrown
foreach (var item in ex.Flatten().InnerExceptions)
{
Console.WriteLine(item.Message);
}
}