Minggu, 23 Januari 2011

See Me in Brazil and Argentina in March


Along with James Senior, I’ll be speaking at a couple of free Web Camps events in South America in March 2011.

argentina_flagBrazil_flag

Buenos Aires, Argentina – March 14-15, 2011

São Paulo, Brazil – March 18-19, 2011

The registration links are not yet available, but I’ll update this blog post once they are. For a list of all upcoming Web Camps events, see the events list.

If you’re not familiar with Web Camps, the website provides the following description, emphasis mine:

Microsoft's 2 day Web Camps are events that allow you to learn and build websites using ASP.NET MVC, WebMatrix, OData and more. Register today at a location near you! These events will cover all 3 topics and will have presentations on day 1 with hands on development on day 2. They will be available at 7 countries worldwide with dates and locations confirming soon.

Did I mention that these events are free? The description neglects to mention NuGet, but you can bet I’ll talk about that as well. Smile

I’m really excited to visit South America (this will be my first time) and I hope that schedules align in a way that I can catch a Fútbol/Futebol game or two. I also need to brush up on my Spanish for Argentina and learn a bit of Portugese for Brazil.

One interesting thing I’m learning is that visiting Brazil requires a Visa (Argentina does not) which is a heavyweight process. According to the instructions I received, it takes a minimum of 40 business days to receive the Visa! Wow. I’m sure the churrascaria will be worth it though.

Good thing I’m getting started on this early. Hey Brazil, I promise not to trash your country. So feel free to make my application go through more quickly.

View/ViewModel Interaction - Bindings, Commands and Triggers


It looks like I have a set of posts on ViewModel, aka MVVM, that have organically emerged into a series or story of sorts.





Recently, I blogged about The Case for ViewModel, and another on View/ViewModel Association using Convention and Configuration, and a long while back now, I posted an Introduction to the ViewModel Pattern as I was myself picking up this pattern, which has since become the natural way for me to program client applications. This installment adds to this on-going series. I've alluded to this topic in the past, but it is now time to focus and dedicate a post on the interactions between a view and its view model, i.e. the arrows in the diagram below:


The ViewModel Pattern


I like to present ViewModel as something that is not brand-new, but a simple refactoring of [most of the] code-behind into a separate class so that the logic is decoupled from the user interface. This class simply employs the basic OOP constructs that you might have encountered in CS101 - it encapsulates state and behavior, exposed via properties, methods and events.





As simple as properties, methods and events...


All view models will encapsulate some interesting application state or data, exposed as properties, usually, in an observable form, i.e. properties that raise change notifications. Almost all view models will also expose some operations, ideally exposed as vanilla methods. And finally, some view models will also raise application-specific notifications as events.





Declarative glue...


A view is then responsible for consuming and working against the object model exposed by its view model as it presents information, and collect and react to user input, gestures etc. The data-binding engine in Silverlight makes it natural to bind to the properties in one-way or two-way fashion. Commands (in the UI, not in the view model - will address this below) allow invoking operations, usually in response to some user input or external inputs (eg. a timer or GPS input). Finally triggers allow the view to listen to events and translate view model notifications into user interface actions. All of these serve as glue expressed in XAML via declarative markup.


This is captured in the diagram above. Bindings are fairly straightforward and you've more than likely used them if you've done any Silverlight programming. So I am mostly going to focus on commands and triggers, but first, lets see this pattern in action.





An example application...


Translation Application ScreenshotAs always, an example helps make things concrete. I converted Tim Heuer's translation/text-to-speech application to follow the view model. In doing so I used the latest release of Silverlight.FX - while the ViewModel is an abstract presentation, it is useful to pick up a framework that allows you to quickly get started with your application, rather than build the plumbing from scratch.


On the right is a screen shot of the application. It is also now included as part of a series of sample applications packaged with Silverlight.FX. You can dowload the latest version (v3.5) by visiting the project page. I'll have a Silverlight 4 version that takes advantage of new capabilities, but in the mean time the Silverlight 3 version should continue to work. The sample application here uses v2 of Microsoft Translator API, which now has support for not just translating text, but also converting text to speech for a specific set of languages. You'll need to get an API key and update the web.config in the sample on your end to run the application.


TranslateWindowModel Object Model


The class diagram of the view model highlights the interesting things going on in the view model:


