Latest Entries »

Weird Error

In attempting to add and test background agents for one of my applications I came across the following error:

BNS Error: The action’s start time has passed when trying to create/update the request

The error raised immediately after calling the ScheduledActionService.LaunchForTest method while debugging.  I’m not sure what that means but the error went away after restarting the emulator.  I can’t reproduce the error now so not sure if I was just in some weird state or what.

Wait for it …

The LaunchForTest method has ended up being really useful in testing my background agents.  Initially though, I didn’t think it was working.  I expected the agent to run at the specified TimeSpan.  Turns out its not quite that quick.   Even if I set the TimeSpan for 1 second it takes about 10-15 seconds for the agent to actually run.  This additional time seems to be constant across any TimeSpan.  So be patient when debugging agents. 

Another potential confusion point starts from the fact that if you add a breakpoint within the agent and debug your app it says the symbols haven’t been loaded.  

image

So I added a Toast notification to show me the agent ran but when debugging nothing happened.  So I thought it wasn’t working.  I kept troubleshooting and went to the settings page to see if my app’s background agent registered, it had and while I was there the Toast appeared then my breakpoint hit as well. 

After further testing, I found the Toast doesn’t appear while in the app and then I remembered that is by design.  You have to handle Toasts programmatically in your app, they will not display if your app is already running.

Regarding the breakpoint, the symbols must not be loaded until the agent actually runs but they will be loaded and the it will break.

So to summarize, if your trying to get quick feedback that your background agent is working you should:

  1. set the LaunchForTest TimeSpan to 1 second
  2. set a breakpoint within your agent
  3. wait 10-15 seconds

Happy Coding!

So I woke up early (3am) to watch the day 1 keynote from Nokia World live and to sum it up briefly,

it was uneventful.

I know there was a lot of hype surrounding this event but there was really no new information announced, especially in regard to Windows Phone.  There was speculation they would announce “a bunch” of Windows Phones.  They did announced 6 phones in total but only two were Windows Phones.  The other four were feature phones for emerging markets.

The two Windows Phones were the Lumia 800 and 710.  The 800 is the N8/Searay hardware running WP7.  The 710 looks the same spec-wise except for the a 5MP camera instead of the 800’s 8MP.

Nokia did announce some WP7 apps.  The Nokia Drive app looked impressive and will come with the 800 free of charge.

Their marketing plan is to target 25 years olds with “amazing everyday” ads.

The 800 will be available in France, Germany, Italy, the Netherlands, Spain and the UK in November.  The 710 will be in Russia, Taiwan, India, Hong Kong and Singapore by the end of the year.

I guess we can look forward to the early part of 2012, for Nokia’s US “products” (which was a cryptic description).  I just hope I don’t have to get up so early again for the announcement.

I’m going back to bed.

I had an issue on a WP 7.0 app the other day that I spent several hours working on after Bing offered no help.  Its rare to find an exception that no one has blogged or posted about.  So I’m going to share my learning.

The scenario: I have a REST JSON service that I’m calling and want to deserialize the result to a strongly typed object.  I’m using the HttpWebRequest to GET the JSON and the DataContractJsonSerializer from the System.Runtime.Serialization.Json namespace in the System.Runtime.Serialization assembly to deserialize the response stream.

If you create the HTTP request correctly and the response type matches the JSON structure everything will work.  I, however, had an issue.  It was all wrapped in a try/catch in the app I was working on so I added a break point and did a quick watch on the deserialize call to dig into the issue.  That’s when I ran into this:

Invalid byte encoding.

image

Bing/Google collectively had about 4 results for this error in the context of C#, none of which were related to JSON.  So that’s when I started digging deeper into my WCF JSON service and its configuration but nothing seemed to work.  I kept getting this error.  I finally started hitting the WCF from the web browser directly and a test client to find that my UriTemplate wasn’t quite right, so I fixed it.  Then I returned back to my WP app to find the same “byte encoding” error.

After several hours across several days I removed the breakpoint and the call worked fine. 

Confused, I add the breakpoint back and the error returned.  So after much troubleshooting the breakpoint itself caused this error.  Not exactly sure where but at some point during the break the network stream is being opened and read then the DataContractJsonSerializer fails when attempting to read the stream again. 

I created some quick test code to verify this.  The code calls the Bing JSON web service and should return an error because I didn’t include the app ID.   The test here is whether the error message can be deserialized.  The solution has three projects:  a WP 7.0 project, 7.1 project and a console app project.  Each works correctly without breakpoints but when you add a breakpoint and attempt to deserialize the JSON and you will get the error.  The console app gives a different error but it seems to be the same result.

