Brad Abrams's complete blog can be found at: http://blogs.msdn.com/brada

Items:   1 to 5 of 543   Next »

Tuesday, April 20, 2010

Wow – I can’t believe it has already been 13 years at Microsoft.  I have had a great time here and learned so much from the smart and passionate people I work with as well as the incredible developer community around .NET.  But I have decided it is time for me to try something new – so my last day at Microsoft will be Friday, April 23rd . 

While I am leaving Microsoft, I continue to have a positive view of the company.   No other company has the footprint that Microsoft does on the industry.   I am confident that the company will continue to have an impact in the years to come.   I will be looking forward to watching the next release of .NET from outside. 

Of course, there is never a good time to leave, but I feel a great sense of accomplishment shipping Silverlight 4 and Visual Studio 2010/.NET Framework 4.  The technologies I have been most closely involved with have found amazingly good homes.  MEF and RIA Services are in the right teams and on the right track long term and I believe those technologies will have great futures.  

What I loved most about my time at Microsoft is the opportunity to work with some of the smartest, most passionate people in the industry to ship some great software that customers LOVE.   As I have been thinking about this transition, I have reflected on a few of the releases I have been a part of and what I learned in the process.     Hopefully you can take these learnings as my last words of wisdom to you. 

  

  • MS-Travel  (later spun off as Expedia )  - My first experience at Microsoft as an intern in Test.  I landed the job because I was able to help my future boss debug a VB issue in the interview ;-).  I learned what it was to be a PM and I fell in LOVE with it. 
  • VB 5  - I came back the next summer as a PM intern and found my sweet spot – PM in the developer space.  I was a PM on the Control Creation Edition of VB 5 and learned the blocking and tackling of consensus building, prioritization and specing! 
  • IE4 and  IE4.01 with Win98 -  It was so energizing to be involved in the first browser wars.   At the time, I think we had IE4, 5 and 6 all going in parallel!   As Release PM I learned a ton about shipping: balancing priorities, triaging, war rooms, and working very broadly across teams. 
  • Common Language Runtime (“Lightning”) and overall .NET Framework (“Project 42”).  In the 4+ years incubating the first release I got my taste for “doing a V1” and I loved it!  We all *knew* we were changing the industry with our work as much as we knew the project could be canceled at any time.  After PDC2000, when we came out of the veil of secrecy, I learned about how to listen to customers and got hooked on bringing customer feedback into the product with the DOTNET@DISCUSS.DEVELOP.COM email list.  If you were on that email list at the time, you helped shape what become the glasnost of Microsoft that lead to weblogs.asp.net, blogs.msdn.com, and eventually channel 9 and the whole community arm of MS.   
  • .NET Framework 1.1   (“Everett” ) and .NET Framework 2.0 (“Whidbey”)  - Between these two releases, I learned about the “V2 trap”.  That is, the critical importance of having a clear vision for a release rather than just “make stuff better”.   It is so much more valuable to customers, and therefore more satisfying for engineers,  to work on “3-big bets” rather than peanut-buttering our efforts over a bunch of small “rounding out” features. 
  • .NET Framework 3.0 with Windows Vista (“WinFX”)  – Back to my “V1.0 passions”, with this release we aimed to make .NET the most important programming model for Windows.  With broad new technologies, WF, WinFS, WCF and WPF there was a LOT of new stuff.  I was asked to bringing this work together to a coherent whole.  I learned a TON about how to develop software at scale and what works (and doesn’t) across such a large organization. This experience also gave me much deeper insight into executive decision making and what works (and doesn’t) to get the most effective decisions made.  
  • ASP.NET 3.5, ASP.NET AJAX and ASP.NET MVC – I learned a whole new development area – AJAX and the web.  This time lit my passion for the web development area that I continue to believe is a game changer.   I learned the value of shipping out of band releases to clearly address customer scenarios as they emerge.  I also learned the value of small, lightweight (download size, concept count, etc) frameworks. 
  • Silverlight 2, 3 and now 4 That rate of maturation of Silverlight has been amazing.  From the first release where there was literally no button, to Silverlight 4 where we have a viable line of business platform.  Here I learned a lot about how to do small, frequent,  incremental releases.  
  • MEF – This technology has a huge potential to change the core patterns the average .NET Developer uses to build their applications. Through this release, I learned two big things:  The value of a close customer (eg VS) shaping and guiding requirements and how to work diligently with the community in a very transparent way (shipping source, open license, etc).   
  • WCF RIA Services - The thing I love about RIA Services is that we tackled an end-to-end customer scenario that crossed database, mid-tier, client and tooling to deliver really compelling customer value.   While this sort of end-to-end thinking forced us to work very closely with many teams, the results were fantastic!   Out of this release I learned the value of focusing on the end-to-end rather than just one small island.