In terms of application state, it exposes the text to be translated, the resulting translated text, the list of languages, and whether the speak operation can be performed. In terms of operations, it provides the ability to perform translation, or to speak (as in produce the audio stream) the translated text. Finally in terms of notifications, it lets its associated view know when that audio stream has been loaded and is available for playing.



[Full post continued here...]

Using ASP.NET Authentication in a Web Service with Silverlight

Using ASP.NET Authentication in a Web Service with Silverlight:

A reader recently asked me to expand on the ASP.NET Authentication + Silverlight concept I started.. Specifically they wanted to do know how they can have a web service that returns different results depending on who calls the service (and what role they are in).

Here is my quick walk through of adding that capability to the Silverlight+ASP.NET AppServices sample.

First, let's look at the scenario we are trying to enable. I wanted to add a "Fire Bob" button. Hopefully, no line of business application has a "fire employee" button, but I thought it showed of the concepts well. Clearly only managers should be able to fire bob, so the button should be grayed out if you are not logged in or logged in but not in the manager role.

image

Logging as manager enables the button and clicking on it actually does the firing and reports status. Notice the background color is a user preference of manager.

image

And when logged in as an employee, the button is grayed out.

image

Defining the service

The first step to enabling this is to define a web service that will fire the employee and offer a way to check to see if you can fire the employee.

In the web project, add a new item and select the new (in Beta2) Silverlight-enabled WCF service

image

Then define the service as such:

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web;

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class FireEmployeeService2
{
[OperationContract]
public void FireEmployee(string employeeName)
{
if (CanFireEmployees())
{
DoTheDirtyWork(employeeName);
}

}
public void DoTheDirtyWork(string employeeName)
{
//Proceed to fire the employee

}
[OperationContract]
public bool CanFireEmployees()
{
return HttpContext.Current.User.IsInRole("Management");

}
}



Notice we are defining two entry points, one to check (CanFireEmployees) and one the actually fire. Clearly in a real world scenario you'd want a few more checks here and more of a model where you start a workflow.. The key thing here is the call to User.IsInRole().. the great thing here is that logging in on the client means you are also logged in on the server! So this just works.



In the Silverlight project, right click and add a service reference. Hit "Discover" and select the right one.



image



In the login_Competed method, go ahead and check to see if this person can fire the employee



FireEmployeeService2Client fireClient = new FireEmployeeService2Client();
fireClient.CanFireEmployeesAsync();
fireClient.CanFireEmployeesCompleted +=
new EventHandler<CanFireEmployeesCompletedEventArgs>(fireClient_CanFireEmployeesCompleted);
this.fireButton.IsEnabled = false;




Then when the call completes,simply set the buttons enable status based on the results.



void fireClient_CanFireEmployeesCompleted(object sender, CanFireEmployeesCompletedEventArgs e)
{
this.fireButton.IsEnabled = e.Result;
}




Then, the actual implementation of the fire button is streight forward, following all the patterns we have setup for this sort of thing.



private void fireButton_Click(object sender, RoutedEventArgs e)
{
this.fireLabel.Text = "Trying to fire...";
var client = new FireEmployeeService2Client();
client.FireEmployeeAsync("bob");
client.FireEmployeeCompleted += new EventHandler<AsyncCompletedEventArgs>(client_FireEmployeeCompleted);
}

void client_FireEmployeeCompleted(object sender, AsyncCompletedEventArgs e)
{

if (e.Error != null)
fireLabel.Text = e.Error.ToString();
else
fireLabel.Text = "Call Succeed";
}


Hope that helps! you can get the full project here.

Data focused Silverlight demo


Yet still more time on traveling, I thought I'd do a little demo of a data oriented scenario with Silverlight.


Here is what we are after:


image


The data for the app is loaded from a Linq model and sent to the Silverlight client via a WCF services.
As the user makes changes to the grid, we asynchronously update the Linq model on the service.
The app uses local storage to cache the data on the local machine to reduce network calls.


Create a new Silverlight application and associated web site.


image


Let's start by creating a data model in the web site.


image


Then drag over the Employees table.


image


Then, Select Photo and delete it. It is a large binary blob that we don't want to be sending back and forth.


Then, because we are going to expose this over a WCF service, let's make it Serializable.


image


Now let's add the WCF service. Be sure to select the Silverlight-enabled WCF service.


image


Then the implantation is straight forward. In this method you can customize based on the user's role, do paging, etc. For now, I will just take the first 15 for this demo.