"Expecting element ‘root’ from namespace ”.. Encountered ‘None’  with name ”, namespace ”. "

image

The test solution can be found at byte-encoding-error-test

Happy Coding!

This week I submitted my first beta app to the marketplace and wanted to share my experience with you all.  The submission was nearly identical to a standard app submission.  There is a field labeled “Distribute to” on the “upload” step of the app submission. 

image

By choosing “Private Beta Test” you will skip the standard certification process which will save about 4 days.  You will be able to setup 100 Windows Live users to install the private beta application and the app will be available for 90 days.  You cannot charge for the beta but it is still a very valuable way to get quick feedback from users.

Click the “Learn more about beta testing” link to get the full description of private beta submission and its limitations.

I submitted the beta to the marketplace around noon on Thursday and by that evening the status was set to “published”.  The only problem was the link provided in the submission successful email didn’t work.  I kept getting the following error in the marketplace on my Mango device:

MARKETPLACE ERROR

We’re sorry, but we can’t complete your request right now.

Try launching Marketplace again.  If the problem continues, check back in a little while, or try restarting your phone.

Error code: 805a0194

I also tried the link on a Nodo device and it had a similar error.

I submitted a support ticket in the marketplace to see what was going on and went to bed.  I got up the next morning and it worked fine.  No problems since.  So apparently although the marketplace status may say the beta is published expect several hours for the app to be available for installation.

Good luck.

I resolved a small bug in my Twitter OAuth code today that others might find useful.  The bug was found on a phone with Nodo but didn’t exist on Mango phones.  I’ve been using the Mango beta tools for a while now and haven’t really had any problems going back and forth between OS versions so this was a bit surprising to find. 

I am currently using the Hammock framework for making OAuth calls to Twitter and Facebook.  In final testing for this app a tester found that the Twitter login page was erroring out on a Nodo phone.  I confirmed the error page in the Nodo emulator and my Nodo device.  Also confirmed that the login page worked fine on Mango.  Here is an image of the error in the emulator:

image

In debugging I found the initial web request to obtain the OAuth token was failing.  As a result we were passing garbage as the OAuth token to the authorized page which resulted in the error above. 

After searching around some I found this post which says to set the RestClient Authority to

“http://twitter.com/oauth”

which was slightly different than what I had


“http://api.twitter.com/oauth”

After making the change Twitter login worked perfectly on both Nodo and Mango phones. 

Happy Coding

Social media integration is a big part of any mobile app these days.  So I was adding Facebook and Twitter sharing to a WP7 app I’m working on.  This was my first experience using OAuth, so it didn’t go exactly smoothly but that’s for another post.  After some work I had Facebook/Twitter authentication and posting working great then the client asked for a logout feature so the user could change accounts if they like.

In my head, I thought no problem surely these APIs have a logout capability just like a login.  Not quite.  Apparently these networks like to keep you logged in once your in.  Twitter does allow you to re-authorize using another set of credentials but their API has no “logout” method.  Alternatively you can use the mobile logoff link in a WebBrowser to remove the session (cookies) and logout. Although this isn’t ideal, it works.

browser.Navigate(new Uri("http://mobile.twitter.com/session/destroy"));

On to Facebook, the API is similar, no direct logout option.  Again we would expect to be able to use the same workaround as twitter, just hit the logout url.  Nope, if you look at the source of the logout button on the Facebook page you will see its performing a POST with a few session keys.  So the link is different for each session.  The keys don’t match any of the OAuth keys I have so I can’t build the link either.

The next potential option is manually clearing the cookies in the WP7 browser.  Sorry, Microsoft doesn’t give us access to clear the cookies.  Some have attempted to work around this, for example

http://cloudstore.blogspot.com/2010/09/clearing-cookies-on-windows-phone-7-or.html

But as the WP7 API has changed these options are no longer working.

I had conceded at this point.  Facebook had won. We wouldn’t be able to allow users to logout.  Then I remembered one of the other logout alternatives suggested clearing the cookies from javascript.  I had tried this but it didn’t work.  But, if I can run JavaScript on a webpage, why can’t I use it to click the logout button on the Facebook page.  I was absolutely sure this wouldn’t work.  I tried anyways and it worked!  I couldn’t believe it.

