ShareLinkTask Serialization.InvalidDataContractException WP8 - c#

I'm having an issue with the ShareLinkTask function from WP8.
I have an app with different pages (to view Comics - one to navigate through the Comics and one page to list a thumbnailpreview of all Comics).
The ShareLinkTask function works just fine as long as I stay in the MainPage.xaml. But when I switch to the Thumbnails.xaml (via NavigationService.Navigate...), select a new cartoon and share it the ShareLinkTask.Show() will show the sharing page and then crash the whole app.
If I make a try-catch around the ShareLinkTask.Show() no exception is thrown.
Here is the ShareLink function - it's called via the "Hold gesture":
ShareLinkTask shareLink = new ShareLinkTask();
shareLink.Title = "a";
shareLink.LinkUri = new Uri(b);
shareLink.Message = "Look at that handsome cartoon!";
try
{
shareLink.Show();
}
catch (Exception a)
{
MessageBox.Show(a.ToString());
}
From the console I get this error line: "System.Runtime.Serialization.InvalidDataContractException" occoured in System.Runtime.Serialization.ni.dll
Now Google doesn't now anything about this problem somehow - to be honest I don't really get / understand what's happening - I don't think that I serialize anything anywhere...
I suggest that I do something wrong by switching back to the MainPage.xaml. All indices etc. are correct and every other function of the app is just working fine.
Does anyone know where to look for the error?
Thanks in advance.

When you call Show, your application is put into a dormant state and may be terminated if the user navigates away instead of completing the task.
When your app is put into a dormant state your data gets serialized, but only classes with "DataContact" attributes can be serialized correctly. So the problem is - you are holding some UNSERIALIZABLE data in you app (Like in PhoneApplicationService.Current.State) . Find out what class causes exception.
Your exception should be like this:
System.Runtime.Serialization.InvalidDataContractException: Type 'TYPE HERE' cannot be serialized.
That will give you a hint of what's going on.

Related

App.MobileService.LoginAsync fails to show dialog on select machine -> Mind Blown

Just wondering if anyone might be able to point me in the right direction here.
user = await App.MobileService.LoginAsync(provider)
this is the line of code in question. The problem is; this works fine on 2/3 test machines (All Windows 10), the dialog is displayed and the program operates as expected. on the third machine however, the dialog does not display. I have wrapped the function in a try catch block and I am catching all exceptions that I then route to a MessageDialog to display on the screen. the messages are never shown, as though the try succeeded, but the function exits on that line exactly and throws no exceptions. I am using MobileServiceAuthenticationProvider.MicrosoftAccount as my provider.
Code redacted to highlight the error, the full code returns a boolean value for success/failure. All traces past the failing line do not appear, so the function is definitely exiting at the specified line.
try
{
//This line fails on a single machine out of three
user = await App.MobileService.LoginAsync(provider)
}
catch(Exception e)
{
//when it fails, this does not trigger, and no traces after this point
//appear until outside the function
MessageDialog msg = new MessageDialog(e.ToString());
await msg.ShowAsync();
}
and just to make things really weird...message dialogs prior to this point in the code work just fine...
I suspect that the security of the machine in question is blocking the login (windows defender), but I really have no idea where to look for this, or even how to test the problem further. Any ideas as to what would prevent this single machine from displaying the Microsoft login window, or ideas on further debugging would be appreciated.
You are not awaiting the response from the Async reply. This means that you will have an ordering and concurrency issue - sometimes it will work, and sometimes it won't and it's all in the timing.
You need:
var user = await client.LoginAsync(provider);

Can I have Parallel Object Recognition in Selenium Webdriver

