Ask Learn
Preview
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
First, if you wander on over to the AgFx CodePlex site, you'll see that there is a new release up. There's some new things in this new release such as some statistics about the performance of your application, the ability to specify exact cache expiration, and some bug fixes. The majority of feedback that I have gotten has been feature requests or "how do I?", and few in the way of bug reports. So it's working well for most people, hopefully that continues. Please file bugs if you find them!
All of the below references the code sample that you can find in the CodePlex source tree at AgFx\Samples\Facebook.Auth.Sample.
Something applications commonly want to do is to use Facebook as their credentials system instead of hand-rolling one. For many types of applications this makes good sense, but it turns out that integrating a Windows Phone 7 application with Facebook can be a bit challenging.
So with this release, you'll see a new sample called Facebook.Auth.Sample that gives you a template to start from that will hopefully make your life easier.
In case you're new to OAuth, it's basically a way to establish credentials without allowing the calling application to ever see a username or password. So instead of some kind of a web service call like service.login(username, password), instead you have a bit of a round-about pattern that looks like the following:
Because there isn't a direct service call here, AgFx isn't set up to really handle this process. It wants a URL to call and a response to parse. We can't do that, but it's still nice to use the caching and databinding-friendly features of AgFx, so we can craft a hybrid solution.
The strategy is basically as follows:
With that in hand, we're in good shape, and we can start making other calls out to Facebook. It is a little goofy that we take data that we have in hand, write it to a stream, and just read it back out again. But OAuth itself is a bit odd compared to the rest of the direct call APIs out there. So this is the price we pay. It's a small one.
Take a look at FacebookLoginModel for details of how this dance works.
PhoneApplicationFrameEx has a property on it called "PopupContent". This content will be shown over the top of the UI (e.g. over the current Page) whenever IsPopupContentVisible is set to true.
We can use this to make the login UI show automatically whenever the user is not logged in, and disappear automatically when a login succeeds. If you look in the samples App.xaml.cs, you'll see the following:
// Here we set up the frame binding.
//
// the below says:
// "When the FacebookLoginModel.Current.IsLoggedIn property is FALSE,
// set the PhoneApplicationFrameEx.IsPopupVisible to true. Or vice-versa."
//
RootFrame.PopupContent = loginView;
Binding b = new Binding("IsLoggedIn");
b.Source = FacebookLoginModel.Current;
b.Converter = new NotConverter();
RootFrame.SetBinding(PhoneApplicationFrameEx.IsPopupVisibleProperty, b);
Which basically takes the FacebookLoginModel.IsLoggedIn property and binds it's opposite to the IsPopupVisible property on the Frame. So, when the app starts for the first time, no cached creds will be available, and the login UI will show.
In the sample, the login UI is pretty much just the WebBrowser control, but I added an overlay that updates status when navigations and processing is happening.
See FacebookLoginView in the sample:
Upon logging in, the app fetches the full name of the user that logged in.
Once we are logged in, making service calls is easy. In the case of the sample, there is a very basic ViewModel called FacebookUser. By default, I just call the "me" user, which returns the information for the logged in user. It works like a standard AgFx model, and here's an example of it's GetLoadRequst:
public LoadRequest GetLoadRequest(LoadContext loadContext, Type objectType) {
// abort if we don't have a token.
//
if (!FacebookLoginModel.Current.IsLoggedIn) {
return null;
}
// build the "me" url including the auth token.
//
string meUri = String.Format("https://graph.facebook.com/{0}?access_token={1}", loadContext.Identity, FacebookLoginModel.Current.Token);
return new WebLoadRequest(loadContext, new Uri(meUri));
}
And in Deserialize, you'd typically want to use a JSON parser to pick out the data, which comes back from Facebook as JSON. For brevity in the sample, I'm using a Regex, which is not an industrial strength solution! In this case, the only value we grab is the user's full name, which then ends up bound into the UIs.
All calls you make should access the FacebookLoginModel.Current.Token property to access the access_token, and a good pattern to handle log outs and other errors is to create a base DataLoader (like FacebookDataLoaderBase, for example), that has unified handling for errors and scenarios where the token has expired. If that's the case, you have one place to go clear the login state. Which, if you may have guessed, will automatically pop the login UI. Then derive your model DataLoaders from that type and do your model-specific processing.
Getting this to work was a bit harder than I expected, so I'm glad I took the time to work through the scenario.
There were three issues:
The sample project handles both of these cases so you can use it as a template for your own Facebook or other OAuth integrations. I believe that Facebook uses standard OAuth, so it should port to another service cleanly, but I have not verified this. The pattern should be about the same.
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign in