Windows Store app webservice consume - c#

I have a windows phone 7 app with following code
ServiceReference1.SMSWarriorServiceSoapClient ws = new ServiceReference1.SMSWarriorServiceSoapClient();
ws.BalanceCompleted += new EventHandler<ServiceReference1.BalanceCompletedEventArgs>(ws_BalanceCompleted);
ws.BalanceAsync(textBox1.Text, textBox2.Password);
Now i want to make it also for Windows 8 store app. I try this
var client = new ServiceReference1.SMSWarriorServiceSoapClient() ;
var result = client.BalanceAsync("user", "pass");
resultDetails.Text = result.ToString ;
but with no luck
I also try the Await but I don't know how to use it

If you are calling the web service method from an event handle then use this.
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
var client = new ServiceReference1.SMSWarriorServiceSoapClient();
var result = await client.BalanceAsync("user", "pass");
resultDetails.Text = result.ToString();
}
If you are calling the web service method from a method then use this.
private async Task ServiceCall()
{
var client = new ServiceReference1.SMSWarriorServiceSoapClient();
var result = await client.BalanceAsync("user", "pass");
resultDetails.Text = result.ToString();
}
Ensure you call method ServiceCall() with await keyword.

if u use await then u must use async keyword or use Task
var client = new ServiceReference1.SMSWarriorServiceSoapClient() ;
var result = await client.BalanceAsync("user", "pass");
resultDetails.Text = result.ToString ;
for example:
// Put the keyword, async on the declaration of the event handler.
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
var respose=await <some async operation >
}

Related

Updating record in winforms using Web API

I'm pretty new to entity framework and Web services.
What I'm trying to do is updating records from winforms application by calling update method in Web API.
Httpresponse message returns bad request and doesn't update anything.
There is either a logical error with the code I wrote in api which updates records or the code I wrote in winform. I can't tell where the problem is.
Update method in API
[HttpPut]
public async Task <IActionResult> UpdateStatus ([FromBody]BookStatus entity)
{
var original = Tools.Context.BookStatus. Find(1);
Tools.Context.Entry (original).CurrentValues.SetValues (entity);
var result = await Tools.Context.SaveChangesAsync();
if (result > 0)
return Ok (result);
return Badrequest ();
}
Winform app where I call update method
private async void button3_click (object sender,EventArgs e)
{
BookStatus status = new BookStatus();
status.IsAvailable = true;
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback=(sender,cert,chain,sslPolicyError)=>{return true;};
HttpClient client = new HttpClient(clientHandler);
client.BaseAdress = new Uri ("Https://localhost:5001");
var serialize = JsonConvert.SerializeObject (status);
var content = new StringContent(serialize,Encoding.UTF8,"application/json");
var result = await client.PutAsJsonAsync ("api/BookStatus/UpdateStatus",content);
Message.Text = result.StatusCode.ToString ()";
}
I checked your codes and it seems that there was someting wrong with PutAsJsonAsync method ,and the webapi could not get the value of bookstatus.
I modified the codes in your winform client,and the webapi could get the value
private void button1_Click(object sender, EventArgs e)
{
BookStatus status = new BookStatus();
status.Id = 1;
status.IsAvailable = true;
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyError) => { return true; };
HttpClient client = new HttpClient(clientHandler);
var result1 = client.PutAsJsonAsync<BookStatus>("https://localhost:44318/WeatherForecast", status).Result;
}
Result:
And if you need help for your codes in your webapi project,you could tell me more details of your project such as your model class and Dbcontext

How to execute async/await command that can show result

I tried the below code to execute command in Task.Run.
SshClient ssh;
public Form1()
{
InitializeComponent();
//BackGround Login is needed.
ConnectionInfo info = new ConnectionInfo(hostNameOrIpAddr, portNo, userName,
new AuthenticationMethod[] {
new PasswordAuthenticationMethod(userName, passWord)
ssh = new SshClient(info);
ssh.Connect();
cmd = ssh.CreateCommand(commandString);
}
private void button1_Click(object sender, EventArgs e)
{
Task.Run(()=>{
SshCommand cmd = ssh.CreateCommand(commandString);
cmd.Execute();
Console.WriteLine(cmd.Result.ToString());
;});
}
But it doesn't work well.
The reason is probably to Dispose the stream immediatly after starting the task.
One of the ways to use async/await is as following:
Note: The async keyword turns a method into an async method, which allows you to use the await keyword in its body.
private async void button1_Click(object sender, EventArgs e) {
var result = await Task.Run(() => RunSshCmd());
Console.WriteLine(result);
}
Let's say running ssh command will take 5 seconds to finish, just example.
private string RunSshCmd() {
Thread.Sleep(5000);
return "Done.";
}
Note: await can only be used inside an async method.

Wait until activity was closed

I use Xamarin Auth to authenticate with OneDrive in my android app. I assume this would work, but I have the issue that when the activity for the login prompt is opened the programm will just continue and not wait for the auth to finish.
How can I wait until it's closed or wrap this in a other way async?
Code:
private IDictionary<string, string> authenticationResponseValues;
protected override async Task<AccountSession> GetAuthenticationResultAsync()
{
await Task.Run(() => ShowWebView());
return new AccountSession(authenticationResponseValues, this.ServiceInfo.AppId, AccountType.MicrosoftAccount)
{
CanSignOut = true
};
}
private void ShowWebView()
{
var auth = new OAuth2Authenticator(
clientId: MSA_CLIENT_ID,
scope: string.Join(",", scopes),
authorizeUrl: new Uri(GetAuthorizeUrl()),
redirectUrl: new Uri(RETURN_URL));
auth.Completed += SetAccountInfos;
var intent = auth.GetUI(Application.Context);
intent.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(intent);
}
private void SetAccountInfos(object sender, AuthenticatorCompletedEventArgs eventArgs)
{
if (eventArgs.IsAuthenticated)
{
Debug.WriteLine(eventArgs);
Debug.WriteLine(eventArgs.Account == null ? "IS NULL" : "IS NOT NULL");
if (eventArgs.Account != null)
{
OAuthErrorHandler.ThrowIfError(eventArgs.Account.Properties);
authenticationResponseValues = eventArgs.Account.Properties;
}
}
}
I dont think using async tactic is reasonable, because app runs before login result returns.
Try to use sync way. Make a login page. If success, then switch to your real app.
I found a solution. Here my code:
await ShowWebView();
return new AccountSession(authenticationResponseValues, ServiceInfo.AppId,
AccountType.MicrosoftAccount)
{
CanSignOut = true
};
private Task<bool> ShowWebView()
{
var tcs = new TaskCompletionSource<bool>();
var auth = new OAuth2Authenticator(OneDriveAuthenticationConstants.MSA_CLIENT_ID, string.Join(",", OneDriveAuthenticationConstants.Scopes), new Uri(GetAuthorizeUrl()),
new Uri(OneDriveAuthenticationConstants.RETURN_URL));
auth.Completed += (sender, eventArgs) =>
{
if (eventArgs.IsAuthenticated)
{
OAuthErrorHandler.ThrowIfError(eventArgs.Account.Properties);
authenticationResponseValues = eventArgs.Account.Properties;
tcs.SetResult(true);
}
};
var intent = auth.GetUI(Application.Context);
intent.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(intent);
return tcs.Task;
}
And the link to the class in the repo: https://github.com/Apply-Solutions/MoneyManager/blob/master/Src/MoneyManager.Droid/Src/AndroidAuthenticationProvider.cs

http request not working in nested async Task<T> methods

I'm working with async tasks for the first time, and I'm confronted with a problem I can't seem to solve.
i've got a method to call an API using a Http request.
internal static async Task<HttpResponse> CallAPI(string objectname, string parameters, HttpMethod method)
{
HttpResponse r = new HttpResponse();
using (r.HttpClient = new HttpClient())
{
r.HttpClient.BaseAddress = new Uri("https://" + Properties.Settings.Default.APIURL + "/");
r.HttpClient.DefaultRequestHeaders.Clear();
r.HttpClient.DefaultRequestHeaders.Add("Accept", "application/vnd+json;version=1");
r.HttpClient.DefaultRequestHeaders.Add("Host", Properties.Settings.Default.APIURL);
r.HttpClient.DefaultRequestHeaders.Add("Expect", "100-continue");
r.HttpClient.DefaultRequestHeaders.Add("Connection", "Close");
switch (method)
{
case HttpMethod.DELETE:
using (r.ResponseMessage = await r.HttpClient.DeleteAsync("api/" + objectname.ToString() + "/" + parameters))
{
var stopwatch = Stopwatch.StartNew();
r.responseTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
r.ResponseData = await r.ResponseMessage.Content.ReadAsStringAsync();
return r;
}
case HttpMethod.GET:
using (r.ResponseMessage = await r.HttpClient.GetAsync("api/" + objectname.ToString() + parameters))
{
var stopwatch = Stopwatch.StartNew();
r.responseTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
r.ResponseData = await r.ResponseMessage.Content.ReadAsStringAsync();
return r;
}
default: throw new Exception("No HTTP Method Found");
}
}
I call a delete() method in the class from a button click event:
protected void btnDelete_Click(object sender, EventArgs e)
{
Activity a = new Activity();
a.Id = Convert.ToInt32(txtObjectId.text);
//a.Delete(); //void method
bool done = a.Delete().Result; //Task<bool> method
}
if I make the delete() method a void, it works fine and returns the http response
public async virtual void Delete()
{
HttpResponse r = new HttpResponse();
r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE);
}
but if I try to make Delete() a Task,
public async virtual Task<bool> Delete()
{
try
{
HttpResponse r = new HttpResponse();
r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE);
return true;
}
catch
{
return false;
}
}
it tries to execute the httpclient.deleteasync method and the app just doens't do anything. I don't get an exception, it doens't freeze, it just doens't seem to do anything anymore.
I have no idea what's causing this behavior, but I'm fairly new to async programming, so I'm probably doing something which I'm not supposed to :-)
If you do .Result or .Wait() on code that uses async/await you will deadlock your program, you must make your event handler async void, this is the only place you are allowed to use async void.
protected async void btnDelete_Click(object sender, EventArgs e)
{
Activity a = new Activity();
a.Id = Convert.ToInt32(txtObjectId.text);
//await a.Delete(); //Task method
bool done = await a.Delete(); //Task<bool> method
}
And in case you do end up using the version that does not return Task<bool> the Delete() function would look like
public async virtual Task Delete()
{
HttpResponse r = new HttpResponse();
r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE);
}
you do not need a return statement.
Also, if you don't need to access the UI, add .ConfigurateAwait(false) to each await call to make it not force the UI thread for it's continuations.
public async virtual Task Delete()
{
HttpResponse r = new HttpResponse();
r = await CallAPI(_Objectname.ToString(), _Id.ToString(), HttpMethod.DELETE).ConfigureAwait(false);
}
You can do the same to CallAPI too to make it run better.