I am using Selenium Webdriver, and I want to verify that everything has loaded in a browser (Chrome as it happens). The browser main window will have 10 or more objects loading inside it (each within their own iframe). I want to ascertain as quickly as possible that each object has loaded, then carry on with the rest of the test. Is it possible to use the C# Parallel.foreach construct to speed things up here, or do I have to check in series.
Parallel.ForEach(loop, f=>
{
try
{
_customObject.MethodCheckingForAnIWebElement(f, AnArrayWithSomeInfo[f]);
}
catch (Exception e) { Console.WriteLine("Throw:" + f + ":" + e.Message); }
});
The code snippet above is throwing f-1 Element is not attached to the page object errors, which is making me think that I just cannot do this approach.
To be clear, each call, I will do something like
_webDriver.SwitchTo().Frame(aFrame)
_webDriver.FindElement(By.CssSelector(some.property));
Apologies if I have missed some obvious documentation on this!
The answer appears to be as I suspected, in the threading model we have for Selenium WebDriver we can't process in parallel. Hence the consistent attachment error. See also Can Selenium use multi threading in one browser?

Ensure data deserialization / serialization

I have 3 ObservableCollections in my ViewModel and one Class which I load when you run an app.
To ensure ObservableCollections are deserialized I just got.
if(SomeCollection.Count == 0)
ThisCollection = await deserializationMethod<ObservableColletion<T>>(filename);
If there is no file, deserializationMethod will create new object with
return Activator.CreateInstance<T>();
That works fine - no problem with that.
And for class I have
if(ClassObject.Loaded != true)
ThisObject = await deserializationMethod<T>(filename);
I added a property - if file is deserialized then it's true.
It looks like it works but it is NOT. It happens very rarely but sometimes file is not deserialized and when you use an app this file is overwritten so every data are destroyed. I cannot find what is causing the problem. It is that you just run an app and it happens - like once per 100 runs.
How to be very sure that if file exist then it will be deserialized for sure?
Or maybe I should make List of these ObservableCollections + Class and serialize it to one file? Is there any good practice with that?
EDIT:
I used SemaphoreSlim to ensure that everything is used as it supposed to, but today it happened again.
The thing is it happens when app is started and nothing else is even tapped. There is no way that something is writing at this moment. It looks like data is not deserialized or is not reading the file that exist. Because every changes are written with closing an app then everything is gone.
Any other ideas what it might be or how to be sure that data are deserialized?
EDIT FINAL - reproduced problem:
I finally reproduced what is going on. So I've removed edits with code that wasn't necessary here.
I have BackPressed event to handle when user is going back or want to exit an app (if on MainPage).
This part of code apparently was causing the problem. What is going on exactly.
First thing is that problem isn't possible to be reproduced using emulator.
My BackPressed method contained await with serializing method that saved the data that were later gone (so as Ondrej Svejdar has written it was writing before reading). BUT I started to test it and there is strange behaviour and I still have some questions about it.
How it happens.
When I started an app (by accident e.g.) and loading screen occurs I start to tap back button few times -> app isn't running it is closing ASAP and I can't even see a UI (sometimes I am able to see AppBar for a moment). Then when I try to open app again (doesn't matter if immediately or later) it is "resuming" and after this exact moment my data are gone. But not all of the data. Only the last one saved with await within BackPressed method. Only this one. I tried to save One, Two and Three ObservableCollections with and without this Class and ALWAYS the last one was saved "empty". After this awaits I got Application.Current.Exit() method that might cause this, but I'm not sure if this should matter when serializing method is Task and only the last one is wrongly serialized.
When I remove this awaits from BackPressed method I can't reproduce this issue so this is it.
Questions I still have are: Is this behavior expected? Is there better method to close an app and ensure serializing data or I just should save it during using an app not while exiting it?
If someone is interested how to do it properly I was thinking about it and come up with few conclusions.
Keep in mind that this are my suggestions and there might be better approach.
While handling BackPressedButton event (the hardware one) I had an implementation of GoBack to previous page (if not on MainPage) or leave an app if on MainPage.
I was closing an app using Application.Current.Exit() and that wasn't causing problems (because I was saving very small files) until I started doing strange things (read "EDIT FINAL - reproduced problem:" of the question for more details).
Thing was the file wasn't saved because an app was closed before writing has finished. Solution is actually very simple. To my Save method which is a Task it just should return true value when writing is finished and this value should be checked while closing an app.
bool saved = await saveDataAsync<T>(whichData, dataFileName)
if(saved)
Application.Current.Exit();
and serializing method looks like this (I'm using semaphoreSlim in case there is possibility to two methods trying to reach the same file)
public async Task<bool> saveDataAsync<T>(T whichData, string dataFileName)
{
var Serializer = new DataContractSerializer(typeof(T));
await mySemaphoreSlim.WaitAsync();
try
{
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(dataFileName, CreationCollisionOption.ReplaceExisting))
{
Serializer.WriteObject(stream, whichData);
}
}
finally
{
mySemaphoreSlim.Release();
}
return true;
}

Order of WindowHandles

I'm encountering an issue where WebDriver seems to change the order of WindowHandles. This causes us to close the wrong one intermittently after getting them in some cases.
What seems to happen is the previously established first window handle is returned as a subsequent handle, which causes my logic to of course, close the wrong one.
Is WebDriver supposed to return the window handles in the same order every time (order of first opened window to last?). This is what I initially expected, but now I'm not so sure.
I should also mention the problem seems to only occur in IE right now, but I'm not certain if this is a more generic issue.
Here is how I'm closing the active window and switching back to the root window.
public void Close()
{
//switch to latest window
string windowName = string.Empty;
if (_driver.WindowHandles.Count > 1)
{
//get 'root' window in list
windowName = _driver.WindowHandles[0];
_driver.Close();
_driver.SwitchTo().Window(windowName);
}
else
{
_driver.Close();
}
}
We're on WebDriver 2.45 (C# bindings, 32-bit IEDriver). If there is a method to close the active window in the C# bindings that would most likely solve this issue as well.
This pop up window handler is entirely unordered as per my understanding. I remember having same conversation on SO and luckily JimEvans(one of the contributors of Selenium) chimed in and clarify few factors. I read about the PopupWindowFinder of Selenium .NET bindings and found that class can make your life lot easier. API is here. However, the whole order issue is entirely complex and painful to deal with. See this thread. Just don't want to reinvent the wheel.

Why would MessageBox.Show cause UnhandledException?

I am working on an app that uses location services. If I am debugging, the app works fine. If I start without debugging, on the first run (after rebuild), it crashes when asking for authorization to use location services. What happens is that if you let it sit, with the messagebox showing long enough (5-10 seconds), it crashes. If I start without debugging again, it works fine (though it doesn't show the messagebox again, because somehow it gets past that line to the next line AFTER the conditional statement, where it sets first run false (I assume, because it doesn't show again).
Again, if I am debugging, no problems. If I start without debugging, it dies. This is the case when building in either the Debug or Release modes.
If I comment this block of code out, it executes without a problem. If I click OK quickly, it executes without a problem.
if (settings.FirstRunLocationPermission)
{
string message = "Do you wish to use location services to see your location on the map? Your location is not being tracked. You can change this authorization in the settings.";
//if (MessageBox.Show(message,"authorization",MessageBoxButton.OKCancel) == MessageBoxResult.OK)
//{
// settings.AllowLocation = true;
//}
settings.FirstRunLocationPermission = false;
}
I would greatly appreciate it if anyone can explain to me why a simple messagebox checking for ok would cause a problem like this. Thanks!
Most likely you are showing the MessageBox in OnNavigatedTo. If that is the case, this SO answer should help. The problem is that if the user does not press a button your app will crash since the framework thinks that navigation has failed.
And yes, this behaviour occurs to me only when debugger is not attached.
If you look at the MSDN Documentation for the method, the reasons for the possible Exceptions is fairly clear:
MDSN - MessageBox.Show Method
The other possibility is that there is some code running in the setter for the settings.AllowLocation property that is throwing the Exception. It would help if you included the actual Exception being thrown.
I use it this way, and it works :
var msg = MessageBox.Show("Do you .... ?", "Title", MessageBoxButton.OKCancel);
if(msg == MessageBoxResult.OK)
{
//Do something;
}
Good luck

Categories

Resources