LoadCompletedEventHandler loadCompleted = null;
loadCompleted = (sender, e) =>
{
    if (
        browser.SaveToString().Contains("logout_form"))
    {
        browser.InvokeScript("eval","document.forms['logout_form'].submit();");
        AppSettings.FacebookAccessKey= null;
        RaisePropertyChanged("LoggedIntoFacebook");
        browser.Visibility=Visibility.Collapsed;
        browser.LoadCompleted -= loadCompleted;
    }
};

browser.LoadCompleted += loadCompleted;
browser.Navigate(new Uri("https://www.facebook.com/logout.php"));

Happy coding!

Its been a while since I used IsolatedStorageSettings from scratch.  I wrote a wrapper several months ago and its just worked since.  So when I was working on a side project recently (very recently) I was pulling my hair out trying to figure out why IsolatedStorageSettings didn’t appear to be working.  I could add an business entity to the dictionary and immediately retrieve it but after the app tombstoned or shutdown the dictionary was empty.  No errors were being thrown.  No data.

I tried clearing out the dictionary thinking there was a bad value in there from a corrupted state.  I searched and searched in the app for other places I might be effecting the dictionary but found none.  I placed the storage logic in three different places.  Nothing worked.

Finally, I binged around to see if anyone else was having a similar issue and found this post where Joel Johnson (MVP in Atlanta) answered this question for another developer.  You must mark the custom type with the DataContract attribute and then any properties you wish to serialize with the DataMember attribute.  Thanks Joel!

    [DataContract]
    public class Article
    {
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Url { get; set; }

        [DataMember]
        public string Description { get; set; }
    }

I searched around for this solution after the fact and it only seems to be buried within comments or forum posts.  The MSDN documentation for IsolatedStorageSettings doesn’t mention it at all.  So don’t assume (like I did) that the IsolatedStorageSettings dictionary can store custom types out of the box.  You must make them serializable first. 

Happing Coding

I had asked on Twitter the other day if there was a post comparing the Microsoft Advertising SDK with alternatives and didn’t really see anything.  So I thought I would share a forum post I found on the subject.  Its brief but I think its valuable to see multiple perspectives on the subject.  Check it out at http://forums.create.msdn.com/forums/t/77992.aspx

I spent several hours last night trying to find a good example of an extra wide, horizontally wrapping Panorama Item but couldn’t find one.  Several of the built in hubs have this layout and I knew there were third parties who had done the same so it should be possible.  I like how this layout can extend the use of Tiles to within applications.  Notice how the first panoramaItem is wider than the others for the Office hub:

Ended up finding two posts, which combined, resulted in this layout.

The first was a post from Dave Relyea which provided the horizontal wrapping for the panoramaItem.  This works great if you are only adding static content to the page but I want to use a dynamic listbox.

The second was a msdn forum post which describes how to make a ListBox wrap horizontally.

The steps to reproduce this layout are:

  1. Set the orientation on your ParoramaItem to “Horizontal”
  2. Set a width on your PanoramaItem, this will determine how much content extends to the right
  3. Add a reference to the Silverlight Toolkit for WP7
  4. Set the ItemsPanelTemplate on your ListBox to a WrapPanel with Horizontal Orientation
  5. Set the ListBox.Template to a ItemsPresenter ControlTemplate
  6. Create the ListBox.ItemTemplate to your liking

Here is the code:

<controls:PanoramaItem Header="near me" Orientation="Horizontal" Width="1000">
                <!–Double line list with image placeholder and text wrapping–>
                <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}" >
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Controls:WrapPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    <ListBox.Template>
                        <ControlTemplate>
                            <ItemsPresenter />
                        </ControlTemplate>
                    </ListBox.Template>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Rectangle Height="200" Width="200" Fill="#FFE5001b" Margin="20"/>
                                <TextBlock Text="{Binding LineOne}" Margin="20" Style="{StaticResource PhoneTextExtraLargeStyle}" />
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </controls:PanoramaItem>

 

I don’t love taking another dependency (the Silverlight Toolkit) but it works.  If you have a better way please share.

Just thought I would mention an issue I had with the emulator today.   I was trying to make some rest calls to a well known web service and kept getting denied with a “Not Found” error in VS.  Trying the url in IE gave a 404.  I finally tried in Chrome and got some meaningful info back.  Apparently the request was expired because the timestamp querystring value was wrong.  So I checked DateTime.Now in the immediate window and sure enough it didn’t match my system time.  At first I thought we arrived at the end of time, with it being the first of the year.  After further reflection of the world and life as I knew it, I remembered I’m using an emulator which has its own time and it had been several days since I shut it down.  This resolved the issue.  I think I will start restarting the emulator more often. 

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: