Non Blocking UI with Gmail Api in Winrt - windows-runtime

I am developing an gmail client in uwp and want to use gmail api but the want the get messages asynchronous wihout blocking the ui the following method blocks the ui.
public async Task<IEnumerable<Message>> GetMessagesAsync(string userId, string labelId, long maxResults)
{
await AuthenticateAsync();
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.LabelIds = labelId;
request.MaxResults = maxResults;
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
}
catch (Exception e)
{
//Console.WriteLine("An error occurred: " + e.Message);
}
return result;
}

Use Task.Run for non blocking
public async Task<IEnumerable<Message>> GetMessagesAsync(string userId, string labelId, long maxResults)
{
await AuthenticateAsync();
return await Task.Run(() =>
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.LabelIds = labelId;
request.MaxResults = maxResults;
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
}
catch (Exception e)
{
//Console.WriteLine("An error occurred: " + e.Message);
}
return result;
});
}

Related

dot net Core 3.1 API HttpRequest returns usually bad request without even sending the request

I have a strange issue with my HttpRequest, i have 2 application one is clientside and the other one is RESTAPI, the issue is i am trying to update my entity by sending a request which the content is Json
public async Task<bool> Update(string url, T obj, string id)
{
var request = new HttpRequestMessage(HttpMethod.Put, url+id);
if (obj == null || String.IsNullOrEmpty(id))
{
return false;
}
request.Content = new StringContent(JsonConvert.SerializeObject(obj),
Encoding.UTF8, "application/json");
var client = _client.CreateClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer", GetBearerToken());
HttpResponseMessage response = await client.SendAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
return true;
}
return false;
}
And here is my clientapp controller below;
[HttpPost]
public async Task<IActionResult> EditUser([FromForm] UserDTO userDTO ,string id)
{
if (!ModelState.IsValid)
{
return RedirectToAction("ErrorPage", "Error");
}
userDTO.Id = id;
await _userRepository.Update(EndPoints.UserEndPoint,userDTO,id);
return RedirectToAction("GetUsers");
}
and i dont know if it is necessary because it doesnt hit even the breakpoint but i am also showing my RESTAPI code below;
/// <summary>
/// Update user
/// </summary>
/// <param name="id"></param>
/// <param name="userDTO"></param>
/// <returns></returns>
[HttpPut("{id}")]
[Authorize(Roles = "Administrator")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateUser(string id, [FromBody] UserDTO userDTO)
{
var location = GetControllerActionNames();
try
{
_logger.LogInfo($"{location}: Requested an Update for id: {id} ");
if (string.IsNullOrEmpty(id) || userDTO == null || id != userDTO.Id)
{
_logger.LogError($"{location}: Request for Id: {id} is not sucessful");
return BadRequest();
}
if (!ModelState.IsValid)
{
_logger.LogWarn($"{location}: Data was incomplete!");
return BadRequest(ModelState);
}
var isExist = await _userRepo.IsExist(id);
if (!isExist)
{
_logger.LogWarn($"{location}: with Id: {id} is not exisist");
return NotFound();
}
var usermap = _mapper.Map<CompanyUser>(userDTO);
if (usermap == null)
{
_logger.LogWarn($"{location}: Data is empty");
return BadRequest();
}
var response = await _userRepo.Update(usermap);
if (!response)
{
_logger.LogError($"{location}: Update is failed ");
return NotFound();
}
_logger.LogInfo($"User is Updated");
return NoContent();
}
catch (Exception e)
{
return InternalError($"{location} - {e.Message} - {e.InnerException}");
}
}
RESTAPI code is working when i try with PostMan.
But from the client side where i send the request it sometimes works but usually gives bad request as response instanly i mean not even go to my RESTAPI. Can you help to resolve this strange problem.
I fixed the issue, on my API Login
Because i was using Microsoft Identity and when i use await PasswordEmailSignInAsync(userName, password, false, false); it automatically genereates application cookie on my API side and i used fiddler to capture requests and i saw there when i get an error or on my API side when the thread exits the application cookie also expires after that when i made a new request from my Client to My API it was giving the bad request on my client side instantly.
So i changed my signin method to var user = await _userManager.FindByEmailAsync(userDTO.Email); var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);
in order to avoid from the application cookie creation. I had already JWT token structure in my application but was useless because default authorized attribute was not using bearer schema and i modified my startup.cs a little help from [Authorize Attribute not working with JWT Access Token in ASP.Net Core1
and now everything works without any problem!.
[Route("login")]
[HttpPost]
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Login([FromBody] UserLoginDTO userDTO)
{
var location = GetControllerActionNames();
try
{
var userName = userDTO.Email;
var password = userDTO.Password;
_logger.LogInfo($"{location}: User:{userName} - Attempted to Login");
//var result = await PasswordEmailSignInAsync(userName, password, false, false);
var user = await _userManager.FindByEmailAsync(userDTO.Email);
var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);
if (result)
{
_logger.LogInfo($"{location}: User:{userName} Logged in Succesfully");
var tokenstring = await GenerateJSONWebToken(user);
return Ok(new { token = tokenstring });
}
_logger.LogWarn($"{location}: User:{userName} couldnt logged in ");
return Unauthorized(userDTO);
}
catch (Exception e)
{
return InternalError($"{location} - {e.Message} - {e.InnerException}");
}
}