[OperationContract]
public IEnumerable<Employee> GetAllEmployees()
{
var context = new NorthwindDataContext();
var q = from employee in context.Employees
select employee;
return q.Take(15).ToList();
}

Now in the client, we need to add a reference to this service.


image


Then define a very simple UI...

        <StackPanel>
<
Button x:Name='btn1' Width='100' Height='50' Content='Load Grid' Click='btn1_Click' RenderTransformOrigin="0.5,0.5"></Button>
<
my:DataGrid x:Name='dataGrid' ></my:DataGrid>
<
TextBlock x:Name="label"></TextBlock>
</
StackPanel>

And handle the button click

private void btn1_Click(object sender, RoutedEventArgs e)
{
var client = new EmployeeService.EmployeesServiceClient();
client.GetAllEmployeesAsync();
client.GetAllEmployeesCompleted += new EventHandler<GetAllEmployeesCompletedEventArgs>(client_GetAllEmployeesCompleted);
label.Text = 'Sending Request';
}

void client_GetAllEmployeesCompleted(object sender, GetAllEmployeesCompletedEventArgs e)
{
dataGrid.ItemsSource = e.Result;
label.Text = 'Got results from network';
}


Now let's send up the changes as the user changes the values in the grid.


What we want to do is sign up for changes on each row. The interesting thing here is that we recycle the rows, so we have to be careful to not sign up for an event more than once. The solution we came up with was to listen for the Loading and Unloading row events and register, unregiser the events on each.


So DataGrid looks like this:

            <my:DataGrid Width='600' Height='200' x:Name='dataGrid' UnloadingRow='dataGrid_UnloadingRow' LoadingRow='dataGrid_LoadingRow' AutoGenerateColumns="True"></my:DataGrid>

And the code:

    private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
((Employee)e.Row.DataContext).PropertyChanged +=
new PropertyChangedEventHandler(Page_PropertyChanged);
}

private void dataGrid_UnloadingRow(object sender, DataGridRowEventArgs e)
{
((Employee)e.Row.DataContext).PropertyChanged -=
new PropertyChangedEventHandler(Page_PropertyChanged);

}
void Page_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Employee ep = sender as Employee;
label.Text = 'Employee ' + ep.EmployeeID + ' changed. Updating network';
}

With this, as the user changes values in the grid, this PropertyChanged event is called.


image


Now all we need to do is call the server with the changed data.


To do that, let's go back and add a new web service.

public void UpdateEmployee(Employee employee)
{
NorthwindDataContext context = new NorthwindDataContext();
var oldEmployee = (from e in context.Employees
where e.EmployeeID == employee.EmployeeID
select e).First();

oldEmployee.FirstName = employee.FirstName;
oldEmployee.LastName = employee.LastName;
// add the rest of the properites

context.SubmitChanges();
}

Note: There are of course easier\better ways to do this sort of updating in linq... http://msdn.microsoft.com/en-us/library/bb425822.aspx


Then back to the Silverlight client and update the reference


image


Now, add a few lines to call this method and we are set.

void Page_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Employee ep = sender as Employee;
label.Text = 'Employee ' + ep.EmployeeID + ' changed. Updating network';
var client = new EmployeeService.EmployeesServiceClient();
client.UpdateEmployeeCompleted += new EventHandler<AsyncCompletedEventArgs>(client_UpdateEmployeeCompleted);
client.UpdateEmployeeAsync(ep,ep.EmployeeID);
}

void client_UpdateEmployeeCompleted(object sender, AsyncCompletedEventArgs e)
{
label.Text = 'Employee ID'+e.UserState+' successfully updated';
}

Run it and it works great!


image


Make changes, refresh to be sure the changes are reflected in the underlying datamodel.


OK, for a final step, let's see if we can cache this data offline in Silverlight's per-application Isolated Storage.


Add the following to the page class

private IsolatedStorageSettings appSettings =
IsolatedStorageSettings.ApplicationSettings;


To client_GetAllEmployeesCompleted add

appSettings['backStore'] = e.Result;
appSettings.Save();

This saves the backStore into the local store.


To the Page constructor add

if (appSettings.Contains('backStore'))
{
label.Text = 'loading data from local store';
dataGrid.ItemsSource = appSettings['backStore'] as IEnumerable;
}
else
{
label.Text = 'No local data';
}

If there is data in the store, we use it.


Run it... the first time, no data..


