Blazor Reload Main Page After NavigateTo (Delay) - c#

I will try to explain but I'm not sure how to ask because I'm not understanding what is happening.
In my Blazor application I have a component inside another, something like this:
<RadzenStepsItem Disabled="true" Text="Etapa 3">
<SelfWebApi.Client.Pages.FuncionarioDependente.Dependentes Admissao=true>
</SelfWebApi.Client.Pages.FuncionarioDependente.Dependentes>
<RadzenTemplateForm TItem="FuncionarioDto" Data="#funcionario" Submit="HandleClickSalvar">
<div class="row justify-content-center pt-4 pb-4">
<RadzenButton Text="VOLTAR AO PASSO ANTERIOR" ButtonStyle="ButtonStyle.Secondary" Class="btn-iniciar-cadastro" Click="#HandleClickVoltarPasso" />
<RadzenButton Text="SALVAR E AVANÇAR" ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Secondary" Class="btn-iniciar-cadastro" />
</div>
</RadzenTemplateForm>
</RadzenStepsItem>
In the child component I can insert, edit and delete data. When I delete I call:
public async void HandleClickExcluir(int dependenteId)
{
var utils = new Utils();
var result = utils.Excluir(dependenteId, "api/FuncionarioDependente/DeleteDependente", "Carregando...", authStateProvider, navigationManager, httpClient);
if (Admissao)
navigationManager.NavigateTo("/admissao", true);
else
navigationManager.NavigateTo("/dependentes", true);
}
This returns to the load of the main component. And there I do:
private async void LoadFuncionario()
{
funcionario = null;
var customAuthStateProvider = (CustomAuthenticationStateProvider)authStateProvider;
var loginId = await customAuthStateProvider.GetLoginIdAsync();
var utils = new Utils();
funcionario = await utils.Obter<FuncionarioDto>($"api/Funcionario/GetFuncionario?loginId={loginId}", funcionario, authStateProvider, navigationManager, httpClient);
foto = funcionario.Documentos.FirstOrDefault(p => p.Tipo == TipoDocumentoEnum.Foto);
if (funcionario.TerceiraEtapa)
this.index = 2;
else if (funcionario.SegundaEtapa)
this.index = 1;
else if (funcionario.PrimeiraEtapa)
this.index = 0;
if (!String.IsNullOrEmpty(funcionario.DataNascimento))
idade = CalculaIdade(funcionario.DataNascimento);
await Task.Delay(4000); // Here is the "problem"
StateHasChanged();
}
I'm trying to understand. If I put the Task.Delay everything works fine, but if I remove it the page does not render.
I think it's related to some data load, but honestly I have no idea how to fix it.
Does anyone knows or have a idea how can I solve this?
Thanks.
Best regards.

Related

Getting multiple documents in firebase functions

I am trying to figure out how to loop through multiple documents, fetched in a firebase cloud function, in Unity, but not sure how?
Here is my cloud script:
exports.getUserData = functions.https.onCall(async(data, context) => {
if (!context.auth) {
throw new functions.HttpsError(
'unauthenticated',
'only autehnticated users can make requests!'
);
}
const userData = await admin.firestore().collection('users').get(data.userid);
const myGroupMemberships = await admin.firestore().collection('groupMembers').where("playerId", "==", data.userid).get();
var myGroups = [];
myGroupMemberships.forEach(group => {
const thisGroup = admin.firestore().collection('groups').get(group.groupId);
myGroups.push(thisGroup);
})
return { "groups": myGroups };
});
As you can see, I first have to find the memberships for the user in "groupMembers", then loop through the records to get the group documents. I am not sure I am sending them correct, but thought that putting them in an array would be easies!?! Not sure thats the case.
In my Unity script I try to get them like this:
var func = FirebaseManager.instance.functions.GetHttpsCallable("getUserData");
var data = new Dictionary<string, object>();
data["userid"] = userId;
var task = func.CallAsync(data).ContinueWithOnMainThread((callTask) => {
if (callTask.IsFaulted)
{
// The function unexpectedly failed.
GA.Log("FAILED!");
GA.Log(string.Format(" Error: {0}", callTask.Exception));
return;
}
var result = (IDictionary)callTask.Result.Data;
// The function succeeded.
GA.Log(string.Format("Whats in the groups: {0}", result["groups"]));
List<Group> theGroups = result["groups"] as List<Group>;
foreach (Group thisGroup in theGroups)
{
GA.Log("GroupName: " + thisGroup.groupName);
}
});
yield return new WaitUntil(() => task.IsCompleted);
The log: Whats in the groups returns this: System.Collections.Generic.List`1[System.Object]
I do not get any logs on the "Groupname" inside the foreach loop!
Where am going wrong and how should I accomplish this?
Any help is appreciated and thanks in advance :-)

WindowHandles not working on IE: Not switching to new tab

I need to open a link in a new tab and get back to the original tab; however, it seems like the WindowHandle is not working properly. The code below only opens a new tab and then loads the link in the original tab without switching to it.
driver.FindElement(By.CssSelector("body")).SendKeys(Keys.Control + "t");
driver.SwitchTo().Window(driver.WindowHandles.Last());
driver.Navigate().GoToUrl("https://bi7-azure.accenture.com/");
driver.SwitchTo().Window(driver.WindowHandles.First());
Alternatively, I read that there is a new feature that does this in a much easier and simple way, but it doesn't work as well (I'm missing a dependency or something), and I don't see a lot of articles about it. It would be great if there's a way I can use this instead, or if not then how can I overcome the issue with WindowHandles. Please note as well that I've already configured IE properly and added the necessary registry edit as per most of the forums on the internet says.
driver.SwitchTo().newWindow(WindowType.TAB);
I know there are duplicate questions for this, but most of them are old so please bear with me.
Try this..
public static string SwitchToTab()
{
var mainHandle = driver.CurrentWindowHandle;
var handles = driver.WindowHandles;
foreach (var handle in handles)
{
if (mainHandle == handle)
{
continue;
}
driver.SwitchTo().Window(handle);
break;
}
var result = Url;
return result;
}
Then...
public static void GoToMainHandle()
{
var handles = driver.WindowHandles;
foreach (var handle in handles)
{
driver.SwitchTo().Window(handle);
break;
}
}
you can also use:
public static void CloseTab()
{
var mainHandle = driver.CurrentWindowHandle;
var handles = driver.WindowHandles;
foreach (var handle in handles)
{
if (mainHandle == handle)
{
continue;
}
driver.SwitchTo().Window(handle);
driver.Close();
driver.SwitchTo().Window(mainHandle);
break;
}
}
You may need to wait for the window to be loaded, before you switch to that window. Here's an extension method, that will do that:
public static SwitchToWindow(this IWebDriver #this, string windowTitle)
{
var tryCount = 0;
while (!#this.WindowHandles.Any(x => #this.SwitchTo().Window(x).Title.StartsWith(windowTitle)))
{
Thread.Sleep(500);
if (tryCount == 60)
throw new NoSuchWindowException($"No window with title {windowTitle} found.");
tryCount=+1;
}
#this.Manage().Window.Maximize();
}

AspNet Core TestServer DbContext.Update(model) doen't save changes

I currently try to create an integration test which tests an edit step. Editing works (changes are saved in the database, editing works during normal program usage), but the changes are not "stored" in the test-dbcontext. Therefore, if I get the edited model from the context again, it still has the old values.
Further additions to the dbcontext (AuditChange) are visible in the test method though.
I have tried other databases (Sqlite, InMemoryDatabase), but still the same problem.
Do I miss something, or is this some "funny" bug somewhere?
Regards
Matthias
Somewhat shortened Test Method:
[TestMethod]
public async Task LocalUserCompleteRunHandlingTestAsync() {
TestServer server = GetTestServer("CompleteRunHandling");
MySqlDbContext context = server.Host.Services.GetService<MySqlDbContext>();
try {
// Creating model and asserting of newly created model removed.
// Get Edit
var editGetResult = await client.GetAsync("/Fruit/Edit/" + fruit.Id);
Assert.IsTrue(editGetResult.IsSuccessStatusCode);
// Post Edit
formTokenVal = await editGetResult.GetAntiForgeryFormToken();
var editedName = "edited Name";
var editedComment = "edited Comment";
var postEditData = new Dictionary<string, string>();
postEditData.Add("Id", fruit.Id.ToString());
postEditData.Add("Name", editedName);
postEditData.Add("Comment", editedComment);
postEditData.Add(formTokenVal.Key, formTokenVal.Value);
var editPostResult = await client.PostAsync("/Fruit/Edit/" + fruit.Id, new FormUrlEncodedContent(postEditData));
Assert.AreEqual(302, (int)editPostResult.StatusCode); // If successful, redirect to index.
context = server.Host.Services.GetService<MySqlDbContext>();
var editedFruit = context.Fruit.Single(r => r.Id == fruit.Id);
Assert.AreEqual(editedComment, editedFruit.Comment); // Assert fails, editedFruit.Comment is still the old value.
Assert.AreEqual(editedName, editedFruit.Name);
// Further code removed
} finally {
context.Database.EnsureDeleted();
}
}
Controller method:
public IActionResult Edit(FruitEditViewModel fruitViewModel) {
if (ModelState.IsValid) {
Fruit fruit= _context.Fruit.Single(f => f.Id == fruitViewModel.Id);
_auditTrailService.TakeSnapshotBefore(fruit);
fruit.Comment = fruitViewModel.Comment;
fruit.Name = fruitViewModel.Name;
_context.Fruit.Update(fruit);
AuditChange auditChange = _auditTrailService.CompareObjects(fruit, GetCurrentUserId(), AuditActionType.Update);
if (auditChange != null) {
_context.Add(auditChange);
}
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(fruitViewModel);
}

Extracting Twitter PIN info, WP7

I've been following this great tutorial:
http://buildmobile.com/twitter-in-a-windows-phone-7-app/#fbid=o0eLp-OipGa
But it seems that the pin extraction method used in doesn't work for me or is out of date. I'm not an expert on html scrapping and was wondering if someone could help me find a solution to extracting the pin. The method used by the tutorial is:
private void BrowserNavigated(object sender, NavigationEventArgs e){
if (AuthenticationBrowser.Visibility == Visibility.Collapsed) {
AuthenticationBrowser.Visibility = Visibility.Visible;
}
if (e.Uri.AbsoluteUri.ToLower().Replace("https://", "http://") == AuthorizeUrl) {
var htmlString = AuthenticationBrowser.SaveToString();
var pinFinder = new Regex(#"<DIV id=oauth_pin>(?<pin>[A-Za-z0-9_]+)</DIV>", RegexOptions.IgnoreCase);
var match = pinFinder.Match(htmlString);
if (match.Length > 0) {
var group = match.Groups["pin"];
if (group.Length > 0) {
pin = group.Captures[0].Value;
if (!string.IsNullOrEmpty(pin)) {
RetrieveAccessToken();
}
}
}
if (string.IsNullOrEmpty(pin)){
Dispatcher.BeginInvoke(() => MessageBox.Show("Authorization denied by user"));
}
// Make sure pin is reset to null
pin = null;
AuthenticationBrowser.Visibility = Visibility.Collapsed;
}
}
When running through that code, "match" always ends up null and the pin is never found. Everything else in the tutorial works, but I have no idea how to manipulate this code to extract the pin due to the new structure of the page.
I really appreciate the time,
Mike
I have found that Twitter has 2 different PIN pages, and I think they determine which page to redirect you to depending on your browser.
Something as simple as string parsing will work for you. The first PIN page I came across has the PIN code wrapped in a <.code> tag, so simply look for <.code> and parse it out:
if (innerHtml.Contains("<code>"))
{
pin = innerHtml.Substring(innerHtml.IndexOf("<code>") + 6, 7);
}
The other page I came across (which looks like the one in the tutorial you are using) is wrapped using an id="oauth_pin" if I recall correctly. So, just parse that as well:
else if(innerHtml.Contains("oauth_pin"))
{
pin = innerHtml.Substring(innerHtml.IndexOf("oauth_pin") + 10, 7);
}
innerHtml is a string that contains the body of the page. Which seems to be var htmlString = AuthenticationBrowser.SaveToString(); from your code.
I use both of these in my C# program and they work great, full snippet:
private void WebBrowser1DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var innerHtml = webBrowser1.Document.Body.InnerHtml.ToLower();
var code = string.Empty;
if (innerHtml.Contains("<code>"))
{
code = innerHtml.Substring(innerHtml.IndexOf("<code>") + 6, 7);
}
else if(innerHtml.Contains("oauth_pin"))
{
code = innerHtml.Substring(innerHtml.IndexOf("oauth_pin") + 10, 7);
}
textBox1.Text = code;
}
Let me know if you have any question and I hope this helps!!
I need to change the code suggested from Toma A with this one:
var innerHtml = webBrowser1.SaveToString();
var code = string.Empty;
if (innerHtml.Contains("<code>"))
{
code = innerHtml.Substring(innerHtml.IndexOf("<code>") + 6, 7);
}
else if (innerHtml.Contains("oauth_pin"))
{
code = innerHtml.Substring(innerHtml.IndexOf("oauth_pin") + 10, 7);
}
because this one doesn't works for windows phone
var innerHtml = webBrowser1.Document.Body.InnerHtml.ToLower();

ASMX Service Doesn't Always Return Data

I am working with an ASMX service in ASP.NET/C#. My service returns proper data for some of my WebMethods, but not all. The interesting part is all of the WebMethods are very similar.
Here's one that always returns data:
[WebMethod]
public AccountItem[] GetAllAccounts()
{
AccountItem[] AccountItems = HttpContext.Current.Cache[AccountItemsCacheKey] as AccountItem[];
if (AccountItems == null)
{
List<AccountItem> items = new List<AccountItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT A.Account_Id, A.Customer_Id, C.Last_Name + ', ' + C.First_Name AS CustomerName, A.[Status], AT.Name AS AcctType, A.Employee_Id, A.Initial_Balance, A.Interest_Rate, '$'+CONVERT(varchar(50), A.Balance, 1) AS Balance FROM Account A JOIN Account_Type AT ON A.Account_Type_Id=AT.Account_Type_Id JOIN Customer C ON A.Customer_Id=C.Customer_Id WHERE [Status]=1"))
{
while (reader.Read())
{
AccountItem item = new AccountItem();
item.AccountId = (int)reader["Account_Id"];
item.CustomerId = (int)reader["Customer_Id"];
item.CustomerName = (string)reader["CustomerName"];
item.AccountStatus = (bool)reader["Status"];
item.AccountType = (string)reader["AcctType"];
item.InitialBalance = (decimal)reader["Initial_Balance"];
item.InterestRate = (decimal)reader["Interest_Rate"];
item.Balance = (string)reader["Balance"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(AccountItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return AccountItems;
}
}
And here's one that never returns data:
[WebMethod]
public TransactionItem[] GetAllTransactions()
{
TransactionItem[] tranItems = HttpContext.Current.Cache[TransactionItemsCacheKey] as TransactionItem[];
if (tranItems == null)
{
List<TransactionItem> items = new List<TransactionItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT [Transaction_Id],[Account_Id],[Amount],[DateTime],[Comment],TT.[Name] AS [TransType],[Flagged],[Employee_Id],[Status] FROM [Transaction] T JOIN [Trans_Type] TT ON T.Trans_Type_Id=TT.Trans_Type_Id"))
{
while (reader.Read())
{
TransactionItem item = new TransactionItem();
item.TransactionId = (int)reader["Transaction_Id"];
item.AccountId = (int)reader["Account_Id"];
item.Amount = (decimal)reader["Amount"];
item.Timestamp = (DateTime)reader["DateTime"];
item.Comment = (string)reader["Comment"];
item.TransType = (string)reader["TransType"];
item.Flagged = (bool)reader["Flagged"];
item.EmployeeId = (int)reader["Employee_Id"];
item.Status = (bool)reader["Status"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(TransactionItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return tranItems;
}
}
As you can see, they're almost identical. The SQL queries for both return a ton of records, but only the GetAllAccounts() WebMethod actually returns that data back.
This is how I'm displaying the data passed back from GetAllAccounts(), which works fine:
#{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Accounts";
Page.Header = "BankSite Mobile - Accounts";
var svc = IntranetService.GetAllAccounts();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
#foreach(var item in svc){
<li>
<h3>Account ##item.AccountId.ToString() (#item.AccountType)</h3>
<p>Customer: #item.CustomerName</p>
<p>Account Balance: #item.Balance</p>
</li>
}
</ul>
</div>
Yet, this doesn't work fine, though it's the almost the exact same code:
#{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Customers";
Page.Header = "BankSite Mobile - Customers";
var svc = IntranetService.GetAllCustomers();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
#foreach(var item in svc){
<li>
<h3>Account ##item.CustomerId.ToString() (#item.CustomerId)</h3>
<p>Customer: #item.CustomerId</p>
<p>Account Balance: #item.CustomerId</p>
</li>
}
</ul>
</div>
...So basically I'm baffled. I don't understand why the data isn't being returned as expected from the non-working WebMethod (GetAllCustomers()). What am I missing?
If you disable loading stuff from the cache, would both methods always succeed to return expected result set? I would try that first, my gut feeling is that something funky with the cache (i.e expires before your method returns). Then go from there.
Try to isolate the problem to the web service by accessing the web service directly in a web browser. Also, if possible, use SQL Server Profiler to make sure the web method is querying the database.
If it is not querying the database, then I would guess that it has already cached an empty array.
Therefore, the inital "if (tranItems == null)" check returns false, but it then returns an empty array as the results.
I found the issue to be that some fields retrieved by the reader were null, and you can't create a null string. The solution was essentially to use something like this for every item property:
item.Amount = (reader["Amount"] != DBNull.value) ? (decimal)reader["Amount"] : 0;

Categories

Resources