How to get Angularjs scope variable after reloadWithDebugInfo?

I have an angularjs web page and want to get the specified element's scope. But after executing the reloadWithDebugInfo function, the result is null;
private Page _page;
private Browser _browser;
private async void button1_ClickAsync(object sender, EventArgs e)
{
try
{
await initAsync();
await test2Async();
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
private async Task initAsync()
{
_browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
ExecutablePath = #"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Timeout = 60000
});
}
private async Task test2Async()
{
try
{
_page = await _browser.NewPageAsync();
await _page.GoToAsync("https://SOME Angular JS WebPage");
await _page.EvaluateFunctionAsync(#"() => angular.reloadWithDebugInfo()");
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope() ");
// scopeContent is null. why? (the above javascript code runs successfully in the chrome dev console.)
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
These statements works well in chrome dev tools.
I expect the json content of the scope, but that is null;
Update:
sorry, I forgot something after Scope().
I want a variable in the scope, not scope itself:
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope().SomeVariable ");
The problem is that the result of the scope function is not serializable.
You would need to build a serializable object inside the EvaluateFunctionAsync and return that.

How to Store Object to windows phone 8.1

In wp8.0 we can store object to IsolatedStorageSettings. wp8.1 object was not storing. Is there any way to store object to wp8.1.
WRITE OBJECT CODE
NewsList = new ObservableCollection<New>(e.News);
var FileName = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync(FileName,CreationCollisionOption.ReplaceExisting);
IRandomAccessStream sessionRandomAccess = await file.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
serializer.WriteObject(sessionOutputStream.AsStreamForWrite(), NewsList);
READ OBJECT CODE
var FileNameNews = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var newsFile = await localFolder.GetFileAsync(FileNameNews);
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
newsVM = new NewsViewModel();
NewsVM.NewsList = (ObservableCollection<New>)serializer.ReadObject(sessionInputStream.AsStreamForRead());
im getting error on this link
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
What mistake is there this code??
Thanks
This is how I do it. No using statements. I try to avoid the Stream syntax as much as possible.
Your error is very likely either because of concurrency (accessing the same file at the same time will throw an exception), or because the stream was not closed properly. I think it is the latter.
You do not dispose of your Stream objects properly (learn the using () {} syntax), which means that the stream remains OPEN after you're done writing. That means you hit the concurrency issue the second time you write, because you're trying to access a stream that's already open.
public async Task CreateOrUpdateData(string key, object o)
{
try
{
if (o != null)
{
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.ReplaceExisting);
var outputString = JToken.FromObject(o).ToString();
await FileIO.WriteTextAsync(sessionFile, outputString);
}
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
}
public async Task<T> GetDataOrDefault<T>(string key, T defaultValue)
{
try
{
T results = defaultValue;
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.OpenIfExists);
var data = await FileIO.ReadTextAsync(sessionFile);
if (!String.IsNullOrWhiteSpace(data))
{
results = JToken.Parse(data).ToObject<T>();
}
return results;
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
return defaultValue;
}

Windows phone httpclient not working

I have the following code. The async call never returns anything. Even for google.com.
try
{
using (
var client = new HttpClient()) {
var response = client.GetAsync("http://www.google.com");
Debug.WriteLine("Coming here1"+response.Result.IsSuccessStatusCode);
if (response.Result.IsSuccessStatusCode)
{
// by calling .Result you are performing a synchronous call
Debug.WriteLine("Coming here1");
var responseContent = response.Result.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
//Console.WriteLine(responseString);
}
else { Debug.WriteLine("else"); }
}
}
catch(Exception e)
{
Debug.WriteLine(e.ToString());
}
}
Try This
try{
WebClient wc = new WebClient();
wc.DownloadStringCompleted+= (sender,args) => {
Debug.WriteLine(args.results);
};
wc.DownloadStringAsync(new Uri(#"http://www.Google.com",UriKind.RelativeOrAbsolute));
}
catch(Exception e){ Debug.WriteLine(e.Message); }
You don't appear to be awaiting your Async call.
Try changing var response = client.GetAsync("http://www.google.com"); to var response = await client.GetAsync("http://www.google.com");
Remember to mark your method as async.
you're also blocking on your async call ReadAsStringAsync().Result. As with client.GetAsync, make sure to await the call instead of blocking with Result. This blog post speaks a bit on the topic.
Read up a bit on async/await. You'll love it once you get the hang of it.

restlet client side POST request with header and JSON

Could you please comment what wrong with this client side restlet code.
It is necessary:
Add HTTP header X-MF-Auth-Token with value token
Place JSON file to the body of HTTP request
Make POST request to server
Post request generates "400" error. Thank you very much!
ClientResource cr = new ClientResource(servername + "/json/place");
cr.getRequest().getAttributes().put("X-MF-Auth-Token", token);
Form form = new Form ();
form.add("Category", "");
form.add("CategoryId", "A1EECAB9-3E66-4F14-92E9-465EDFB22BA7");
form.add("Latitude", "0");
form.add("Longitude", "0");
form.add("Name", "Loremipsum");
form.add("PlaceId", "00000000-0000-0000-0000-000000000099");
cr.post(form, MediaType.APPLICATION_JSON);
if (cr.getStatus().isSuccess()) {
// Register Successful
Log.v("Register()", "Successeful");
return true;
} else {
Log.v("Register()", "ERROR");
return false;
}
} catch (ResourceException e) {
// Login Error
Log.v("AddPlace() error:", e.getStatus().toString());
return false;
}
You can use JSONObject instead of Form:
JSONObject jo = new JSONObject();
try {
jo.add("Category", "");
jo.add("CategoryId", "A1EECAB9-3E66-4F14-92E9-465EDFB22BA7");
jo.add("Latitude", "0");
jo.add("Longitude", "0");
jo.add("Name", "Loremipsum");
jo.add("PlaceId", "00000000-0000-0000-0000-000000000099");
} catch (JSONException ex) {
}
cr.post(new JsonRepresentation(jo), MediaType.APPLICATION_JSON);
i think you're not adding X-MF-Auth-Token to the header.
try
Form headers = (Form) cr.getRequest().getAttributes("org.restlet.http.headers");
if (headers == null) {
headers = new Form();
cr.getRequest().getAttributes.put("org.restlet.http.headers", headers);
}
headers.add("X-MF-Auth-Token", token);