image


Hit load and refresh and you should have local data


image


Now, just to be sure things are working the way we expect, right click on the Silverlight control, select Application Storage and Delete this one for this app. Notice it says zero as a rounding issue,there is so data there.


image


Hit refresh and it is back to no data. Just as we expected.


In this post we:

Got the data for the app is loaded from a Linq model and sent to the Silverlight client via a WCF services.
As the user makes changes to the grid, we asynchronously update the Linq model on the service.
The app uses local storage to cache the data on the local machine to reduce network calls.

Download the full sample here.

ASP.NET Dynamic Data: Customizing the UI


In my last post on Dynamic Data, I showed what Dynamic Data adds to the current ASP.NET data story. In this post I show how to customize the UI with Metadata, field templates, and page templates.

I start off by showing off the Dynamic Data Wizard.

File\New WebSite

image

Create a new connection, in this case using SqlExpress

image

It may take a minute, but the wizard will load the database metadata.. let's select just a few tables for this demo

image

The next step is customizing the project that gets generated. For this demo, we will Add All.

image

Next, we can do some further customization of the end application..

image

The resulting application looks great. Notice the automatic filtering, navigation between tables, editing and validation.

image

Custom Metadata

Dynamic Data works off the metadata in the data model. As you see from above there is already a lot of this in the database. But we can customize it and add more.

In NorthwindDataContextPartialClass.cs,

We customize the error message to be more friendly..

[Required(ErrorMessage="Please fill in the product name")]
public object ProductName {





Set a maximize string length



[StringLength (20)]
public object QuantityPerUnit {


image 


And customize formatting



[DisplayFormat(DataFormatString="{0:C}")]
public object UnitPrice {





image



There are many other customization, and it is an extensible system, so you can add your own!





Custom Field Templates



In the DynamicData\FieldTempates directory you will find some default field templates. Dynamic Data uses these to render values based on their type. As an example, change the Text template as such:



String(

<asp:Literal runat="server" ID="Literal1" Text="<%# FieldValueString %>" />

)



image



Now, clearly this particular modification is not that useful.... But for example if you wanted to change the check box rendering to say "True" or "False". That is easily done by editing the boolean template as such:



<asp:Label runat="server" ID="label"></asp:Label>




public partial class BooleanField : System.Web.DynamicData.FieldTemplateUserControl {
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);

label.Text = "False";
object val = FieldValue;
if (val != null && Convert.ToBoolean(FieldValue))
label.Text = "True";

}

public override Control DataControl {
get {
return label;
}
}
}


Now, that readers as:



image 




There are a bunch of other things you can do... Use third party controls, etc.






Custom Page Templates



In the DynamicData\PageTemplates directory you will find the default rendering for all the kinds of pages. Changing these templates changes how all "Lists" or "ListDetails" are rendered.



image



From the URL, you can see that the table in we are using is "Products" and we are using the "List" view. Change the List.aspx template as follows:



    <h2>My Customization: <%= table.DisplayName%></h2>




image image



But notice, Categories does not have this customization.



That is because we have defined a further customization just for the Categories table. Look in DynamicPages\CustomPages\Categories\List.aspx



image







In this post I show how to customize the UI with Metadata, field templates, and page templates. You can get the final project here.



Enjoy!

Loving the South African Developer Community


I just got back from South Africa and I am happy to report that the .NET Developer community is very strong there.

User's Group Meetings in in Johannesburg and Cape Town

