Why is .NET MAUI crashing upon an event handler being activated? - c#

I am having a strange issue with my .NET MAUI app connected to an API controller and SQL backend. The app successfully accesses the login endpoint of my API and denotes that it logs in (I've confirmed by looking at my SQL db as well as by using Postman). However, once I hit the "login" button on my login page and I am notified that I have logged in, I thereafter call (within the same button event handler) absolute navigation to the home page using
await Shell.Current.GoToAsync($"{nameof(HomePage)}");
I use absolute shell navigation many other places in my app without issue (though to different pages), but for some reason, on this page, hitting "login" crashes my app immediately. Despite no exception being thrown or error, I have deduced that it is this line doing something wrong... and the app works fine if I remove this line. HomePage is a brand new page and I did register its route in appshell. I am flabergasted and would appreciate you input!
I expect to be able to use absolute shell navigation using .NET MAUI without my app crashing.

A simple await Shell.Current.GoToAsync($"{nameof(HomePage)}"); in the button clicked event will not crash the app, unless you didn't register the Login Page in the AppShell. In other words, the code in your App.cs is such as:
public partial class App : Application
{
      public App()
      {
            InitializeComponent();
MainPage = new LoginPage();
           // MainPage = new AppShell();
      }
}
If so, you can register the LoginPage in the shell and use MainPage = new AppShell(). Or you can try to change Shell.Current.GoToAsync($"{nameof(HomePage)}"); in the button clicked event as App.Current.MainPage = new AppShell().
In addition, if I'm wrong, could you please show more code about the Button click event and the shell?

Related

Xamarin forms + prism login flow

I'm new in Xamarin Forms (and in Prism as well) I'm trying to create my first xamarin forms application and need a login flow.
I tried to check if user logged in application.OnInitialized method (and show Login or Main page depending on the result). But the problem is that if i show Login page and then after login i show Main page, then user is able to navigate to login page using hardware buttons..
Then i tried to check this in OnNavigationTo in Main page, but it's not working also. I checked this in PRE version and stable version and had different errors. In one of them the navigation just didn't work, in other - i got an error, that main page couldn't be created.
Then i tried to inject navigation service into MainPage (not a view model), but i found out that navigation service couldn't be injected there.
Then i decided to send a message from view after base.OnAppearing and subscribe to that message in view model and do navigation to login if needed as a callback. But there's one very strange problem. If i'm using ToolBarItems on a MainPage, then on windows phone it's disappearing after navigation back from login page (but suddenly, login page on windows phone HAS that toolbar items), Looks like OnAppearing method on windows phone fires before toolbar items are loaded. In any case, it's not a solution.
Then i decided to add a blank page and send a message after base.onAppearing into a view model and inside that view model i do redirect to Login or main page. So, it works with one small "BUT". If i press hardware back button on login page or main page i don't close application as i navigate to blank page which redirects me to login or main page.
Is there a proper way to implement login flow using prism? i really like it as it's very powerful framework..
Thanks in advance!
Keep in mind that OnNavigatedTo only works when using the latest preview version, and calling NavigationService.Navigate. There are a couple of approaches to take here. First you can navigate to MainPage, then check in the OnNavigatedTo. If not logged in, navigate to the LoginPage. You could also just check on App startup. When you show the LoginPage, you can use an absolute URI to replace the entire navigation stack. Essentially what this does is set MainPage = new MainPage().

How to solve Page Caching bbin Windows Phone

The first page in Windows Phone is always cached, that means when you run the app then press back button to close the app then reopen the app from the phone or the simulator (not from visual studio) the page events such as the constructor, NavigationHelper_LoadState, and OnNavigatedTo are not called, even I disabled page cashing by
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Disabled;
and in App.xaml.cs
rootFrame.CacheSize = 0;
But still cached.
How can I solve this problem because I need to get data from a server and show it in the page.
Couldn't you load data in OnNavigatedTo? If you need to load data in constructor you can also try to remove page from navigation stack.

Resume, instead Restart, app using URI Launcher

I'm trying implement Facebook Login using the Facebook C# SDK but I'm having an issue returning back to the app when a login has been successful.
I have followed all the steps in this tutorial but i'm having an issue.
I have created a custom UriMapper that should go back to the MainPage.xaml when launched.
public override Uri MapUri(Uri uri)
{
if (uri.AbsoluteUri.Contains("/Protocol?encodedLaunchUri=msft"))
{
return new Uri("/MainPage.xaml", UriKind.Relative);
}
return uri;
}
My problem is the page refreshes and all my data in forms and text boxes gets removed.
Is it possible to "Resume" an app via URI instead of restarting it?
I've tried adding the tag below in the manifest but this does not work.
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
The part that you added in the manifest file enabled Fast App Resume, which means that your application won't be relaunched as a new instance if it is sitting in the background. But this doesn't guarantee that your input boxes will get their data restored. For this, you need to preserve the page state and restore it when the app resumes. Read more about this here.

Simulating a button click within ascx page

I need to simulate a button click on my ascx page. The user firstly clicks on a button on the service home page which links to a certain service and a new window opens for that related service. If they are not logged in it directs them to the login page. A querystring is sent with it to keep note of what service they had originally clicked. When the user then logs in they are redirected back to the services page and the querystring of what they clicked on before is sent also.
I have up to this point working fine. The problem is that when I'm redirected back to the online services page I need to simulate an onclick event which will open the new window. I cant click on an the onclick method for the button as there is none, everything is done dynamically. Any ideas?
I would have thought the easiest way to achieve what it sounds like you're trying to do is in the code behind for your Online Services Page check to see whether the query string contains the url for the service they clicked on before you sent them to the login page, if it does then add some javascript to run on start up which launches the pop-up (using the ClientScriptManager.RegisterStartupScript method: http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.registerstartupscript.aspx).
If you absolutely have to fire the click event you can also do that from your javascript by finding the button you want to click by it's ClientId (using getElementById) and then calling the javascript click() method on it. Here is an example: http://www.w3schools.com/jsref/met_html_click.asp

"Unspecified error" from javascript in my Silverlight application

I have a Silverlight application written in C# that utilizes the Bing Maps SDK. In this application I have a page with some javascript functions to expose functions within the application. The application registers the Bing MapControl in the MainPage's constructor with:
HtmlPage.RegisterScriptableObject("Page", new MapControl(this.BingMap));
In the javascript function, I call the methods of the application like so:
<script type="text/javascript">
function ClearMap() {
var control = document.getElementById('silverlightControl');
control.Content.Page.ClearMap();
}
</script>
However, whenever I refer to the control.Content.Page property in a javascript function, I get an "Unspecified error". Even just setting it to a variable will cause the error, for example:
var page = control.Content.Page;
Here is the strange part. I am using this silverlight application from 2 other applications. One is a windows service, and the other a winform application. The winform embeds a visible WebBrowser into its form and uses that to call the javascript functions. When using the winform, everything works fine with no errors.
The error only occurs when calling these functions from the windows service. The service instantiates a WebBrowser object just like the winform application does, and initializes everything in the same way. The only difference is that it's running as a service, and the WebBrowser is not visible nor embedded in any forms. Could that fact possibly cause this error?
I currently have the winform application, the windows service, and the silverlight application's webservice all running on my own local machine.
UPDATE
After Gnostus' comments, I figured out that the main issue I'm having is that the "Page" object is not being created because the App class never gets initialized after navigating to the webservice from the windows service-based WebBrowser. The winform app and the service both do this the exact same way:
WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
WebBrowser.Navigate("http://localhost:56062/BingMapsWebServiceTestPage.aspx");
while (WebBrowser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
I added some code to the MainPage's constructor where it calls HtmlPage.RegisterScriptableObject("Page", new MapControl(this.BingMap)); that will log some text when it gets hit. When I run the above code in the WebBrowser of the winform application, the following occurs:
The DocumentCompleted event gets fired twice (once by the browser and I assume once by the silverlight control)
The App() is intialized and the "Page" element successfully added in the MainPage's constructor
The above while loop completes
When I do the same from the windows service, it does #1 and #3, but not #2. Step 2 only gets hit when I call a javascript function that refers to the Page object, and only after it errors.
UPDATE 2
After messing around in a new winform application, I discovered that the silverlight control will fail to load upon calling Navigate() whenever the WebBrowser or its parent form is invisible. I found that it's possible to still call my javascript functions if the parent form is hidden AFTER the silverlight application has finished loading. Does anyone know a better way to force the silverlight app to load aside from flashing up a visible form? Is it even possible to show a form from a windows service, or am I going to have to rethink this whole thing as a console application?

Categories

Resources