Weblog Home Page

Welcome to my blog! On this page you'll find the most recent posts on ASP.NET, photography, and other random thoughts and opinions. If you are looking for older posts, check out the archive pages. Or you can also subscribe to my RSS feed. And while you are here, check out my photo gallery...

Ajax Server Controls Book

Yesterday, I received my copy of "Advanced ASP.NET Ajax Server Controls". I had a chance to get an early peek at the content when Adam and Joel asked me to write the foreword for their book.

One thing I liked about this book is that this is one of the few that dive deep into the framework, its architecture and extensibility, and address the power-user/developer scenarios.

If you're building applications in Ajax today, and want to take that to the next level, you'll want to look into the platform deeper beyond the out-of-the-box features i.e. its extensibility. You'll specifically want to build reusable components and controls, on both the server and on the client. Check out this book on more details like "the client script framework", "the script application object", "localization" and "the control toolkit" amongst many other relevant topics.


[ Tags: | | ]
Comments (4)


Themes for Silverlight Applications

Silverlight provides the ability to completely customize the look and feel of controls (including the intrinsic ones - often something one desires when working with HTML), while preserving their behavior, through a combination of styles, templates, visual states and transitions. For example, the screen shot below (click to run), shows the stock look replaced with a sketch or napkin look and feel (based on Corrina's (our resident designer) rough skin sample).

Red, Blue, Green Sketch controls vs. Stock Silverlight controls (Click to Run)

The general approach to defining app-wide customizations in Silverlight today is to define a bunch of named styles in the Resources dictionary of the Application's XAML markup, and then reference them via the StaticResource markup extension elsewhere in the UI. However this approach has some shortcomings, that HTML designers have long overcome through the use of separate and multiple style sheets.

  • Application.Resources become unwieldy. Styling just a few controls can quickly lead to 1000's of lines of XAML. Simply navigating and finding what you're looking for becomes a chore. The first thing I do when I pick up a theme created by a designer is try to separate out the set of individual styles per control.
  • Styles get mixed up with functionality. To me (speaking from my developer mindset), Application.Resources is better suited for global data and other behavioral aspects of my application shared across the application, rather than serving as a container for visual and presentation items. Hence my desire for separating these out, so I can just import a designer's creation into my app.
  • Styles are not easily swappable. This is also partly because styles are mixed up in an application's resources. If I want to switch from say a Flat look to a Sketch look in my app, I have to carefully swap things in and out, track dependencies between styles etc.
  • Styles cannot be dynamically selected. I'd like to create an application that can dynamically pick a different font/color scheme, i.e. have the notion of themes, perhaps based on a user's profile. This requires some level style merging as well as the ability to include multiple themes separately in the xap package and pick one of them dynamically.

There are probably a few other issues that came up in my discussion with Corrina but suffice to say, these stem from placing styles statically in Application.Resources. Designers working on HTML have long overcome these issues through the use of separate and multiple style sheets that help separate content and behavior from presentation.

I started to think about how I might go about creating a more concrete theming system for Silverlight apps, and naturally I looked to CSS as well as what we had done with Themes in ASP.NET (the App_Themes folder pattern) to see how much I could re-use here, while still feeling natural in the context of Silverlight, and reasonably designable via Expression Blend. The end result was a very small theming feature addition to on-going Silverlight.FX framework.

In the rest of the post, I'll describe how to go about creating the themes above and consuming them in the application.

[... continued here]
Comments (18)

Search for Rich Internet Applications

If you're developing a web site, especially a public facing site, search and indexability are probably high on your list of requirements and priorities. Yesterday, searchability of rich internet applications got extra attention with Adobe's announcement that it is providing technology to search engines to improve indexability of swf/flash-based applications.

This is particularly interesting to me as I think getting the right SEO behavior for RIAs is based on looking at end-to-end solutions that involve complementary server-side techniques (guess that is not totally unexpected from someone like me who has been working on asp.net). I've also been presenting on Search and RIA and enabling indexability for Silverlight and Ajax apps for a couple of years at various conferences... links to those below.

There has always been a question mark around indexability of RIAs, whether they're built in Flash, or Silverlight, or even Ajax. The fundamental problem is that static indexing of a RIA is likely to turn up only the user interface of the application, and not the interesting and meaningful data fetched by application logic and presented dynamically to the user. Indexing an application binary or script is akin to having desktop search index winword.exe instead of your documents... not very useful. Most folks are now seeing indexing something like a raw swf binary as less and less useful, as applications become more and more dynamic.

The two key things around improving SEO (besides various general techniques like URL canonicalization, friendly URLs and search-engine friendly URL rewriting) are ensuring indexability and facilitating relevance. Indexability is created through addressing the what content is visible to the crawler, as well as where the crawler should look. Relevance is primarily addressed through creating deep linkable content and interesting content (so folks actually link to it).

[... continued here]

[ Tags: | | | ]
Comments (15)

ViewModel Pattern extended with the Dynamic Language Runtime

In my last post, I posted an implementation of the ViewModel or M-V-VM pattern for use in Silverlight applications. This pattern allows you to decouple your view presentation logic and data from the view, thereby facilitating independent development/design of your app as well as easier unit testing of your application code. I will highly recommend you check out that post for the more detailed description and intro sample if you haven't already done so, as this post will build further on that.

Now that I've done some additional exploration, and prototyping, I think the syntax used to define the glue between the View and the ViewModel as first presented was a bit suboptimal, and could be re-done to be much more intuitive. Read on to find out more.

Amazon Search Sample
In that post, I had a simple Amazon Search app to demonstrate the view model pattern. Focusing on the search aspect of the scenario, here are the relevant snippets of code and XAML forming the view model and the view respectively:

public class SearchViewModel : Model {
    ...

    public void Search(string keyword) {
    ...
    }
}

<vm:View xmlns="..." xmlns:x="..."
  xmlns:vm="clr-namespace:Silverlight.FX.ViewModel;assembly=Silverlight.FX"
  xmlns:app="clr-namespace:AmazonSearch.Views">
  <vm:View.Model>
    <app:SearchViewModel />
  </vm:View.Model>

  ...

  <Button Content="Search" IsEnabled="{Binding CanSearch}">
    <vm:ButtonEvents.Click>
      <vm:InvokeMethod MethodName="Search">
        <vm:ElementParameter ElementName="searchTextBox" ElementProperty="Text" />
      </vm:InvokeMethod>
    </vm:ButtonEvents.Click>
  </Button>

  ...
</vm:View>

Action behaviors were used to implement the glue that allows a View to invoke some operation defined on the View Model in response to an event. As you can see in the example above, an InvokeMethod action has been associated with the Button's Click event and it is set up to invoke the Search method on the ViewModel passing in the Text in the specified TextBox.

InvokeMethod Shortcomings in Associating View to ViewModel
The first issue with this approach is that it isn't super-friendly. The XAML to define a list of parameters gets verbose very quickly. Secondly it doesn't allow for a number of scenarios, around passing in arbitrary data into the view model. I noted in the post that I might want to do something like this instead:

<Button Content="Search" Click="{Action InvokeMethod Search(searchTextBox.Text)}" IsEnabled="{Binding CanSearch}" />

I got to thinking about this after writing and re-reading the post myself, and what occurred to me is that this is quite a slippery slope, eventually leading to a full expression language. Not wanting to create such a thing, I started reflecting on what could be repurposed.

I realized the Dynamic Language Runtime (DLR) would be a perfect fit. It is just the right designer-friendly glue that can be used to call into the bulk of the logic that is itself developed using statically compiled code that exists in the view model and the rest of the app. I could scope the use of the script down to a minimum by hosting the DLR to execute just script expressions. The DLR would also give me the benefit of using something like JavaScript, and potentially on any another scripting engine created to run on the DLR.

[... continued here]
Comments (22)

ViewModel Pattern in Silverlight using Behaviors

The MVC pattern is quite widespread, and lots has been written about it. Clearly, it is a popular addition to ASP.NET. MVC works especially well for request/response style web apps as well as in navigation-based client apps.

The ViewModel pattern, or more accurately said, the Model-View-ViewModel (M-V-VM) pattern on the other hand hasn't been discussed a whole lot as a formal pattern. However, it is a really nice pattern that is very well suited to client apps that generally feature interactive or dynamic user interfaces that are data-bound and implemented declaratively, for example, most Silverlight apps.

Introduction to ViewModel
This is a very brief description of the pattern, and how it is both similar and dissimilar from the code-behind pattern that is in vogue.

Model/DataModel
This is somewhat analogous to the model in MVC. It basically represents the data that the application operates over, as well as the data access mechanism. This might be reused for different parts of the application. This might be partially defined declaratively, and/or code-gen'd.
View
This represents the user interface, displays data, and enables user interaction. This is typically defined declaratively - XAML, HTML etc. No surprises here.
ViewModel
This can also be read as "The View's Model" which is a bit more representative of its function. This sits in between the View and the Model and surfaces data in a form that is more suited for viewing or editing. It also defines operations that can be invoked to perform some work, often times resulting in changes to the data that the View is bound to. While it doesn't depend on the View, it is logically associated with one in a one-to-one manner. This might be partially code-gen'd as well, but for the most part this is authored in code.

Code-behind PatternYou've probably been doing something quite close all along. I am sure you've written some piece of UI that is associated with some code-behind that is responsible for loading in data, and implementing logic to handle user input and interaction in the form of event handlers. The figure on the right illustrates the mechanics of the code-behind pattern. One of the big problems with code-behind is that it mixes your logic with presentation and couples it deeply, which gets in the way of testability. Another problem is that it leads to co-mingling of designer-centric parts of the app with developer-focused parts of the app. Often times these implications may be ok for quick-and-dirty prototyping but would be nice to avoid for real apps.

ViewModel PatternThe ViewModel pattern attempts to address these problems by encouraging separation of logic from the presentation. The data being presented is implemented as properties on the ViewModel, that the View consumes via data-binding. Secondly, most of the backing logic and operations are implemented as methods on the ViewModel that the view invokes via commanding. The key constraint is that the ViewModel is not dependent on View concepts such as choice of controls. The figure on the left illustrates this pattern. It is not a fundamentally different world, but rather something closer to a rearrangement and refactoring of the same pieces.

Some folks might argue that all of code-behind is to be removed. I tend to think that some may remain, specifically, to facilitate view-to-view interactions that cannot be expressed declaratively in XAML easily, hence the sliver of code-behind in the view.

This is simply one amongst many patterns that encourage discipline over what code goes where, how it is related to other code etc. The goal here is to think about how to get both long-term benefits from practicing discipline, as well as make it suitable for those smaller apps and quick-and-dirty experimental apps, by making this pattern emerge naturally from tooling guidance. I won't cover tooling today; perhaps another blog post on this down the road.

ViewModel In Action
Enough theory! Onto a running app... I've built a simple Amazon Search application using the ViewModel pattern, and the Silverlight.FX framework I've built to support it on top of Silverlight 2. You can play with it here, as well as download the entire solution containing code for the sample, associated sampling of unit tests, and the framework it builds upon.

[... continued here]
Comments (23)

Microsoft Source Analysis aka StyleCop

A couple of weeks back, StyleCop, which used to be an internal tool was rebranded and publicly released as Microsoft Source Analysis. Right around that time, we were having an internal discussion within the team around what sort of coding style guidelines we should put in place for a new project.

Such discussions are always fun, and can serve as fodder for ongoing back and forth unless someone just gives in. If design guidelines are debatable (eg. Id vs ID), style guidelines are at least an order of magnitude more debatable; everyone has an opinion and a set of preferences around source code. I think what we really need is a system around how code is a model, not just text, and the editor is simply a view over that model that reflects a user's choice. In the meantime, we have guidelines, and tools such as StyleCop to help enforce them.

Speaking about debatable guidelines, it seems one of the big point of debates was around the tool's default rule that tabs should not be used for indentation. I personally agree with that one, but I'll throw in an even more debatable rule that is a preference of mine (which unfortunately the tool doesn't default to): K&R bracing style. You've already seen me use it in blog posts that contains code snippets. Ultimately, independent of specific stylistic choices, a consistent and predictable code base is a first step toward facilitating readability and discoverability. Definitely check out the tool if you haven't already.

For those curious, I actually have a coding guidelines document I use that is mostly based on what we agreed on for the ASP.NET code base some years back. I tried to tweak the settings offered by the tool to create a matching set, though I think I'll need to write some custom rules around ordering and spacing if I want the tool to exactly match my preferences.

On a related note, this tool completely works as expected with Script# projects, as I expected. So, if you're using Script# to build an Ajax app or component, you too can now benefit from this tool. This just shows how a good chunk of both new and existing .NET tooling can be repurposed without much work.

Comments (12)

Engineering Excellence Award for Script#

Every year, Microsoft holds an Engineering Excellence Conference. This is that week. In addition to a variety of conference sessions around engineering practices and trustworthy computing, a number of awards are handed out during the opening keynote.

One of the awards that is handed out recognizes innovation in tools and practices that promote better engineering and have broad impact, and adoption. I am glad to share that this year, Script# was presented this award. :-)

In terms of impact and adoption, a number of product teams across Microsoft are using Script# to implement their Ajax-based Web experiences. It is always fun to see folks adopting something you've worked on and creating some amazing applications, but more importantly, the award helps make a case for the productivity wins and the engineering discipline that Script# can bring to Ajax development by leveraging the .NET programming model and tools. In addition to Live Messenger and Live Mesh, there are others that are in the works (that I don't think I can share publicly just yet), but as always, I'll share as and when they do become public.

I'd like to say thanks to those who helped champion the technology early on beyond just a personal project, and help improve the project - folks like Steve Gordon, Shaofeng Zhu and Justin Rockwood from Microsoft, and Wei Zhu, who is now at Facebook, as well as the many others, internal and external, who have shared feedback, bug reports and enthusiasm over the course of the last couple of years.

I've been a bit on the busy side recently, but still to come is sharing sources over on the CodePlex site in addition to the ongoing discussion forums.


[ Tags: | ]
Comments (23)

AutoComplete for Silverlight TextBoxes

Yesterday I blogged about using and creating behaviors in Silverlight. This post will walk you through an autocomplete behavior that will hopefully furher crystallize the behavior concept.

To recap, a behavior is simply an object that can be declaratively attached to another component to extend the built in functionality of that component. Typically a behavior will encapsulate some event handling logic. This event handling logic could have been written by the app developer in their code-behind, but moving it into a behavior makes it much more encapsulated and suited for reuse. It has the nice side-effect of making things a bit more designer-friendly by cleaning up the code-behind and turning things into a more XAML-friendly form.

Remember Google Suggest? That kicked off a spree of auto-complete implementations for use in Ajax apps including the one we did for ASP.NET Ajax (and later in the Ajax Control Toolkit). The AutoComplete behavior is very similar. It can be used to suggest various completions based on the text that a user has entered so far. This behavior allows extending the standard Silverlight TextBox control (as well as the WatermarkTextBox control). This post will cover various scenarios accomodated by the behavior I've put together.

The screenshot above illustrates the type of experience you can add to any TextBox. You can see and play with a live demo by scrolling toward the end of this post (this requires Silverlight 2). Of course, all of the code is available as well, so you can include this into your own app.

Scenario 1: Basic completion scenario
Lets assume I've got a TextBox on a form that allows your user to enter in the name of a city, and I also have a service on the server that accepts a string prefix and returns a set of matching city names as an array of strings (serialized using the JSON format). I'd like to hook the two of them together to improve the user experience of the form, by offering a list of suggestions.

Here's the most basic use of the AutoComplete behavior in XAML as a way to get started.

<TextBox x:Name="cityTextBox">
  <f:Form.AutoComplete>
    <f:AutoComplete ServiceUri="/App_Services/Cities.ashx" />
  </f:Form.AutoComplete>
</TextBox>

Done... no code required! The AutoComplete instance assigned to the Form.AutoComplete attached property listens the TextBox events and in the background fetches city suggestions, displays a dropdown list with the cities, and allows the user to pick one. The AutoComplete does all sorts of fancy things by default like not fire off a web request per keystroke, cache results etc. As you can see the declarative XAML-based usage model makes the scenario quite simple to implement.

[... continued here]

[ Tags: | | ]
Comments (12)

Silverlight Behaviors

In the past, I've written about behaviors and control extenders in the context of Ajax and HTML-based UI. This post introduces a similar behavior semantics for Silverlight and XAML-based UI as well.

The mini-behavior framework I have prototyped allows you to write and use behavior as a combination of a component + an attached property. The framework provides the logic to attach/detach behaviors for behavior authors. The rest of this post demonstrates using and writing a simple behavior based on this framework. Over the next few posts, I'll discuss a few more behaviors as a way to further experiment and demonstrate the behavior concept.

Using the DefaultCommit Behavior
Lets say you're implementing a typical form with a TextBox and a search Button. You'll probably want to allow users to press the Enter key after typing in some search keywords to kick off the search rather than force them to click the button explicitly. What you'd normally do is write a couple of event handlers to handle both the Click event from the Button and the KeyDown event from the TextBox (to look for the Enter key) in your code-behind, and trigger the search logic from each of them. This is more complicated and messy than it needs to be.

Ideally you simply want to handle a single event - the button's Click event. In fact, in HTML forms, this is built in into the notion of a Form with a submit button. However, it isn't so in Silverlight, where a Form concept is baked in. This is where this behavior comes in. Once this behavior is available, I can author the following XAML:

<TextBox x:Name="searchTextBox">
  <f:Form.Commit>
    <f:DefaultCommit ButtonName="searchButton" />
  </f:Form.Commit>
</TextBox>
<f:Button x:Name="searchButton" Content="Search"
  Click="OnSearchButtonClick" />
[... continued here]

[ Tags: | | ]
Comments (9)

Live Mesh

Live Mesh is finally public - it was announced earlier today at the Web 2.0 conference. We’ve had the social graph buzzword bantered around for some time in the context of Facebook. Will mesh become the next one to go around? Check out the intro post. Live Mesh is all about software + services, and connecting and bringing devices together into your own personal "mesh" enabling them to work in a connected way.

Ray Ozzie alluded to the Web as the Hub of the social mesh and the device mesh earlier at MIX08. Over on the Live Mesh blog, Mike Zintel alludes to a bunch of concepts around the Live Mesh platform, such as mesh object, and a data synchronization platform. I am particularly excited about the prospect of seeing a new generation of Web apps that leverage the platform in all sorts of interesting ways, not just for local storage, but also synchronized local storage of application data and personal data, and offline execution, as a means to differentiate and cater to new user experiences on the Web. The APIs that emerge around this platform will be something to keep an eye on.

On another personal note, I am super excited to see and run the Web version of Live Mesh, which simulates a Vista desktop and Explorer folders right within your Web browser for anywhere access to your devices and a data. While it will be interesting to see the user reactions around this UI metaphor in the browser as shown in the screenshot, the Ajax code behind the scenes is pretty much written in Script# (I've worked with the team for a while), and now that the site is public, I’ve added it to the new showcase page on my project site.


[ Tags: | | ]
Comments (6)

Script# 0.5 Update and Associated CodePlex Project

This is a quick post on the latest release of Script# (Build 0.5). I'll be following up with subsequent posts with more details on some of the specific feature additions, but here is a list of whats new (besides bug fixes, and improved compiler error reporting):

  • Support for localization based on .resx files - now you can generate localized script files while using strongly typed resources using .resx tooling available in Visual Studio and other localization tools.
  • Support for generating script doc-comments - now XML doc-comments are automatically transformed into ASP.NET Ajax-style doc-comments, which are useful for driving intellisense in Visual Studio, if you're creating script libraries that will be used by others.
  • Updated compat layer to abstract browser differences now works for not just Mozilla but also WebKit-based (Safari, iPhone), and Opera browsers.
  • Support for creating overloaded APIs, and creating and invoking functions dynamically (these were limitations in the past).
  • Support for creating Silverlight 2 plugin instances.

Also, Script# is now on CodePlex (actually it has been on there for a month or so, but this is the first release since). The forums associated with the CodePlex project should significantly improve the experience around sending feedback, and having discussions around the technology and using it. Several folks have asked me in the past about open sourcing it. My plan is to eventually have the source out there as the project approaches its v1 status, starting the with the core framework and runtime, and subsequently the compiler itself. Stay tuned on that front for more in the next few months.

There are a couple of related CodePlex projects to call out:

  • Messenger Developer Samples - contains MIX08 Messenger samples including how you can use Messenger APIs using Script#
  • Script# proxy generator - Think wsdl.exe for Script#. A number of you have sent me mail about this feature. This project basically takes care of generating C# proxies for ASP.NET Ajax-enabled Web services.

Finally, I've updated my project site as well with more introduction to Script#, release notes, and a high-level roadmap. I will also be transitioning the documentation that is currently available in pdf form to the site over time.


[ Tags: | | | ]
Comments (20)

Ajax Templates

Just over a month ago, at MIX08, I presented a talk on Real-World Ajax. One of the demos I included was an Ajax templating technique to demonstrate separation of presentation and content from behavior to help manage script complexity, and to help facilitate designer/developer workflow.

The demo was based on early thoughts around what we need to do in this area. What is presented here is still quite simplistic in terms of the range of options it provides to developers. The demo worked well with the audience, and I'd love to hear any feedback people have in this area that can be fed into the design process at this early stage (I alluded to this work in comments to my Ajax vs. Silverlight post).

Here is my scenario - in my Ajax app, script issues a web request to fetch a list of data, in this case a list of bookmarks, and constructs HTML to visualize the results. This is often implemented as follows:

<div id="bookmarkList"></div>
<script type="text/javascript">
function fetchBookmarks() { 
    // Issue an XMLHTTP request to retrieve user's bookmarks.
}
function onBookmarksAvailable(bookmarks) {
    // Update display using retrieved bookmarks. Each boomark has Url and Title properties.
    var sb = new Sys.StringBuilder();
    sb.append("<ul>");
    for (var i = 0; i < bookmarks.length; i++) {
        sb.append("<li>");
        sb.append("<a href=\"");
        sb.append(bookmarks[i].Url);
        sb.append("\">");
        sb.append(bookmarks[i].Title);
        sb.append("</li>");
    }
    sb.append("</ul>");
    $get('bookmarkList').innerHTML = sb.toString();
}
</script>

This works. However, there is a problem. The definition of the UI is now embedded in script. Its hard to design and change it. And its hard to preview it without running the page. The problem is worse if the structure of each item is more complicated than what the sample tries to do.

Here is where templating comes into the picture. Templates have been super common in server-side frameworks like ASP.NET, and are now popping up in client-side script frameworks, as Ajax apps start becoming more client-centric. With templating the developer or designer can define the structure of an item in regular markup, and the templating engine is then responsible for generating the script equivalent.

[... continued here]

[ Tags: | | ]
Comments (27)

Ajax vs. Silverlight and .NET

I get the Silverlight vs. Ajax question all the time, whether it is at a conference, over email, or over on discussion forums. In the interest of seeding a broader discussion, and hearing what other people think, I thought this would be an interesting blog post, along with the side benefit of having a ready-made answer the next time the topic comes up.

There have been a number of blog posts pitching Ajax vs. RIA (whether its Flash or Silverlight) such as this one here. Personally, I think Ajax and Silverlight complement each other, and the "vs." is a bit misplaced. Furthermore, the way I see it, there is a continuum, with a number of sweet spots representing specific classes of applications. This perspective is perhaps directly reflected in the makeup of the UIFX team that I work on at Microsoft - the team is spread across ASP.NET, Ajax, Silverlight and RIA frameworks all at once actively working on cool stuff in each of these areas (i.e. lots to look forward to).


User-facing Application Spectrum

[... continued here]

[ Tags: | | | ]
Comments (28)

Facebook Client Library built on Script#

While developing Facebook.NET, it was on the back of my mind to create a script library equivalent in script# for client-side only interaction with the Facebook REST API using the existing JSONP interface to their REST service. I didn't do it yet for security reasons, as it would require sending down both the application key and secret to the client (something that existing Flash and Silverlight examples unfortunately and incorrectly show). Instead I opt'd for creating a Facebook Proxy service that allows your client code to talk to facebook via your service in an almost transparent manner. Those of you who have downloaded Facebook.NET can see a sample of this.

Now Facebook is offering a client-side SDK. Wei Zhu blogged about the JavaScript Client Library for the Facebook API on the official developer blog last Friday. If you're a Facebook application developer, you'll want to check this out.

Wei Zhu has been a long-time supporter of Script#, and it makes me super excited to see that the library itself was coded in Script#, and also uses the Script# runtime as part of its implementation. I am sure Script# usage resulted in some substantial productivity gains, and makes me hopeful that this will spike some more interest in the technology. Its also exciting to see the potential for a number of Facebook apps built on top of this. I am hopeful that Facebook will eventually release the .dll version of the script, so other downstream users of Script# will be able to directly reference these APIs in their C# code, without having to create a stub metadata dll

I also chatted with Wei during the weekend about possible security implications. It looks like they've thought through the implications. Specifically, you only need to publish the API key (which is public anyway), and the client library connects with Facebook to generate a temporary user-session scoped secret using some new services, so you don't have to publish your actual secret. Nice!


[ Tags: | ]
Comments (11)