C# UWP UploadOperation BackgroundUploader Unable to find response - c#

string boundray = "---------------------------" + DateTime.Now.Ticks.ToString("x");
string url = HttpDomainHandling(currentUser.DomainURL) + API + "&is_multi_part_upload=true";
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n" + "Content-Type: {3}\r\n\r\n", boundray, "file", file.Name, "application/octet-stream");
string footer = string.Format("\r\n--{0}--\r\n", boundray);
Stream headerStream = GenerateStreamFromString(header);
Stream footerStream = GenerateStreamFromString(footer);
Stream dataStream = await sfile.OpenStreamForReadAsync();
MemoryStream fileDataStream = new MemoryStream();
await headerStream.CopyToAsync(fileDataStream);
await dataStream.CopyToAsync(fileDataStream);
await footerStream.CopyToAsync(fileDataStream);
fileDataStream.Position = 0;
IInputStream stream = fileDataStream.AsInputStream();
BackgroundUploader backgroundUploader = new BackgroundUploader();
backgroundUploader.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundray);
backgroundUploader.SetRequestHeader("Cookie", Constants.FELIXSESSIONID + "=" + currentUser.SessionID);
backgroundUploader.Method = "POST";
UploadOperation uploadOpration = await backgroundUploader.CreateUploadFromStreamAsync(new Uri(url), stream);
await Task.Factory.StartNew(() => CheckUploadStatus(uploadOpration, progressEvent, cts));
var result = await uploadOpration.StartAsync();
ResponseInformation info = uploadOpration.GetResponseInformation();
return info;
Unable to find json response in result and response information..where can i get this response...
I am trying to upload file to my server.. and its return upload data in json format..

Finally got the Answer
BackgroundUploader is used when you want to upload something on IP or some address and you don't want the response string from server...
BackgroundUploader can return just status code and successfully or error message info
if you want to upload something and you want you response string example JSON or XML...
need to use UWP HTTPCLIENT
//Create an HTTP client object
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
//Add a user-agent header to the GET request.
var headers = httpClient.DefaultRequestHeaders;
//The safe way to add a header value is to use the TryParseAdd method and verify the return value is true,
//especially if the header value is coming from user input.
string header = "ie";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
header = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
Uri requestUri = new Uri("http://www.contoso.com");
//Send the GET request asynchronously and retrieve the response as a string.
Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage();
string httpResponseBody = "";
try
{
//Send the GET request
httpResponse = await httpClient.GetAsync(requestUri);
httpResponse.EnsureSuccessStatusCode();
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}

Related

How to Access File Content from C# HTTPWebRequest with AutoRedirect

I'm trying to call a URL that should return an authentication token.
Data is posted to the URL and after a number of redirects returns a JSON object with a token.
I'm using C# and WPF.
Here is the excerpt from what I am doing:
HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(action);
request1.Method = "POST";
StringBuilder sb = new StringBuilder();
String boundary = "-----------------------------1721856231228";
foreach (elem in elems)
{
String nameStr = elem.GetAttribute("name");
if (nameStr != null && nameStr.Length != 0)
{
String valueStr = elem.GetAttribute("value");
sb.Append("\r\n" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"" + nameStr + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(valueStr);
}
}
sb.Append("\r\n--" + boundary + "--" + "\r\n");
String postData1 = sb.ToString();
request1.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3";
request1.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36";
request1.ContentType = "application/x-www-form-urlencoded; boundary=" + boundary;
request1.ContentLength = postData1.Length;
request1.KeepAlive = true;
request1.AllowAutoRedirect = true;
StreamWriter w = new StreamWriter(request1.GetRequestStream());
w.Write(postData1);
w.Close();
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
StreamReader reader1 = new StreamReader(response1.GetResponseStream());
String responseText1 = reader1.ReadToEnd();
reader1.Close();
response1.Close();
But the response doesn't contain the JSON with a token.
I am using Fiddler and can pause at the end of the above code and the URI that should have the JSON hasn't been called. I can continue executing other code in the debugger, and then later, Fiddler will show the URI as having been called and a File Download popup lets me then download a JSON file that contains the token.
I don't want the popup and I want to be able to capture the JSON data programmatically.
I found by adding the following line to the end of the code above, and just executing that line in the debugger, that Fiddler will report that the token URL has been called (and I can see in Fiddler the correct JSON response):
System.Windows.Forms.Application.DoEvents();
But I don't know how to access this response or how to short-circuit the file download popup from not happening.
Maybe something in the KeepAlive setting would help?
try newtonsoft to read
using Newtonsoft.Json
TokenModel tokenModel;
StreamReader reader1 = new StreamReader(response1.GetResponseStream());
using (JsonTextReader reader = new JsonTextReader(reader1))
{
tokenModel = serializer.Deserialize<TokenModel>(reader);
}
Reference: https://www.newtonsoft.com/json/help/html/ReadJson.htm
Or you can use following complete request with response with HttpClient
var client = new HttpClient();
client.BaseAddress = new Uri("your url");
int _TimeoutSec = 90;
client.Timeout = new TimeSpan(0, 0, _TimeoutSec);
string _ContentType = "application/x-www-form-urlencoded";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType));
//if you have any content to send use following keyValuePair
var kv = new List<KeyValuePair<string, string>>();
kv.Add(new KeyValuePair<string, string>("key1", "value"));
kv.Add(new KeyValuePair<string, string>("key2", "value"));
var req = new HttpRequestMessage(System.Net.Http.HttpMethod.Post, "your url") { Content = new FormUrlEncodedContent(kv) };
var responseAsyn = client.SendAsync(req);
var response = responseAsyn.GetAwaiter().GetResult();
TokenModel tokenResponse = new TokenModel();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
tokenResponse = JsonConvert.DeserializeObject<TokenModel>(responseString);
}