  • User group meeting in Johannesburg - thanks for setting this up Craig Nicholson.. I had a great time showing off Silverlight 2. We had lot of fun talking about Silverlight wit these slides and demo that I did. I also showed HardRock DeepZoom, the video wall and HSN.TV
  • User group meeting in Cape Town - Thanks to Hilton Giesenow for setting this up. This time I did a drill down into the ASP.NET MVC framework. The response was excellent! Thanks folks for your questions and interest! Here is the slides and demo..

Mix Essentials in Johannesburg and Cape Town

We had over 664 developers\designers attend the events in both cities… A little over 3/5th of them were developers and the vast majority of them were active ASP.NET developers. Just about everyone was already on VS2008.

clip_image001 clip_image002

Keynote:

We kicked off the day with keynote highlighting Microsoft’s investment in UX. I got drafted to do a breif bit on to show off some of the great work we are doing in WPF for SP1. So I showed the very cool WPF Bitmaps effects demo ScottGu showed at Mix '08 in Vegas… Judging from the comments afterward, I think it got a few people thinking about what is possible with a desktop applications. People were impressed that the CPU was not being chewed up by this..

clip_image003

For the rest of the day we split up – the designers when to a different room and I kept all of the developers. I did three sessions covering the full web development space. The retention rate was really good… just about everyone stuck around for the end.

Silverlight 2:

Next up I did an hour fifteen minute demo on Silverlight 2 development. I focused on end-to-end development, not just the UI glitz side of Silverlight and the audience responded very where. Rather than going through a bunch of slides I created an application from scratch that does read\write data access via WCF and LINQ as well as local storage via Isolated storage Here is part of the flow I used: http://blogs.msdn.com/brada/archive/2008/06/26/data-focused-silverlight-demo.aspx and http://blogs.msdn.com/brada/archive/2008/06/23/using-asp-net-authentication-in-a-web-service-with-silverlight.aspx. Thanks Scott Morrison for your help with this! Here are the slides I used to kick it off.

Ajax:

I had a great time doing this ajax demo… It was basically a reprise of my Mix 08 talk which is an all demo talk.. I could tell people really loved it! Because I had just come back from Safari, I re-themed it with my pictures.

clip_image005


MVC:

I split the last talk on the “future of ASP.NET” into two parts… Part 1 was on MVC. The “no viewstate” and the “IDs not mangled” were winners! Folks generally seemed to get that they did not have to move to ASP.NET MVC. The two consistent big asks where for better\more ajax support and some sort of reusable component support. I think we are well on our way to address both of those. Here are the slides and demo I used.

Dynamic Data:

This talk was a real crowd pleaser. I started off by showing how to change an existing site into being Dynamic Data aware and this really drove home the point about the value Dynamic Data adds. http://blogs.msdn.com/brada/archive/2008/06/20/asp-net-dynamicdata-an-introductory-demo.aspx . By this point ½ the room was already sold… but there was much more. I then used the wizard to show off all the customization capabilities of DD. That pulled the rest of them in. http://blogs.msdn.com/brada/archive/2008/06/27/asp-net-dynamic-data-customizing-the-ui.aspx . The questions here were all about support for different data sources. NHibernate, plain old objects, etc. I think we have a great story here and I wish I would have had time to demo it. Here are the slides I used

Closing

I had a little fun to close out the event. Through the day I had been throwing out giveaways (t-shirts\balls\hats) whenever someone asked a question or pointed out a bug I had made (there were a few!). But I was left with a big Microsoft keyboard that I didn’t want to through. So I ask for a volunteer to come up and code something on stage like I had done all day! I chose creating a LINQ model over top of Northwind as I did that like 5 different times during the event so I thought it was fair. The victims.. ah, I mean volunteers at the Cape Town and Johannesburg events did well! They started off kind of shaky and made me nervous, but they got in and nailed it! It was a good fun time for all as the audience “helped” out a bit by yelling suggestions. One guy even said “you owe me ½ that keyboard” when he finally go it ;-). Oh, and some folks asked me about the zooming tool I used to zoom in on the screen. It is called ZoomIt.

clip_image006

Here are a few blog posts I have already seen from the event..

http://liamb.com/2008/06/23/brad-abrams-visits-south-africa/
http://metallemon.blogspot.com/2008/06/mix-essentials-2008.html
http://www.fremus.co.za/blog/2008/06/first-experiences-with-visual-studio-2008/

I'd love to hear your feedback\thoughts on this... and if you blogged on the event please let me know and I will add your link here.

Oh, and I did spent a few days on Safari at Mala Mala adjacent to Krueger national park. I was amazed at the big game viewing... I highly recommend it. Here are some photos.

image image

Great User Experience Example in a Business Application


DNR-TV has a great talk\demo with Billy Hollis on a next generation business applications in WPF and Silverlight. Billy is working with a customer to provide a temp worker to job matching services. So far the application is in WPF, but they are planning to create a Silverlight version as well. Watch the web cast for a full demo.

A few things I thought was cool:

  1. They use visual clues effectively to direct the users attention (for example per-entity model pop-ups)
  2. They multiple-module editing model. Many records can be edited at the same time. There is great navigation and notification support to manage all of this.
  3. Dirty tracking seems nicely done.

Billy, we are all looking forward to playing with the real thing!

Here are a few screen shots:

image

image