Issue with HttpClient.GetStringAsync method in windows phone 8.1 - windows

private async void refresh_Tapped(object sender, TappedRoutedEventArgs e)
{
httpclient.CancelPendingRequests();
string url = "http://gensav.altervista.org/";
var source = await httpclient.GetStringAsync(url); //PROBLEM
source = WebUtility.HtmlDecode(source);
HtmlDocument result = new HtmlDocument();
result.LoadHtml(source);
List<HtmlNode> toftitle = result.DocumentNode.Descendants().Where
(x => (x.Attributes["style"] != null
&& x.Attributes["style"].Value.Contains("font-size:14px;line-height:20px;margin-bottom:10px;"))).ToList();
var li = toftitle[0].InnerHtml.Replace("<br>", "\n");
li = li.Replace("<span style=\"text-transform: uppercase\">", "");
li = li.Replace("</span>", "");
postTextBlock.Text = li;
}
What this code does is basically retrieve a string from a website (HTML source which is parsed right after). This code is executed whenever i click a button: the first time i click it it works correctly, but the second time i think that the method (GetStringAsync) returns an uncompleted task and then execution continues using the old value of source. Indeed, my TextBlock does not update.
Any solution?

You get probably a cached response.
May this will work for you:
httpclient.CancelPendingRequests();
// disable caching
httpclient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
string url = "http://gensav.altervista.org/";
var source = await httpclient.GetStringAsync(url);
...
You can also add a meaningless value to your url like this:
string url = "http://gensav.altervista.org/" + "?nocahce=" + Guid.NewGuid();

To prevent Http responses from getting cached, I do this (in WP8.1):
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.CacheControl.ReadBehavior =
Windows.Web.Http.Filters.HttpCacheReadBehavior.MostRecent;
filter.CacheControl.WriteBehavior =
Windows.Web.Http.Filters.HttpCacheWriteBehavior.NoCache;
_httpClient = new HttpClient(filter);
Initialize your HttpClient in this manner to prevent caching behaviour.

Related

Android post image to Facebook comment

This is a followup to my previous question: Xamarin.Forms App return data to calling App
That works perfectly and I can share images to anywhere, except to Facebook comments. When I click the camera on the content box the app can be selected, I can select the image, Set result and Finish are called, and the app closes and it sends data to Facebook, and then however I then get the error : The image could not be uploaded, try again?
I can't find any fundamental differences between posting to a status or a comment, so I'm guessing it's subtle. Any thoughts on how I can change my intent to post properly?
Adding for completeness:
Bitmap b = null;
string url;
if (!string.IsNullOrEmpty(this.saleItems[i].ImageUrl))
{
url = this.saleItems[i].ImageUrl;
}
else
{
url = await FileHelper.GetLocalFilePathAsync(this.saleItems[i].Id);
}
//download
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
b = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
//set local path
var tempFilename = "test.png";
var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var filePath = System.IO.Path.Combine(sdCardPath, tempFilename);
using (var os = new FileStream(filePath, FileMode.Create))
{
b.Compress(Bitmap.CompressFormat.Png, 100, os);
}
b.Dispose();
var imageUri = Android.Net.Uri.Parse($"file://{sdCardPath}/{tempFilename}");
var sharingIntent = new Intent();
sharingIntent.SetAction(Intent.ActionSend);
sharingIntent.SetType("image/*");
sharingIntent.PutExtra(Intent.ExtraText, "some txt content");
sharingIntent.PutExtra(Intent.ExtraStream, imageUri);
sharingIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
//await SaleItemDataService.Instance.BuySaleItemAsync(this.saleItem);
SetResult(Result.Ok, sharingIntent);
Finish();
Use below:
Intent sharingIntent = new Intent();
string imageUri = "file://" + requestedUri;
sharingIntent.SetData(Android.Net.Uri.Parse(imageUri));

WebAPI HttpContext is Null Inside ContinueWith() => tast

I'm just wondering if someone could explain what is happening here.
Given this Post method on an API controller:
public HttpResponseMessage PostImage()
{
var request = HttpContext.Current.Request;
var c = SynchronizationContext.Current;
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
{
MultipartMemoryStreamProvider provider = task.Result;
foreach (HttpContent content in provider.Contents)
{
Stream stream = content.ReadAsStreamAsync().Result;
Image image = Image.FromStream(stream);
var uploadFileName = content.Headers.ContentDisposition.FileName;
var requestInside = HttpContext.Current.Request; // this is always null
string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);
//string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");
string fileName = userprofile.UserCode + ".jpg";
string fullPath = Path.Combine(filePath, fileName);
image.Save(fullPath);
}
});
return result;
}
}
Why would var requestInside = HttpContext.Current.Request; be null?
I've checked all the relevant settings:
<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5"
And SynchronizationContext.Current is the newer AspNetSynchronizationContext rather than LegacyAspNetSynchronizationContext.
I'm presuming at the moment that it's because I'm on a different thread, is this a correct assumption?
ContinueWith is not guaranteed to run on the same thread hence the synchronization context could be lost. You could change your call to specify to resume on the current thread with parameter TaskScheduler.Current. See this previous SO answer.
If you use await/async pattern it will automatically capture the current syncronization context on resume once an awaitable operation completes. This is done by resuming the operation on the same thread which is bound to that context. An added benefit, IMHO, is cleaner looking code.
You can change your code to this which uses that pattern. I have not made any other changes to it other than use async/await.
public async Task<HttpResponseMessage> PostImage()
{
var request = HttpContext.Current.Request;
var c = SynchronizationContext.Current;
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
MultipartMemoryStreamProvider provider = await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider());
foreach (HttpContent content in provider.Contents)
{
Stream stream = await content.ReadAsStreamAsync();
Image image = Image.FromStream(stream);
var uploadFileName = content.Headers.ContentDisposition.FileName;
var requestInside = HttpContext.Current.Request; // this is always null
string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);
//string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");
string fileName = userprofile.UserCode + ".jpg";
string fullPath = Path.Combine(filePath, fileName);
image.Save(fullPath);
}
}
return result;
}

