i have application that using await to retrieving data from windows azure, and using it along with retrieving data from json, so first i get data from json for the first row of the list and next list is from windows azure
private RootObjectDetail _hereRestDetail= null;
public RootObjectDetail hereRestDetail
{
get { return _hereRestDetail; }
set { this.SetProperty(ref this._hereRestDetail, value); }
}
private ObservableCollection<AddressDetail> _hereRestAddressDetail = null;
public ObservableCollection<AddressDetail> hereRestAddressDetail
{
get { return _hereRestAddressDetail; }
set { this.SetProperty(ref this._hereRestAddressDetail, value); }
}
private async void UpdateTransportDetail()
{
try
{
isBusy = true;
isBusyMessage = "Loading web server data...";
addressItem = await addressTable
//.Where(placeId = hereRestDetail.placeId )
.ToCollectionAsync();
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
RootObjectDetail result = JsonConvert.DeserializeObject<RootObjectDetail>(e.Result);
hereRestDetail = result;
hereRestAddressDetail.Clear();
hereRestAddressDetail.Insert(0,result.location.address);
var oc = new ObservableCollection<AddressDetail>();
foreach (var item in addressItem)
hereRestAddressDetail.Add(item);
}
else
{
isFailed = Visibility.Visible;
isFailedMessage = "Can't get data from web server, please refresh and make sure your internet data connected";
}
isBusy = false;
};
client.DownloadStringAsync(new Uri(hrefText + transportDetailURL));
}
catch (Exception)
{
isFailed = Visibility.Visible;
isFailedMessage = "Something wrong happen, please refresh";
}
}
but sometimes i giving me error like failed to connect to database, so maybe anyone can give me some way to making this call more efficient?
Related
I am getting this error dialog even after logging in successfully using Microsoft login.
Here is the code to authenticate :
#region IMicrosoftLogin implementation
public async System.Threading.Tasks.Task<Xamarin.Auth.Account> LoginAsync()
{
window = UIApplication.SharedApplication.KeyWindow;
viewController = window.RootViewController;
var auth = new OAuth2Authenticator(
"key_here",//for non- prod
//for production
"openid email https://graph.microsoft.com/user.read",
new Uri("https://login.microsoftonline.com/common/oauth2/V2.0/authorize"),
new Uri("https://myapp_redirect_url"),// for non- prod
null
)
{
AllowCancel = true
};
auth.Completed += Microsoft_Auth_Completed;
var tcs1 = new TaskCompletionSource<AuthenticatorCompletedEventArgs>();
d1 = (o, e) =>
{
try
{
if (e.IsAuthenticated)
{
viewController.DismissViewController(true, null);
tcs1.TrySetResult(e);
}
else
{
viewController.DismissViewController(true, null);
}
}
catch (Exception)
{
tcs1.TrySetResult(new AuthenticatorCompletedEventArgs(null));
}
};
try
{
auth.Completed += d1;
if (viewController == null)
{
while (viewController.PresentedViewController != null)
viewController = viewController.PresentedViewController;
viewController.PresentViewController(auth.GetUI(), true, null);
}
else
{
viewController.PresentViewController(auth.GetUI(), true, null);
UserDialogs.Instance.HideLoading();
}
var result = await tcs1.Task;
return result.Account;
}
catch (Exception)
{
return null;
}
finally
{
auth.Completed -= d1;
}
//auth.Error += (object sender, AuthenticatorErrorEventArgs eventArgs) => {
// auth.IsEnabled = false;
//};
}
private void Microsoft_Auth_Completed(object sender, AuthenticatorCompletedEventArgs e)
{ /// Break point here is not getting triggered.
var authenticator = sender as OAuth1Authenticator;
if (authenticator != null)
{
authenticator.Completed -= Microsoft_Auth_Completed;
}
if (e.IsAuthenticated)
{
var a = e.Account;
}
else
{
}
}
Login async called on button click like this :
btnSignIn.Clicked += async (object sender, EventArgs e) =>
{
if (networkConnection != null && networkConnection.CheckNetworkConnection())
{
UserDialogs.Instance.ShowLoading("Loading", null);
var loginresult = await MicrosoftLogin.LoginAsync();
.....
MicrosoftLogin.cs
namespace projectnamescpace
{
public interface IMicrosoftLogin
{
Task<Account> LoginAsync();
}
}
Please help me.
I have already saw following link solutions and they aren't working for me.
https://forums.xamarin.com/discussion/5866/xamarin-auth-and-infinite-error-alerts
Authentication Error e.Message = OAuth Error = Permissions+error
https://forums.xamarin.com/discussion/95176/forms-oauth-error-after-authenticated-unable-to-add-window-token-android-os-binderproxy
The issue might be caused by the HostName been blocked because of Area Policy .
You could solve this by modifying the DNS (to 8.8.8.8 as an example) for your Mac as well.
Your device, Settings/Wi-Fi
Choose connected Wi-Fi pot
Press DHCP/DNS
Set to 8.8.8.8
Or you could connect phone to the VPN for your apps deployed to device to see corporate servers.
Having this :
public Item_DataColl invoke_command_READ(string UCPTName)
{
networkingThread = new Thread(new ParameterizedThreadStart(thread_command_READ));
networkingThread.Start(new readingThreadParameter(UCPTName));
}
private Item_DataColl thread_command_READ_result(object parameter)
{
readingThreadParameter p = parameter as readingThreadParameter;
Item item;
if (p.UCPT_Name != null)
{
Item_DataColl resultSet;
try
{
OnProgressBarUpdate(progressBar.UnknownEnd);
resultSet = connector.command_READ(p.UCPT_Name);
readOperationDone(resultSet);
OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
return resultSet; // HERE, I WANT TO RETURN RESULT
}
catch (Exception e)
{
OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
}
finally
{
OnProgressBarUpdate(progressBar.Invisible);
}
}
}
I'm trying to execute a SOAP request and to send the result. To make the application "non-blocking", i've used Thread.
The soap request works perfectly, but i have trouble to send a result just after the end of the thread. I will have to keep track of it and when the thread is over, to send back the result to another class.
How can i perform this ?
Well.. this solution CAN BE WRITTEN WAY BETTER.. but I'm currently working with the code you already posted.
The approach - using a callback (with a delegate):
First - declare a delegate in your class scope
private Action<Item_DataColl> OnResultSetComplete;
Second - assign the delegate with some function BEFORE calling your thread
public Item_DataColl invoke_command_READ(string UCPTName)
{
OnResultSetComplete = (resukts) =>
{
// DO SOMETHING HERE
};
networkingThread = new Thread(new ParameterizedThreadStart(thread_command_READ));
networkingThread.Start(new readingThreadParameter(UCPTName));
}
Finally - change your read result function:
private Item_DataColl thread_command_READ_result(object parameter)
{
readingThreadParameter p = parameter as readingThreadParameter;
Item item;
if (p.UCPT_Name != null)
{
Item_DataColl resultSet;
try
{
OnProgressBarUpdate(progressBar.UnknownEnd);
resultSet = connector.command_READ(p.UCPT_Name);
readOperationDone(resultSet);
OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
if (OnResultSetComplete != null) OnResultSetComplete(resultSet);
}
catch (Exception e)
{
OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
}
finally
{
OnProgressBarUpdate(progressBar.Invisible);
}
}
}
I need to browse a set of url adresses (yes another web scraper..).
I want to use tasks. But I have problem returning AFTER the browser is finished.
To be sure the site is fully loaded I have to jump to document_completed and from there I call the Navigate method with another url.
Something like this:
private WebBrowser browser;
private List<string> urlsToVisit;
int urlCounter = 0;
public PageBrowser(List<string> urls) //constructor
{
urlCounter = 0;
urlsToVisit = urls;
browser = new WebBrowser(); //one instance of browser for all urls
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += browser_DocumentCompleted;
}
//this I want to call from somewhere else and return true AFTER it opens all sites
public bool Run()
{
VisitPages();
return true;
}
private void VisitPages()
{
if (urlCounter < urlsToVisit.Count)
{
browser.Navigate(urlsToVisit[urlCounter]);
urlCounter++;
}
else
{
browser.Dispose();
}
}
private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath) return;
System.Threading.Thread.Sleep(3000); //random interval between requests
VisitPages();
}
I am pretty sure, the solution is very simple but I just don't see it..
Thank you
Petr
I would suggest you to use a WebClient instead of a WebBrowser UI component since you don't seem to need to render anything. It seems as you just want to send requests to your list of urls and return true if everything went well, and return false if any type of problem occured.
private async Task<bool> VisitUrls()
{
var urls = new List<string>
{
"http://stackoverflow.com",
"http://serverfault.com/",
"http://superuser.com/"
};
var success = await BrowseUrls(urls);
return success;
}
private async Task<bool> BrowseUrls(IEnumerable<string> urls)
{
var timeoutWebClient = new WebClient();
foreach (var url in urls)
{
try
{
var data = await timeoutWebClient.DownloadDataTaskAsync(url);
if (data.Length == 0) return false;
}
catch (Exception ex)
{
return false;
}
}
//Everything went well, returning true
return true;
}
i want to know how to insert MobileServiceCollection from Windows Azure to my ObservableCollection from JSON web service
private ObservableCollection<AddressDetail> _hereRestAddressDetail = null;
public ObservableCollection<AddressDetail> hereRestAddressDetail
{
get { return _hereRestAddressDetail; }
set { this.SetProperty(ref this._hereRestAddressDetail, value); }
}
private async void UpdateTransportDetail()
{
try
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
RootObjectDetail result = JsonConvert.DeserializeObject<RootObjectDetail>(e.Result);
hereRestAddressDetail.Clear();
hereRestAddressDetail.Insert(0,result);
}
else
{
isFailed = Visibility.Visible;
isFailedMessage = "Can't get data from web server, please refresh and make sure your internet data connected";
}
};
client.DownloadStringAsync(new Uri(hrefText + transportDetailURL));
hereRestAddressDetail = await addressTable.ToCollectionAsync();
}
catch (Exception)
{
isFailed = Visibility.Visible;
isFailedMessage = "Something wrong happen, please refresh";
}
}
and what i try to do is to add my azure data into the next entry of hereRestAddressDetail (since the first is from json web service) with this
hereRestAddressDetail = await addressTable.ToCollectionAsync();
but it just replace the data from json not adding it, how can i make it appear with my json data also?
Not sure if the question is still actual, but you can replace the while collection
hereRestAddressDetail = new ObservableCollection<AddressDetail>(await addressTable.ToCollectionAsync());
Or (i'd recommend this way) grab OptimizedObservableCollection ( for example, here: http://www.pedrolamas.com/2013/05/08/cimbalino-windows-phone-toolkit-updated-to-v2-3-0/ ) and use it like
hereRestAddressDetail.ReplaceWith(await addressTable.ToCollectionAsync()); // replace
or
hereRestAddressDetail.AddRange(await addressTable.ToCollectionAsync()); // add
On my windows phone 7 Mango app I use the Microsoft.Live and Microsoft.Live.Controls references to download and upload on Skydrive. Logging in and uploading files works fine but whenever I call the "client.GetAsync("/me/skydrive/files");" on the LiveConnectClient the Callback result is empty just containing the error: "An error occurred while retrieving the resource. Try again later."
I try to retrieve the list of files with this method.
This error suddenly occured without any change on the source code of the app (I think..) which worked perfectly fine for quite a while until recently. At least I didn't change the code section for up- or downloading.
I tried out the "two-step verification" of Skydrive, still the same: can log in but not download.
Also updating the Live refercences to 5.5 didn't change anything.
Here is the code I use. The error occurs in the "getDir_Callback" in the "e" variable.
Scopes (wl.skydrive wl.skydrive_update) and clientId are specified in the SignInButton which triggers "btnSignin_SessionChanged".
private void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
processing = true;
client = new LiveConnectClient(e.Session);
client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(UploadCompleted);
client.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(OnDownloadCompleted);
client.DownloadProgressChanged += new EventHandler<LiveDownloadProgressChangedEventArgs>(client_DownloadProgressChanged);
infoTextBlock.Text = "Signed in. Retrieving file IDs...";
client.GetAsync("me");
}
else
{
connected = false;
infoTextBlock.Text = "Not signed into Skydrive.";
client = null;
}
}
private void OnGetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
if (e.Error == null)
{
client.GetCompleted -= new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.GetCompleted += getDir_Callback;
client.GetAsync("/me/skydrive/files");
client_id = (string)e.Result["id"];
if (e.Result.ContainsKey("first_name") && e.Result.ContainsKey("last_name"))
{
if (e.Result["first_name"] != null && e.Result["last_name"] != null)
{
infoTextBlock.Text = "Hello, " +
e.Result["first_name"].ToString() + " " +
e.Result["last_name"].ToString() + "!";
}
}
else
{
infoTextBlock.Text = "Hello, signed-in user!";
}
}
else
{
infoTextBlock.Text = "Error calling API: " +
e.Error.ToString();
}
processing = false;
}
public void getDir_Callback(object s, LiveOperationCompletedEventArgs e)
{
client.GetCompleted -= getDir_Callback;
//filling Dictionary with IDs of every file on SkyDrive
if (e.Result != null)
ParseDir(e);
if (!String.IsNullOrEmpty(e.Error.Message))
infoTextBlock.Text = e.Error.Message;
else
infoTextBlock.Text = "File-IDs loaded";
}
Yo shall use client.GetAsync("me/SkyDrive/files", null) in place of client.GetAsync("me");
This is my code and it works fine.
private void btnSignIn_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
{
try
{
if (e.Session != null && e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(client_GetCompleted);
client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(client_UploadCompleted);
client.GetAsync("me/SkyDrive/files", null);
client.DownloadAsync("me/SkyDrive", null);
canUpload = true;
ls = e.Session;
}
else
{
if (client != null)
{
MessageBox.Show("Signed out successfully!");
client.GetCompleted -= client_GetCompleted;
client.UploadCompleted -= client_UploadCompleted;
canUpload = false;
}
else
{
canUpload = false;
}
client = null;
canUpload = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void client_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
try
{
List<System.Object> listItems = new List<object>();
if (e.Result != null)
{
listItems = e.Result["data"] as List<object>;
for (int x = 0; x < listItems.Count(); x++)
{
Dictionary<string, object> file1 = listItems[x] as Dictionary<string, object>;
string fileName = file1["name"].ToString();
if (fileName == lstmeasu[0].Title)
{
folderID = file1["id"].ToString();
folderAlredyPresent = true;
}
}
}
}
catch (Exception)
{
MessageBox.Show("An error occured in getting skydrive folders, please try again later.");
}
}
It miraculously works again without me changing any code. It seems to be resolved on the other end. I have no clue what was wrong.