C# Twitter request OAuth Token

I am trying to request token from the Twitter API based on my consumer key and consumer secret key. However I am getting a The remote server returned an error: (403) Forbidden which I am not sure why?
This is my attempt so far
//Get Request Token
string oauth_consumer_key = "<consumer key>";
string oauth_consumer_secret = "<consumer secret>";
Uri requestToken = new Uri("https://api.twitter.com/oauth2/token?oauth_consumer_key=" + oauth_consumer_key + "&oauth_consumer_secret=" + oauth_consumer_secret);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requestToken);
req.Method = "POST";
try
{
using (var response = req.GetResponse() as HttpWebResponse)
if (req.HaveResponse && response != null)
{
}
}
catch (WebException wex)
{
}
The code is incomplete however running through it I always seem to get a Forbidden exception?
If I post the URL request as follows, it works fine and returns the token
https://twitter.com/oauth/request_token?oauth_consumer_key=bidjtABOkF0b3mvw1UaHWDf7x&oauth_consumer_secret=qWO208QapZvckBoyWu3QET8uFnBXXlG3tSTWSS8oAOtoY8qwHD
Am I doing something wrong?
Solved my problem by using Task / Asyc and also adding authorization OAuth headers. Now able to get access token
Here is my solution:
public async Task<ActionResult> AccessToken()
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token");
string oauth_consumer_key = "<consumer key>";
string oauth_consumer_secret = "<consumer secret>";
string url = "https://api.twitter.com/oauth2/token?oauth_consumer_key=" + oauth_consumer_key + "&oauth_consumer_secret=" + oauth_consumer_secret;
var customerInfo = Convert.ToBase64String(new UTF8Encoding()
.GetBytes(oauth_consumer_key + ":" + oauth_consumer_secret));
// Add authorization to headers
request.Headers.Add("Authorization", "Basic " + customerInfo);
request.Content = new StringContent("grant_type=client_credentials", Encoding.UTF8,
"application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.SendAsync(request);
string json = await response.Content.ReadAsStringAsync();
var serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(json);
ViewBag.access_token = item["access_token"];
return View();
}

universal windows app , making a WebRequest Method = GET

Does anyone know how to get the WebResponse ?? the method GetResponse() is obsolet, btw it's windows universal app.
Uri uri = new Uri("myuri");
HttpClient httpclient = new HttpClient();
HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(uri);
httpclient.DefaultRequestHeaders.Add("name", "value");
httpclient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
webrequest.Method = "GET";
HttpWebResponse response = webrequest.GetResponseAsync();
StreamReader streamReader1 = new StreamReader(response.GetResponseStream());
solved:
solved with this: private async void Start_Click(object sender, RoutedEventArgs e)
{
response = new HttpResponseMessage();
outputView.Text = "";
httpClient.DefaultRequestHeaders.Add("name", "value");
// The value of 'InputAddress' is set by the user and is therefore untrusted input.
// If we can't create a valid URI,
// We notify the user about the incorrect input.
Uri resourceUri = new Uri("myuri")
string responseBodyAsText;
try
{
response = await httpClient.GetAsync(resourceUri);
response.EnsureSuccessStatusCode();
responseBodyAsText = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
// Need to convert int HResult to hex string
statusText.Text = "Error = " + ex.HResult.ToString("X") +
" Message: " + ex.Message;
responseBodyAsText = "";
}
// Format the HTTP response to display better
responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine);
outputView.Text = responseBodyAsText;
You need to include the await keyword.
HttpWebResponse response = await webrequest.GetResponseAsync();