I am deeply grateful for the opportunities I have had at Microsoft in working with such an amazing set of co-workers and vibrant community.

Initially, I am going to take some time off to enjoy the wonderful spring weather in Seattle and visit Legoland with the kids before starting my next endeavor.  

While I will not be as deeply involved in the .NET Developer Community – I will be keeping up and enjoying the successes I know you will have.    Good luck and have a great time! 

I’d love to stay in touch:

Email: BradA42@gmail.com

Blog: http://bradabrams.com

Twitter: @BradA

Facebook:  Brad Abrams


Monday, April 12, 2010

Continuing in our series, I wanted to touch on how a RIA Services can be exposed  your service in JSON.  This is very handy for Ajax clients.

 

The great thing is that enabling the JSON endpoint is that it requires NO changes whatsoever to the DomainService.  All you need to do is enable it is to add the JSON endpoint in web.config

  1:   <system.serviceModel>
  2:     <domainServices>
  3:       <endpoints>
  4:         <add name="JSON"
  5:              type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  6:         <add name="OData"
  7:              type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  8:         <add name="Soap"
  9:              type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
 10:       </endpoints>
 11:     </domainServices>
 12: 

 

As you can see, this above snippet shows adding the JSON endpoint from the RIA Services toolkit as well as the OData and Soap ones. 

You can see the endpoint results navigate to the URL in this format:

http://localhost:21516/BusinessApplication1-web-DishViewDomainService.svc/Json/GetRestaurants

image

 