Using the API licenseCloud, and incoporating it with your aps and web pages

I tried using the licenseCloud API but was una ble to get it right, the only guess I came to was the fact that I obtained an XML and a link to that XML "https://secure.licenseapi.com/?token=73af9d231e354e2c9ba30a72fdc68341b88613c1&sku=EXAMPLE&license=e59d6fd6629044f4ace4", so I took the link, placed in a textbox and on a buttonclick fires.
XDocument csvDocument = XDocument.Load(txtActivateFromSite.Text);
var samples = csvDocument.Descendants("license")
.Select(el => new
{
Id = el.Element("dashed").Value,
Selected = el.Element("status").Value,
Selected1 = el.Element("trial").Value,
Selected2 = el.Element("expires").Value,
Selected3 = el.Element("activated").Value
});
string dashed = ""; string status = ""; string trial = ""; string expires = ""; string activated = "";
foreach (var sample in samples)
{
dashed = sample.Id;
status = sample.Selected;
trial = sample.Selected1;
expires = sample.Selected2;
activated = sample.Selected3;
}
MessageBox.Show("your Application has been activate with License Number " + dashed + " on " + activated + " expires on "+
expires + ".");
Somehow I incoporated it to get something, please anymore ideas on how to use licensecloud
Appears you've forgotten the CMD parameter on your link:
&cmd=activate...
Also, you can download some sample code here (in PHP). Will give you a good idea on how to get it to work:
https://www.licensecloud.com/2015/04/10/licensecloud-protect-web-page/

square Connect API Batch

I am using .NET to list the payments from my square account.
I am able to get a list of the payments, but to get the description field I have to go one level deeper and make http end point calls for each payment. This is time consuming.
Question: Can anyone provide me with a sample in Visual C# or Java to make batch calls for retrieving payments (using multiple payment id's)?
Your help is greatly appreciated.
Thanks,
Prashant
#Andrew - Here's what I am using, I am just not sure how to add the headers for batch payments retrieval.
string res = string.Empty;
string qs = string.Empty;
foreach (string s in parameters.Keys)
{
if (qs == string.Empty)
qs = "?";
else
qs += "&";
qs += s + "=" + parameters[s];
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_connectUrl + "/" + command + qs); ///
request.Proxy = null;
request.Headers.Add("Authorization", "Bearer " + _accessToken);// ");
request.ContentType = "application/json";
request.Method = method; // "GET";
try { HttpWebResponse responseGet = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(responseGet.GetResponseStream());
StringBuilder output = new StringBuilder();
output.Append(reader.ReadToEnd());
responseGet.Close();
request = null;
return output.ToString();
}
catch (Exception exp)
Looks like I've been able to answer my own query.
We need to be able to send the following POST to the HTTP Endpoint
{"requests":[{"method":"GET","relative_path":"/v1/me/payments/<payment_id>","access_token":"XXXX","request_id":"1"},{"method":"GET","relative_path":"/v1/me/payments/<payment_id>","access_token":"XXXX","request_id":"2"}]}
the following code in .NET achieves the above
//Convert the body of request into a byte array
byte[] byteArray = Encoding.UTF8.GetBytes(body);
//Set the length
request.ContentLength = byteArray.Length;
//Write the body to the request by using a datastream
//This line never returns....
Stream datastream = request.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
And that's all there is to it.
Hope this helps anyone is is set out to use the batch mode.
Thanks

HtmlUnit error will not get second page after javascript?

Somebody please explain why am getting null pointer exception
HtmlPage page = null;
boolean savePagesLocally = false;
String url = "http://example.com";
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
webClient.setThrowExceptionOnScriptError(false);
try
{
page = webClient.getPage( url );
HtmlRadioButtonInput radioButton2 = (HtmlRadioButtonInput) page.getElementById("ctl00_phContent_ucUnifiedSearch_rdoIndvl");
radioButton2.click();
HtmlTextInput textField3 = (HtmlTextInput) page.getElementById("ctl00_phContent_ucUnifiedSearch_txtIndvl");
textField3.setValueAttribute("1061726"); // null pointer occurs here!
For those who would like to know:
Replacing the line
HtmlTextInput textField3 = (HtmlTextInput) page.getElementById("ctl00_phContent_ucUnifiedSearch_txtIndvl");
With the following loop:
HtmlTextInput textField3 = (HtmlTextInput) page.getElementById("ctl00_phContent_ucUnifiedSearch_txtIndvl");
while(textField3 != null) {
webClient.waitForBackgroundJavaScript(100)
textField3 = (HtmlTextInput) page.getElementById("ctl00_phContent_ucUnifiedSearch_txtIndvl");
}
This loop will wait until HTMLUnit has an element by that ID.

Resources