Upload audio file to soundcloud using c#

WebClient client = new WebClient();
string postData = "client_id=" + "b408123adf1e3a950876d84475587ca2"
+ "&client_secret=" + "d74a342169f5f5b369622d582f77b09e"
+ "&grant_type=password&username=" + "biksad" //your username
+ "&password=" + "369789";//your password :)
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
string tokenInfo = client.UploadString(soundCloudTokenRes, postData);
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://soundcloud.com/biksad/tracks") as HttpWebRequest;
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] { new UploadFile(filePath, "#" + fileName, "application/octet-stream") };
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "biksad");
form.Add("track[sharing]", "public");
form.Add("oauth_token", tokenInfo);
form.Add("format", "json");
form.Add("Filename", fileName);
form.Add("Upload", "Submit Query");
string lblInfo;
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
lblInfo = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
lblInfo = ex.ToString();
}
I want to upload an audio file from my server to my soundcloud account. I got this error:
Cannot close stream until all bytes are written.
How can I detect "form" values correctly(track[title],track[sharing]...etc.)?
this link will show you what all the fields on that POST mean
http://developers.soundcloud.com/docs/api/reference#tracks
you can also use this tool they provide to look at what the URL should contain:
http://developers.soundcloud.com/console

Post string and bytearray to server

I have done POSTING and GETing from server using string post data, but now i have the next WebService:
submitFeedback(String token, String subject, String body, byte[] photo, byte[] video);
private void PostFeedbackData()
{
if (GS.online != true)
{
MessageBox.Show(GS.translations["ErrorMsg0"]);
}
else
{
HttpWebRequest request = HttpWebRequest.CreateHttp("https://****/feedback");
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
}
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
// End the stream request operation
Stream postStream = myRequest.EndGetRequestStream(callbackResult);
// Create the post data
string postData = "";
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
postData = "{\"jsonrpc\": \"2.0\", \"method\": \"getUserSchedule\", \"params\":[" + "\"" + (App.Current as App).UserToken + "\",\"" + FeedbackTitle.Text + "\",\"" + FeedbackContent.Text + "\",\"" + imageBytes + "\"], \"id\": 1}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
});
}
Look at post data - it is a string, i can't place there imageBytes array. How to do it?
Is there any reason for using HttpWebRequest ?
I am asking that because i think that the correct way of sending files to a service is by multipartform data. With HttpWebRequest you have to manually implement that.
Here is an example that is using Microsoft's HttpClient that might work for you:
public async Task<string> submitFeedback(String token, String subject, String body, byte[] photo, byte[] video) {
var client = new HttpClient();
var content = new MultipartFormDataContent();
// Some APIs do not support quotes in boundary field
foreach (var param in content.Headers.ContentType.Parameters.Where(param => param.Name.Equals("boundary")))
param.Value = param.Value.Replace("\"", String.Empty);
var tok = new StringContent(token);
content.Add(tok, "\"token\"");
var sub = new StringContent(subject);
content.Add(tok, "\"subject\"");
// Add the Photo
var photoContent = new StreamContent(new MemoryStream(photo));
photoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"photo\"",
FileName = "\"photoname.jpg\""
};
photoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(photoContent);
// Add the video
var videoContent = new StreamContent(new MemoryStream(video));
videoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"video\"",
FileName = "\"videoname.jpg\""
};
videoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("video/mp4");
content.Add(videoContent);
HttpResponseMessage resp;
try {
resp = await client.PostAsync("SERVER_URL_GOES_HERE", content);
}
catch (Exception e)
{
return "EXCEPTION ERROR";
}
if (resp.StatusCode != HttpStatusCode.OK)
{
return resp.StatusCode.ToString();
}
var reponse = await resp.Content.ReadAsStringAsync();
return reponse;
}
Change accordingly.
Note: HttpClient is also using HttpWebRequest under the hood.
Also I don't think its a good idea to have the UI thread making the request. That makes no sense since you are blocking the interface and making the async theory useless.

Categories

Resources