{"GetRestaurantsResult":{"TotalCount":-2,"IncludedResults":[],
"RootResults":[{"Address":"49 Gilbert St.","City":"London",
"ContactName":"Charlotte Cooper","ContactTitle":"Purchasing Manager",
"Fax":"(171) 555-2222","HomePage":"","ID":1,"ImagePath":
"Restaurant_Alinea.jpg","Name":"Alinea - Updated from Ajax",
"Phone":"(171) 555-2222","PostalCode":"EC1 4SD","Region":""},
{"Address":"P.O. Box 78934","City":"New Orleans","ContactName":
"Shelley Burke",
"ContactTitle":"Order 

 

As you can see – some nice looking JSon.   Now, to write a very simple Ajax client.

Below is an example query method in the Ajax client

         function query() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "BusinessApplication1-web-DishViewDomainService.svc/Json/GetRestaurants", false);
            xmlhttp.send();
            var rawResults = JSON.parse(xmlhttp.responseText);
            var results = rawResults.GetRestaurantsResult.RootResults;
            var entity
            for (var i = 0; i < results.length; i++) 
            {
                entity = results[i];
                document.getElementById('results').innerHTML += ' <br> ' + entity.Name;
            }
           
        }

This is wired up to to a very simple button

        <button type="button" onclick="query()">
            Query</button>
image

 

Update is just a bit more tricky…  but still basic:

        function update() {
            var operation = {};
            operation.Entity = { "__type": "Restaurant:#BusinessApplication1.Web", "ID": 1, "Name": "Alinea - Updated from Ajax"};
            operation.OriginalEntity = { "__type": "Restaurant:#BusinessApplication1.Web", "ID": 1, "Name": "Alinea" };
            operation.Operation = 3; //update
            var csData = JSON.stringify({ "changeSet": [operation] });
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'BusinessApplication1-web-DishViewDomainService.svc/Json/SubmitChanges', false);
            xmlhttp.setRequestHeader("Content-Type", "application/json");
            xmlhttp.send(csData);
            var results = xmlhttp.responseText;
            document.getElementById('results').innerHTML = results;
        }

 

 

In this demo, we showed how to enable the Ajax\JSON client for RIA Services.


Monday, March 29, 2010

Continuing in our series, I wanted to touch on how a RIA Services can be exposed as a Soap\WSDL service.   This is very useful if you want to enable the exact same business logic\data access logic is available to clients other than Silverlight.    For example to a WinForms application or WPF or even a console application.  SOAP is a particularly good model for interop with the Java\JEE world as well. 

 

First you need to add a reference to Microsoft.ServiceModel.DomainSerivves.Hosting.EndPoints assembly from the RIA Services toolkit. 

 

image

 

Then you need to edit the endpoints section of the domainserivces config in web.config  file.  Below I am showing the SOAP and OData endpoints enabled. 

 

  <system.serviceModel>
    <domainServices>
      <endpoints>
        <add name="OData" 
             type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <add name="Soap"
             type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </endpoints>
    </domainServices>
 
 
 

 

Now, all you have to do is navigate in the browser to this URL:

http://localhost:21516/BusinessApplication1-web-DishViewDomainService.svc

Note the pattern is [namespace]-[typename].svc

image

And we get the very familiar WCF service debug page.

And if you really want to drill in, here is the full WSDL describing the service.

image

 

You are done on the server, now let’s look at how you consume that on the client.    For the sake of simplicity, I have created a new Console application.  Right click on the project and select Add Services Reference.

image


image

  1: var context = new DishViewDomainServiceSoapClient();
  2: var results = context.GetRestaurants();
  3: foreach (var r in results.RootResults)
  4: {
  5:    Console.WriteLine(r.Name);
  6: }
  7: 

 

The code for query is very simple.  Line 1 creates the client proxy, line 2 does a synchronous call to the server. Then we simply loop through the results.

 

image

 

Updating the data is a little bit more interesting…    I need to create a ChanageSet that I populate with any updates. in this case I am updating just one value.  I also need to send the original value back to the server. 

  1: var changeSet = new ChangeSetEntry();
  2: var org = new Restaurant();
  3: org.ID = entity.ID;
  4: org.Name = entity.Name;
  5: entity.Name = "Updated:" + entity.Name;
  6: changeSet.Entity = entity;
  7: changeSet.OriginalEntity = org;
  8: changeSet.Operation = DomainOperation.Update;
  9: var updateResults = context.SubmitChanges(new ChangeSetEntry[] { changeSet });
 10: 

 

 

And you can see the result of running this a couple of times:

image

 

For more information, see Deepesh’s post on Configuring your DomainService for a Windows Phone 7 application

 

For V1.0, this post describes the RIA Services story for WPF applications.  While it works, it is clearly not the complete, end-to-end solution RIA Services offers for Silverlight.   For example, you may want the full experience:  the DataContext, entities with validation, LINQ queries, change tracking, etc.  This level of support for WPF is on the roadmap, but will not make V1.  But if you like the RIA Services approach, you might consider DevForce from IdeaBlade or CSLA.NET which works for both WPF and Silverlight.   The great folks at IdeaBlade have offered me 10 free licenses to give out.  If you are interested in one, please let me know.


Friday, March 26, 2010

To continue our series,  In real business applications our data is often very valuable and as such we need to know who is accessing what data and control certain data access to only users with privilege.  Luckily this is very easy to do with RIA Services.  For example, say we want to let only authenticated users access our data in this example.   That is as easy to accomplish as adding an attribute, see line 2 below. 

 

  1:     [EnableClientAccess]
  2:     [RequiresAuthentication]
  3:     public class DishViewDomainService : LinqToEntitiesDomainService<DishViewEntities>
  4:     {
  5: 

 

When we run the application, we now get an error.  Clearly you can do a bit better from a user experience angle… but the message is clear enough. 

  image_thumb[93]

 

Notice there is a login option, so we can log in…

image_thumb[107]

 

and even create a new user.

image_thumb[108]

 

and with a refresh we now get our data

image_thumb[97]

And the application knows who i am on the client and gives me a way to log out.

Now you can also easily interact with the current user on the server.  So for example, only return records that they have edited, or, in this case, log every access:

 

  1:         public IQueryable<Restaurant> GetRestaurants()
  2:         {
  3:             File.AppendAllLines(@"C:\Users\brada\Desktop\log.txt", new string[] {
  4:                 String.Format("{0}:{1}", DateTime.Now,
  5:                 this.ServiceContext.User.Identity.Name)});
  6:             return this.ObjectContext.Restaurants
  7:                 .Where (r=>r.Region != "NC")
  8:                 .OrderBy(r=>r.ID);
  9:         }
 10: 

 

Line 5 is the key one.. we are accessing the current users on the server.   This gives us a nice simple log.

3/7/2010 9:42:57 PM:darb
3/7/2010 9:43:05 PM:darb

Now we can also personalize this a bit.  Say we want our users to be able to give us a favorite color and we keep track of that on the server and the client, so it works seamlessly from any machine. 

First we need to add BackgroundColor to our backing store.  I this case I am using ASP.NET profile storage, so I add the right stuff to web.config

image_thumb[103]

Then I need to access this from the Silverlight client, so I add a property to the User instance in the Models\User.cs

    public partial class User : UserBase
    {
        public string FriendlyName { get; set; }
        public string BackgroundColor { get; set; }
    }

Finally, we need to access  it on the client.   In main.xaml add lines 2 and 3..

  1:   <Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootGridStyle}"
  2:         Background="{Binding Path=User.BackgroundColor}"
  3:         DataContext="{StaticResource WebContext}">
  4: 
  5: 

 

Run it and we get our great default background color!

image_thumb[104]

Now, that is nice, but it would be even better to give the user a chance to actually edit their settings.  So in About.xaml, we use a very similar model as above.

  <Grid x:Name="LayoutRoot"
        DataContext="{StaticResource WebContext}">

and

<sdk:Label Content="Background Color:" />
<TextBox Text="{Binding Path=User.BackgroundColor, Mode=TwoWay}" Height="23" />

Then wire up a save button

        private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            WebContext.Current.Authentication.SaveUser(false);
        }

 