WP8 async method in scheduled task

I am trying to make live tile which uses data from DownloadStringAsync method.
protected override void OnInvoke(ScheduledTask task){
WebClient web = new WebClient();
web.DownloadStringAsync(new Uri("website"));
web.DownloadStringCompleted += web_DownloadStringCompleted;
StandardTileData data = new StandardTileData();
ShellTile tile = ShellTile.ActiveTiles.First();
data.BackContent = string;
tile.Update(data);
}
void web_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
string=e.result ;
} // example
string is returning null all the time. I think it is because of async operation. Somehow if I can make it sync maybe it can work. any ideas ? thanks
You have a Race Condition Since the download operation is asynchronous, the 'string' variable (which should not compile BTW) will not necessary be updated when you will read it's value to set the BackContent.
Try this with the Async/Await keywords:
protected async override void OnInvoke(ScheduledTask task)
{
var web = new Webclient();
var result = await web.DownloadStringTaskAsync(new Uri("website"));
StandardTileData data = new StandardTileData();
ShellTile tile = ShellTile.ActiveTiles.First();
data.BackContent = result;
tile.Update(data);
}
If you can't use DownloadStringTaskAsync in your WP8 App, then try using TaskCompletionSource to accomplish the same thing, as exampled in this post .
protected async override void OnInvoke(ScheduledTask task)
{
var result = await DownloadStringTaskAsync (new Uri("website"));
StandardTileData data = new StandardTileData();
ShellTile tile = ShellTile.ActiveTiles.First();
data.BackContent = result;
tile.Update(data);
}
public Task<string> DownloadStringTaskAsync(Uri address)
{
var tcs = new TaskCompletionSource<string>();
var client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
tcs.SetResult(e.Result);
}
else
{
tcs.SetException(e.Error);
}
};
client.DownloadStringAsync(address);
return tcs.Task;
}
Here are an example 1 & example 2 & example 3 from MSDN for using the Async/Await keyword with WebClient in Windows Phone 8.
Since you are using WP8, then you might need to add the Nuget package for the Async/Await keyword. just run
install-package Microsoft.Bcl.Async
In the Package Manager Console. Or use Nuget GUI to download it (search for 'async')

Categories

Resources