And it works!

image_thumb[105]

And what’s better is if you run it from another browser, on another machine, once you log in you get the exact same preferences!

image_thumb[106]


Thursday, March 25, 2010

I continue to be impressed with the quality of .NET Developers in Israel.. we had a full house last night for a 2+ hour presentation on building business applications with Silverlight and RIA Services.   The audience was very engaged and had lots of good, relevant questions which created a really good conversation.    Check out the slides and demo.

I started off by demoing the Right-to-Left text support for Hebrew that is baked in as part of Silverlight 4.  

image

 

Then I started from scratch, with File\New Project and built out a simple data-oriented application.. basically I walked though most of this series

You can find the completed demo, including the files and code snippets you would need to repeat the demo yourself, which i would be high flattered if you did at your own user’s group or for your development team.  You an find the demo steps in the series

image

 

A couple of interesting links:

- We talked about the ViewModel (MvvM) support for RIA Services.  I high recommend checking out MIX10 Talk - Slides and Code and View/ViewModel Interaction - Bindings, Commands and Triggers

- We also talked about SEO – here is a good post on it: Silverlight 4 + RIA Services - Ready for Business: Search Engine Optimization (SEO)

- More details on the Silverlight out of browser work check out Tim Heuer’s video Out-of-browser Experiences

- During the break I showed a world map showing hits to my blog in real time from all over the world.  This is Stumpler.. it is a VirtualEarth, Silverlight, Azure based service from Brian Hitney.  You can add your own blog for free or just watch the hits to mine.  I expect to see Israel lighting up more often now ;-)

 

Thanks to Jackie Goldstein and Guy Burstein for organizing the event and for Jackie and Kim for the unique tour of a Kibbutz – it was great fun!


Items:   1 to 5 of 543   Next »