|
|
These blog entries are written by industry experts and leaders. We consider this content to be a good read for any software developer or web technologist.
October 2008 - Posts
-
My Toolbox column in the November 2008 issue of MSDN Magazine is avaiable online. The November issue examines:
- DayPilot - DayPilot is an AJAX-enabled calendar and scheduling ASP.NET Web control that offers functionality not unlike what you find in Outlook and other desktop-based calendar applications. Plus there's a free, open-source Lite version.
- Blogs of Note - Jeff Smith - Jeff's blog contains great posts on T-SQL syntax, queries, and tips and tricks for getting the most out of Microsoft SQL Server.
- RegexBuddy - with its terse syntax and mix of special characters, regular expressions are usually hard to read, understand, and enhance when using the naked eye. However, with a tool like RegexBuddy, regular expressions are much easier to grok. RegexBuddy is a desktop application with features that assist in building, testing, and editing regular expressions. RegexBuddy includes a regular expression debugger and wizards for turning your regular expressions into C# or VB code.
For The Bookshelf section I reviewed The Productive Programmer , by Neal Ford. An excerpt from the review follows:
In the Productive Programmer (O'Reilly, 2008), Neal Ford shares proven techniques that will help any developer improve his or her productivity. The first part of the book explores behaviors and tools for boosting developer productivity; the second part looks at software development practices that help contribute to a more streamlined development process. He espouses the Don't Repeat Yourself tenet for improving productivity and provides examples of how to avoid needless repetition in areas from version control to technical documentation. Poor software development practices can quickly swallow up those productivity gains, Neal notes. Adding unnecessary features, insufficiently testing your code, and failing to correctly encapsulate your objects are all practices that lead to bugs and unmaintainable code. The willingness to question the status quo is another important aspect in developer productivity. Too often developers get into a rut and use a particular design pattern or coding technique because that's the way it's always been done, overlooking or turning down alternatives that may be more efficient.
Enjoy! - http://msdn.microsoft.com/en-us/magazine/dd148647.aspx
As always, if you have any suggestions for products, blogs, or books to review for the Toolbox column, please send them to toolsmm@microsoft.com.
|
-
A couple of months ago my good buddy Ryan Dunn contacted me about writing some Ruby samples for the new SQL Data Services that is part of the recently announced Windows Azure. (at the time it was called SSDS). I completed the samples about a month or so ago but we had to wait to announce them until PDC. I wanted to create more than just a sample, I wanted to create something that would actually be useful.
The first step to using SDS from Ruby was to write a simple library to make working with the REST interface simpler. SDS has a very nice REST interface but its much easier to work with a Ruby library that wraps the XML format and calls. In this library I also included an ActiveResource "adapter" that makes working with SDS as easy as working with an regular active resource object. This library is hosted on github (http://github.com/sdsteam/sds-rest) and is published as a gem (gem install sds-rest).
Next I wanted to create a simple Rails application that used the sds-rest library and the activeresource "adapter", I created a simple task application that is also hosted on github: http://github.com/sdsteam/sds-tasks. This application shows how simple and easy the sds-rest library makes working with SDS from Rails.
Lastly we wanted to modify an existing application to work with SDS, this proved to be a little more challenging. I decided to try and convert Radiant CMS to work with SDS, but due to the nature of Rails and how tightly the Model are coupled to Active Record it would have been almost a compelte re-write to get it working with SDS using the ActiveResource adapter. Instead I elected to create an active record adapter that worked with SDS. The problem of course is that Active Record is designed to work with a relational database and SDS isn't one of those. While the active record adapter works for this example, I haven't published as a separate gem because it definitely isn't a fully functioning active record adapter. This version of Radiant is also hosted on github: http://github.com/sdsteam/sds-radiant.
If you are interested in Ruby and SDS please check these out and let me know what you think. Each sample includes step by step instructions on getting it setup and working (even if you haven't used Ruby or Rails before).
I plan on writing much more about the process of writing these samples, it definitely presented a number of interesting challenges.
-James 
|
-
Rick Strahl recently posted about some his frustrations with the Visual Studio 2008 Designer - HTML Mangling with Literal Controls in the <head>. While I've not had Visual Studio mangle my pages' markup when switching between the Design and Source views like Rich has, I have had one especially nagging issue since Visual Studio 2005: when I'm in the Designer and I select a control on the page very often the properties for the selected control are not loaded in the Properties window. This problem has been particularly accute in Visual Studio 2008. Does this happen to anyone else?
Here are things I resort to when this behavior starts:
- Say au revoir to the Designer and do your development from the Source view. This is fine if you are comfortable with HTML and Web control and data binding markup, but this option is less palatable if you are training or teaching a class or helping a coworker who is most familiar with the Designer.
- Try loading the properties by selecting another control on the page and then re-selecting the initial control whose properties I wanted to view. Sometimes this works.
- Right-click on the control and select Properties from the context menu. This technique worked 100% of the time in Visual Studio 2005 but rarely works for me in 2008.
- Selecting a control in the declarative markup seems to 'wake up' the Properties window. To load a control's properties, then, go to Split view, click up in the declarative markup to 'wake up' the Properties window and then select the control from the Designer.
This Designer behavior is especially frustrating when teaching a class. Each quarter I teach a class that introduces ASP.NET to students and it's a triffle embarassing to be standing at the front of the class showing them how to perform a certain task and fighting with Visual Studio's Designer to get a control's properties loaded in the Properties window.
It could be worse, I guess. I have one client who uses Visual Studio 2005 and he cannot set controls' ID properties from the Designer. If he adds a TextBox Web control to the page from the Designer its properties load in the Properties window and the ID displays as TextBox1. Now, if he goes to the Properties window and types in, FirstName, for instance, the Properties window shows FirstName but once he clicks off that control and returns to it the ID value has reverted to TextBox1. The only way he can change a control's ID property is to go to the Source view and change it from the declarative markup.
|
-
-
Time for another meeting of the new Raleigh Alt.Net Beer Users Group, or Alt.bug for short. We will be meeting tonight (10/20) at O'Malleys Tavern (Guinness and Red Oak on tap) and start around 6:00 PM and go till whenever, hope to see you there.
-James 
|
-
Today we released a beta of the new ASP.NET MVC framework. Click here to download it. You can also visit www.asp.net/mvc to explore tutorials, quickstarts, and videos to learn more. The ASP.NET MVC Beta works with both .NET 3.5 and .NET 3.5 SP1, and supports both VS 2008 and Visual Web Developer 2008 Express SP1 (which is free - and now supports class libraries and web application project types). Today's ASP.NET MVC Beta release comes with an explicit "go-live" license that allows you to deploy it in production environments. The previous preview releases also allowed go-live deployments, but did so by not denying permission to deploy as opposed to explicitly granting it (which was a common source of confusion). Today's release is clearer about this in the license. The beta release is getting close to V1 feature complete, although there are still a few more features that will be added before the final "V1" release (including several VS tooling enhancements). The team decided to call this release a "beta", though, because the quality and testing of it is higher than the previous previews (a lot of bug fixes and performance tuning work went into it), and they feel that the core features that are in it are now "baked enough" that there won't be major changes from this release to the final product. This post contains a quick summary of some of the new features and changes in this build compared to the previous "Preview 5" release: I am also planning to publish a few end to end tutorials in the weeks ahead that explain ASP.NET MVC concepts in more depth for folks who have not looked at it before, and who want a "from the beginning" set of tutorials on how to get started. New "Add View" Menu in Visual Studio With previous ASP.NET MVC preview releases you had to manually add views through the Project->Add New Item dialog in VS, and creating and wiring up everything required several manual steps (making sure the directory/file structure is right, going into the code-behind file to specify the strongly typed ViewData model type, etc). Today's beta makes the steps much easier. You can now just move your source editor cursor to be within a Controller action method in the source editor, and then right-click and select a new "Add View" context menu item (alternatively you can type the Ctrl-M Ctrl-V keyboard shortcut to invoke this without having to take your hands off the keyboard): This will bring up a new "Add View" dialog that allows you to specify the name of the view you want to create, its master page, and optionally its strongly typed ViewData "Model" type: Visual Studio will automatically pre-populate the view name based on the action method your cursor is within (you can then override this if you want). For example, if our cursor had been within an "Edit" action method when we selected "add view" it would have pre-populated the view name textbox with "Edit" instead of "Browse". The strongly typed ViewData "model" for a view can be selected from an editable ComboBox that lists all classes in (or referenced) from the MVC project: You can either select a type from the list, or manually type one in the ComboBox. You can also optionally pick an initial type from the list and then tweak it. For example, we could select the "Product" class from the list and then use the ComboBox editing support to wrap it as an IEnumerable<Product> - meaning a sequence of products: When we click the "Add" button, Visual Studio will automatically create the appropriate view directory structure, and add a strongly typed view with the right name and base class to our project. For example, if I followed the steps above it would create a new \Views\Products directory for me (since my controller class name is "ProductsController") and add the strongly-typed "Browse.aspx" view to it (which derives from ViewPage<IEnumerable<Product>> - since that was the model type we indicated in the dialog above): The newly created view will automatically be opened for us in the IDE. We can then implement our view with full intellisense (tip: make sure to do a build immediately after creating the view to ensure that intellisense shows up for your strongly typed model): And at runtime we will now have an SEO optimized product browsing page built with ASP.NET MVC: Note: The view file created by Add-View with this beta release is empty. For the final release we are hoping to add some "scaffolding" features to the Add-View dialog that will allow you to optionally specify that you want to automatically create an HTML list/details view or edit/insert form based on the strongly-typed model specified in the add-view dialog (you can then start with this initial html view and tweak it however you want). In the future we will also integrate ASP.NET Dynamic Data with MVC to support even richer scaffolding options. New \Scripts directory and jQuery Support The project template that ships with today's release now adds a new \Scripts directory underneath the project root. This is now the recommended place to store JavaScript files in your application. The ASP.NET MVC Beta now adds both ASP.NET AJAX and jQuery libraries to this folder: The jQuery files are the standard jQuery libraries, and are licensed under the MIT source license (read my previous jQuery and Microsoft post for details). With the SP1 updates of VS 2008 or Visual Web Developer 2008 Express, you will get basic JavaScript intellisense when using the above jQuery files. We will be shipping a jQuery intellisense-annotation file in a few more weeks that provides much better and more complete jQuery intellisense support (including the ability to get intellisense when using multiple chained selectors/commands). This will be included built-in with the next ASP.NET MVC update. Form Post and Model Binder Improvements One of the biggest areas of feature investment with the ASP.NET MVC "Preview 5" release was the work around form post scenarios. I did an in-depth blog post about these form post scenario features last month. Today's beta includes a number of additional tweaks, enhancements, and refinements in this area. These include: Built-in Model Binder support for Complex Types Preview 5 introduced the concept of "model binders" - which allow you to map incoming form post values to complex .NET types passed as Controller action method parameters. Model binders in preview 5 were extensible, and you could create custom binders and register them at multiple levels of the system. Preview 5 didn't ship with any "pre-built" binders, though, that you could use out of the box (you instead had to build your own). Today's beta now includes a built-in, pre-registered, binder that can be used to automatically handle standard .NET types - without requiring any additional code or registration. For example, we can now create a "Person" class like below with standard properties: And then have a Controller action method take it as an parameter argument simply by writing the code below: Because the argument parameter above is named "person", the model binder will by default look for form-post values whose key names are in the format "person.Name", "person.Age", "person.Email". It will then use these values to create and populate a new "Person" object that is passed into our action method. Developers can optionally override the default name mapping logic using a new [Bind] attribute introduced with today's beta - and by setting its "Prefix" property. For example, if we set the prefix property to "PersonToSave", the binder would instead look for the following form values: "PersonToSave.Name", "PersonToSave.Age", and "PersonToSave.Email" when creating the person instance. You can set the prefix to an empty string to have the binder map "Name", "Age" and "Email" with no prefix: The [Bind] attribute allows you to optionally specify an "Included" or "Excluded" property - which can be used to either "whitelist" or "blacklist" properties from being mapped on the objects. For example, the code below indicates that we want to map only the "Name" and "Age" properties on our person object: Important safety tip: In general you want to be very careful to make sure you don't allow properties to be mapped that you don't want mapped. Always use include/exclude anytime you have properties that you don't want to be mapped on an object. For example: assuming there was a "Salary" property on our Person object - we would not want to map it unless we explicitly wanted an end-user to be able to set it. You want to be explicit about not mapping unwanted properties like this to prevent a hacker from trying to fake out a form request and attempting to submit additional property information not editable in the UI. Refactored Model Binder Infrastructure The model binder system has been refactored significantly for the beta. You can now re-use and plug-in functionality in a much more granular fashion when building your own custom model binders. Model binders are also now used by the UpdateModel and TryUpdateModel methods - allowing you to write one binder and re-use it everywhere any form value is handled inside ASP.NET MVC. Improved UpdateModel and TryUpdateModel methods The UpdateModel and TryUpdateModel methods now support several new options and overloads (including richer whitelist and blacklist options). It also now optionally supports the ability to just call "UpdateModel" to populate an instance with the default binding rules (with preview 5 you always had to supply a whitelist - and several people asked for an option to just map all): Another new feature in today's beta is the ability to define a strongly-typed whitelist filter that you use with UpdateModel/TryUpdateModel. You can do this by defining an interface with the subset of bindable properties that you want to map. For example, below I'm defining a "IPersonFormBindable" interface that only has three properties (and does not have the salary property): We could then indicate that we want to use this contract to limit which properties are mapped using code like below: This will ensure that only those properties defined on the IPersonFormBindable interface are mapped - and that the Salary one is not mapped. Improved Unit Testing of UpdateModel and TryUpdateModel Scenarios With Preview 5 you had to use mocking in order to unit test form post scenarios that used the UpdateModel or TryUpdateModel methods. Today's beta now allows you to unit test all form post scenarios without ever requiring mocking (which enables better friction-free unit testing). There is a new IValueProvider interface introduced with today's beta that the model binding infrastructure uses to retrieve values to bind (as opposed to always going against the request object). The FormCollection class (which is built-into the beta) implements this interface - and you can now explicitly pass an instance of this to UpdateModel/TryUpdateModel to bind its values from. For example: below in the "Save" action method we are binding all incoming form values to a FormCollection (which will be passed in as an argument to the action method). I can then pass this form collection to the UpdateModel call and have it map the values onto the person model object using this parameter: We could then unit test a successful form post scenario for the above action method using the code below (notice how we don't need to mock anything - instead we can just create a formcollection, populate it, and pass it as a parameter): We could then unit test an unsuccessful form post (which fails because of invalid input for the age value) using the code below. Notice how we are verifying that the edit form is redisplayed (so that users can correct their problem) in a form-post failure scenario: We did not have to mock anything to unit test both of the above form submission scenarios. Strongly Typed [AcceptVerbs] attribute ASP.NET MVC Preview 5 introduced a new [AcceptVerbs] attribute that you could use to indicate which HTTP verbs an action method supported. In preview 5 you always specified verbs using strings. We still support this with the beta, but have also added support for common verbs to be specified using a strongly-typed enum mask. For example: Today's beta release also no longer requires that you specify [AcceptVerbs] on both actions in scenarios like above. By default ASP.NET MVC now looks for an action method that explicitly supports the incoming http verb - and if one is not found will use the action method that doesn't have an explicit verb specified. This saves some typing for common GET/POST scenarios (you no longer need to decorate the GET method). Validation Error Messages One of the features that unfortunately did not make it into the beta (but which we will add for the next update) is support so that you can expose custom error validation messages from your model classes (as opposed to customizing them in the Controller like you can do today). We are currently investigating a few ways to enable this - including adding support for the IDataErrorInfo interface, as well as support for the new Dynamic Data attributes in the System.ComponentModel.DataAnnotations namespace. One improvement that did make it into today's beta, though, is that the default validation error messages are now more end-user friendly (which hopefully eliminates the need to define custom validation messages in a lot of cases): HTML Helper Cleanup Today's beta has some miscellaneous cleanup improvements to the HTML helpers (in general this is a tricky area - since there are so many overload combinations to get right). Html.Form -> Html.BeginForm One of the usability changes made with today's beta was to rename Html.Form() to Html.BeginForm() and to support two modes of using it - one leveraging a using statement, and the other leveraging an explicit Html.EndForm() helper method. The reason we've moved to support both of these approaches is that we've seen a lot of questions/confusion in the forums around how the using statement works for this scenario (the pattern is unfamiliar to a lot of developers). Below are two examples that demonstrate how we can implement the above create screen scenario (complete with validation error message UI) using the two different form approaches: Approach 1: Using Statement with Html.BeginForm(): The below approach uses the IDisposable pattern with the using keyword in VB and C# to auto-terminate the </form>: Approach 2: Explicit Html.BeginForm() and Html.EndForm(): The below approach uses an explicit EndForm() call to close the </form>: Developers can use whichever they feel most comfortable with - both approaches logically do the exact same thing. Many HTML Helper Methods Moved to be Extension Methods One change we made with today's beta was to move many of the Html helper methods to be extension methods that live under the System.Web.Mvc.Html namespace (previously they were just instance methods on the HtmlHelper class). We did a similar thing with the AJAX helper methods in "Preview 5" (they now live in the System.Web.Mvc.Ajax namespace). These changes don't impact intellisense in the view markup (we by default automatically reference the namespace in the web.config file so it works just like before - although if you are migrating an app from preview 5 you'll need to add the namespace yourself to web.config, read the release notes for steps on how to-do this). If you have standalone classes/tests that use the helper methods make sure to add the appropriate "using" statement to import them. The reason we moved the helper methods to be extension methods instead of instance methods was to provide developers with more flexibility to add/remove/replace our built-in implementations (as well as to give ourselves more flexibility in the future). If you want to override the HTML rendering of a method you can now easily do so - and still keep the same method code/signature in your markup. Silverlight / ASP.NET MVC Project Integration When you create a new Silverlight 2 project within Visual Studio or Visual Web Developer 2008 Express (using the recently released Silverlight 2 and VS 2008 Tools for Silverlight download), you now have the ability to select a ASP.NET Web Site, ASP.NET Web Application Project and now an ASP.NET MVC Project to host it within: When you choose this option, Visual Studio will automatically copy and deploy/update the Silverlight application into the ASP.NET MVC application when you make a change and do a build within the IDE. This makes it easier to start integrating a .NET based Silverlight front-end (running inside the browser) with an ASP.NET MVC web backend - and opens up some interesting new possibilities. ASP.NET MVC Futures Assembly For the last several preview releases, ASP.NET MVC features have been split across two assemblies - System.Web.Mvc.dll and Microsoft.Web.Mvc.dll. The later assembly + namespace contains "futures" features that hadn't yet been committed to ship in the core V1 product. As features become "committed" we move them from the futures assembly into the core assembly - and also change the namespace (from Microsoft.Web.Mvc to System.Web.Mvc). The previous preview releases automatically shipped and added the "futures" assembly when you did a File->New ASP.NET MVC project. Starting with today's beta we are no longer automatically adding this assembly - instead you need to explicitly add it from your project if you want to use it. The reason for this is so that developers can clearly distinguish those features that will be in the fully supported V1 product (which implies product support and a higher commitment around backwards compatibility), and those that might still evolve in the future (and not be added to the supported product until vnext). Important: the futures assembly (along with all the source code in it) will continue to ship and will work with ASP.NET MVC V1. So if there is a feature in it you really like, you do not have to worry about it disappearing on you (it is still there and you can still use it). You just now need to explicitly reference the assembly and use it in your project. We plan to ship a version of the ASP.NET MVC Futures assembly that works with the Beta later today. You will be able to download it here. \Bin and GAC Deployment The ASP.NET MVC beta now supports both GAC based deployment (where you install the assembly once for the machine) as well as local \bin based deployment (where you store a copy of the assembly in the application directory). We will use the GAC to enable automatic-servicing updates via Windows Update (where an administrator can automatically patch a machine - like they do with the rest of the .NET Framework today, and not have to update each individual application). One downside with GAC based deployment, though, is that it can make deploying applications that require a GAC component harder for hosted scenarios - since you typically do not have admin access on the server machine (and you need admin rights to install components in the GAC). To make sure hosted scenarios work well (and to ensure that you don't need your hoster to install anything other that ASP.NET 3.5 in order for ASP.NET MVC to work), we will also support the ability to deploy the ASP.NET MVC framework assemblies in the \bin directory of your application. This will allow you to just xcopy/ftp the application onto the server and have it work (no admin access or setup needs to be run on it). The one caveat with this is that you'll be responsible for updating the assembly anytime a servicing update comes out - Windows Update can't automatically find all the application directories on a machine to-do this for you. Summary Today's beta release is a step closer to the final ASP.NET MVC 1.0 product. While not 100% feature complete, we think the major subsystems are all getting really close to being done, and that the quality level is now pretty good. I am going to try and post some more end-to-end tutorials in the coming weeks that show off how to use ASP.NET MVC from the beginning, and then logically progress to richer and richer scenarios. Included in the list of tutorials will be my infamous AJAX with MVC post that I keep promising to write - but so far haven't (my excuse: the Silverlight 2, ASP.NET MVC, .NET 4.0, VS10, and Windows 7 ship cycles are all happening in parallel on my team - and I've unfortunately been really busy which is the reason for the delay). As I always like to make sure I point out: If you don't like the MVC model or don't find it natural to your style of development, you definitely don't have to use it. It is a totally optional offering - and does not replace the existing WebForms model. Both WebForms and MVC will be fully supported and enhanced going forward (ASP.NET WebForms in .NET 4.0 will add richer URL routing features, better HTML css markup support, complete control over the ClientId property, more AJAX features, and more that I'll be blogging about soon). So if you don't like the MVC option, don't worry, and don't feel like you should or need to use it (you don't). Hope this helps, Scott 
|
-
Today we shipped the final release of Silverlight 2. You can download Silverlight 2, as well the Visual Studio 2008 and Expression Blend 2 tool support to target it, here. Cross Platform / Cross Browser .NET Development Silverlight 2 is a cross-platform browser plugin that enables rich media experiences and .NET RIAs (Rich Internet Applications) within the browser. Silverlight 2 is small in size (4.6MB) and takes only 4-10 seconds to install on a machine that doesn't already have it. It does not require the .NET Framework to be installed on a computer to run - the Silverlight setup download includes everything necessary to play video or run applications. Developers can write Silverlight applications using any .NET language (including VB, C#, JavaScript, IronPython and IronRuby). Silverlight provides a rich set of features for development including: - WPF UI Framework: Silverlight 2 includes a rich UI framework that makes building rich Web applications much easier. In includes a powerful graphics and animation engine, as well as rich support for higher-level UI capabilities like controls, layout management, data-binding, styles, and template skinning. The WPF UI Framework in Silverlight is a compatible subset of the WPF UI Framework features in the full .NET Framework, and enables developers to re-use skills, controls, code and content to build both rich cross browser web applications, as well as rich desktop Windows applications.
- Rich Controls: Silverlight 2 includes a rich set of built-in controls that developers and designers can use to quickly build applications. The Silverlight 2 release includes core form controls (TextBox, CheckBox, RadioButton, ComboBox, etc), built-in layout management panels (StackPanel, Grid, Panel, etc), common functionality controls (Slider, ScrollViewer, Calendar, DatePicker, etc), and data manipulation controls (DataGrid, ListBox, etc). All Silverlight controls support a rich control templating model, which enables developers and designers to collaborate together to build highly polished solutions.
-
Rich Networking Support: Silverlight 2 includes rich networking support. It includes out of the box support for calling REST, WS*/SOAP, POX, RSS, and standard HTTP services. It supports cross domain network access (enabling Silverlight clients to directly access resources and data from resources on the web). It also includes built-in sockets networking support. - Rich Base Class Library: Silverlight 2 includes a rich .NET base class library of functionality (collections, IO, generics, threading, globalization, XML, local storage, etc). It includes rich APIs that enable HTML DOM/JavaScript integration with .NET code. It includes LINQ and LINQ to XML library support (enabling easy transformation and querying of data), as well as local data caching and storage support. The .NET APIs in Silverlight are a compatible subset of the full .NET Framework.
- Rich Media Support: Silverlight 2 includes built-in video codecs for playing high definition video, as well as for streaming it over the web (including both live and on-demand support). Silverlight includes support for adaptively switching video bitrates on the fly based on network conditions (enabling users to avoid seeing the dreaded "buffering..." message), placing and metering ads within video streams, as well as enabling content protection.
The final Silverlight 2 release delivers a tremendous amount of power and flexibility that enables you to really push the boundaries of what can be done in a browser, and enable great end user experiences. Silverlight Customers Over the last few months a number of very high profile sites have successfully launched using the beta releases of Silverlight 2. In August, NBC hosted the Olympics live on nbcolympics.com and served up 1.3 billion page views, 70 million video streams, and 600 million minutes of video content - making it the largest ever media event on the web. Users visiting the site spent an average of 27 minutes on the site when they watched a video - an unprecedented number for online traffic. In August, the Democratic National Convention was streamed live using Silverlight, and broadcast a 2Mbit live video feed of the event and speeches - receiving outstanding feedback from audiences watching it. This month a number of other high profile sites are going live with the final release of Silverlight 2. CBS College Sports Network will be streaming 20,000 hours of live games for 150+ college and university partners. AOL is launching their new AOL Mail browser version to 60 million users using Silverlight 2. Blockbuster will be launching their new MovieLink subscription service using Silverlight. Yahoo! Japan is live today enabling live streaming of Major League Baseball games. Hard Rock International will be updating their memorabilia site with new features. And companies like Toyota, HSN and hundreds of others will be live this week as well. Silverlight Control Pack Silverlight 2 ships with dozens of built-in UI controls that can be used to build applications. Below is a screen-shot of the Silverlight DataGrid, RadioButton, CheckBox and DatePicker controls in the final release: Today we are also announcing the "Silverlight Control Pack" - which will deliver dozens of more controls that you can use with Silverlight 2. We will continually add new controls to the control pack over the next few months (we expect to ultimately have more than 100 controls total). The first release of the control pack will include controls like TreeView, DockPanel, WrapPanel, ViewBox, Expander, NumericUpDown, AutoComplete and more. All controls will ship with full source, and with a OSI license that allows you to modify and use the source for any purpose. Interoperability Today we are also announcing that Microsoft is partnering with Soyatec to sponsor additional tools for developing Silverlight applications using the cross platform Eclipse development platform. Click here to learn more about this and download the free Silverlight Eclipse plugin. Click here for a step-by-step tutorial that walks-through how to use their Eclipse tools today to build a Silverlight 2 application. We are also announcing today that we are releasing the Silverlight XAML vocabulary and schema under the Open Specification Promise (OSP), which enables anyone to create products that read and write XAML for Silverlight. Learning Silverlight 2 The best way to learn Silverlight 2 is to visit the www.silverlight.net web-site. You can find free online tutorials, videos and training available there. The site also hosts an online forum system where MVPs and Microsoft Silverlight team members will be able to help answer technical questions. Also make sure to subscribe to the Silverlight Community RSS Feed, Jesse Liberty's Blog, and Tim Heuer's Blog for a daily dose of great Silverlight content. I've recently updated my Digg-client tutorial for the final Silverlight 2 release. This provides an end to end walkthrough of a Silverlight 2 application, and helps explain the different programming concepts behind it (controls, layout management, networking, data-binding, styles, user controls, control templates, etc). If you are brand new to Silverlight or WPF development I recommend walking through it to understand the basics: You can develop Silverlight 2 applications using any version of Visual Studio 2008. Simply install the Silverlight Tools for Visual Studio 2008 download to get Silverlight tooling support within it. If you do not have VS 2008, you can alternatively install the free Visual Web Developer 2008 Express SP1 Edition. This free tool provides great ASP.NET development tool support, and starting today also now supports Silverlight 2 development. You can follow all of the steps in my tutorial above using the Visual Web Developer 2008 Express Edition - and get full intellisense, debugging, and deployment support. Upgrading from the Beta If you have the Beta2 or RC versions of the VS Tools for Silverlight, or the Silverlight 2 Beta SDK or Developer Editions of Silverlight 2, please make sure to uninstall these completely before downloading and installing today's release. End users who have Silverlight 1, or Silverlight 2 Beta1 or Beta2 will be automatically upgraded to the final Silverlight 2 release starting later this month. Until then, if they visit a Silverlight 2 (final release) site, they will see the standard install prompt that a machine that does not have Silverlight installed would see. Clicking it will upgrade their machines to the final release of Silverlight 2 (there is no need for them to uninstall anything - Silverlight 2 will cleanly install over Silverlight 1 or the previous betas). Because there are some breaking changes between Silverlight 2 Beta2 and the final Silverlight 2 release, end users who have the final Silverlight 2 release installed will not be able to run applications that are still targeting Silverlight Beta2. Most major Silverlight 2 sites plan to upgrade to the final release in the next 24 hours (which will fix this issue) - if you hit a site built with Beta2 before then you might experience trouble with it. That should go away within about a day once all sites are updated though (this was one reason why we released the public release candidate last month - to help developers get their sites ready for the final release). Summary Silverlight 2 is a major release that enables some great new application and media experiences to be built, and allows developers to use .NET within any browser to create them. Thank you for all your support and feedback the last year as we've worked on it. All of us on the Silverlight team are really excited to see what you build with it. :-) Scott 
|
-
Between work and diaper changes I've been reading Michael Coles's book Pro T-SQL 2008 Programmer's Guide, and found this little gem (pg. 527-528):
The OUTPUT Clause You can use the OUTPUT clause with the the INSERT, UPDATE, DELETE and MERGE DML statements. ... The OUTPUT clause returns information about the rows affected by the DML statements that can be useful in comparing preupdate and postupdate data, or for troubleshooting and logging purposes. ... You can use the OUTPUT clause to output a SQL result set like that returned by a SELECT statement, or you can combine OUTPUT with the INTO clause to output rows to a table or a table variable.
This feature is supported in T-SQL 2008, but was initially added to Microsoft SQL Server 2005. And here it is three years later and I'm just learning about it!
One use of the OUTPUT clause is to grab the just-inserted IDENTITY column value:
INSERT INTO TableName(ColumnList) OUTPUT inserted.IdentityColumnName VALUES(Values)
The above will return the just-inserted IDENTITY value as a result set, just as if you had followed an OUTPUT-less INSERT statement with the statement:
SELECT SCOPE_IDENTITY()
You could use the OUTPUT statement to return information about the rows affected by an UPDATE. For example, in these tough economic times you might need to increase prices by 20% for all products that cost less than $10.00. The following statement performs the described update and returns those products whose prices were increased, showing both their old price and their new price:
UPDATE Products SET Price = Price * 1.20 OUTPUT inserted.ProductID, deleted.Price AS OldPrice, inserted.Price AS NewPrice WHERE Price < 10.00
This UPDATE statement will modify the data and return a three-column result set with a row for each modified product along with its preupdate price (deleted.Price) and its post-update price (inserted.Price).
Pretty neat, eh?
In fact, You can string these DML statements together, so you do an UPDATE with an OUTPUT whose results are then automatically INSERTed into another table (such as an audit table). The OUTPUT statement feels like in-place triggers (kind of like how Common Table Expressions are akin to in-place views).
I'll have to write an article on the OUTPUT statement on 4Guys one of these days...
Further Reading....
|
-
-
A decision all independent software developers must make early on in their career is when to bill a client and under what terms. This decision, of course, is not the developer's alone to make - it must be discussed and agreed upon by the client, as well. Similarly, a developer must decide how to charge: by hour or by project. Over the years I have received numerous e-mails from fellow developers who are contemplating striking it out on their own, and wonder what suggestions or advice I have for billing.
My general policy is as follows:
Software Development: For software development I charge per hour. I have never taken on a client and billed per project, and likely never will. My primary concern with billing per project is that my estimation or the client's estimation may be off base, which hurts one of us. Also, when billing by the hour there is no concern about scope creep or other things tacked on by the client late in the game in an attempt to get more bang for his buck. Billing per hour is ideal for the software developer, but customers often prefer a fixed price for the project because it puts a cap on the amount it will cost. A new customer does not know what kind of work they can expect from a developer per unit time. To ameliorate this concern, I usually propose a very simple, short feature or milestone for new clients, so that they can get a good gauge of how long it takes me to complete a task, and what level of quality they can expect. I have also given price caps for customers on tight budgets, but this is more the exception than the rule.
Another reason that I propose a very short and simple first project for new clients is because I require payment in full and up-front for new customers. This sours some customers and I've certainly lost some business because of this policy. The way I see it, this requirement serves as a vetting process. It shakes out customers who may have shaky cash flow or who are going to later nickel and dime me for the work performed or, worst yet, not pay at all. Once I've had some time to work with a client and have established a good working relationship, I will relax these conditions and bill on a monthly basis (or more often, if requested). If I have not yet established a relationship and do not fully trust the client, I continue requiring payment up front and in full. When I finally end up billing on a monthly basis, my terms are Net 15 (that is, I require payment within 15 days of invoice), but I have some customers who much prefer Net 30 and once that relationship and trust is established I'm willing to agree to those terms.
I find this process of establishing trust by requiring payment up front at first, and then billing monthly with Net 15 terms to be a surefire approach to ending up with solid clients. To ensure prompt payment, some independent software developers use tactics like hosting the application on their server and not sending the code to the client until payment is received in full. Another, more questionable approach, is to put a backdoor into the application so that if the client does not pay the software developer can "break into" the application and "turn it off" until payment is received. I dislike both of these techniques as it frames the working relationship in adversarial terms.
I have waived or relaxed these requirements - payment up front for new clients, Net 15 terms, etc. - for very large or very established customers, such as regional businesses with thousands of employees, or Fortune 500 companies. These types of clients are more the exception than the rule, though, as the vast majority of my clientele are small businesses. And some companies or industries have Net 60 terms and won't make any exceptions.
Training Like with software development, I require payment up front or on delivery of services for new clients. I will make exceptions for very large and established clients, but only sparingly. My hesitancy here in due in part to a negative experience with a local training company that was very late with payment. I ended up taking the client to small claims court, but was paid in between the time they were served and when the court date was set. (My decision to go to small claims court and the resulting process is summarized in My Small Claims Court Experience.)
While I always charge by the hour for software development, I charged for training services using a variety of models. For personal training I usually charge hourly, as it makes the most sense. In this way the customer has direct control over the costs and knows the precise charge for another hour or day's worth of training. For classroom events I usually charge a per-day rate, which depends on a number of factors, including:
- Class size
- Number of days of instruction
- The location relative to my home - is the classroom setting five miles away, or across the country?
- The material used and the topics covered - am I given the course-wear to teach or do I need to create it?
When a potential customer asks for a training quote, I use the above criteria to judge how long it will take me to create the course-wear (if needed) and to prepare for the class, how much travel time there will be (if any) and the total hours of instruction. I then multiple that number by my usual hourly rate for software development, then multiply that by a number between 1.0 and 2.0. This coefficient depends on the size of the class (the more students, the higher the number) and based on how excited I am to teach the class. If I'm teaching a two-day class to 5 smart devs who work in a fun company that's headquartered on the beach, and we're having a luau at the end of the second day, then that number will be a lot closer to 1.0 than if it's a class of 25 devs at a stuffy corporate office and I have to wear a suit each day. The figure derived from that equation, plus any travel and entertainment costs, are what I quote the client.
Writing Unlike training and software development, it's hard to get a client to pay you by the hour for an article, tutorial, or book. Also, in my experience, it's rare to be paid by the word. Usually publishers have a pre-determined rate they pay for a written piece with a minimum word count. For print media - books and magazines - there is also a maximum word count. The pre-determined rate for magazines and websites is usually a dollar amount; for books it's a royalty rate and advance. (For a breakdown of compensation on writing a book, see The Economics of Writing a Computer Trade Book.)
Also unlike training and software development, it's virtually impossible to get a client to pay you anything up front. Book publishers offer advances, sure, but they don't start rolling in until you have completed a significant portion of the work. (This is true for computer trade authors; I'm sure Stephen King gets his advance whenever he wants.) As a result, as a write you have to be willing to get paid after the article or tutorial or book is written and published. As a result, I take a bit of a gamble if I write for a small publisher, small magazine, or small website. Having been bitten in the past, these days I rarely write for small operations unless I know the people running them and trust that I'll be compensated. But if a small publisher contacts me out of the blue and wants me to write five chapters for a book, I'll pass.
In Summary... What's infinitely more important than the decision you make as when to you bill your clients and what terms to use, is to have very frank and clear communication before any work begins. It is imperative that you discuss with your client when you will bill and when you expect payment. They may agree, or they may want to change the terms. But what's vital is that there is a clear understanding. I've talked with many independent software developers who were too uncomfortable bringing the subject up or just assumed that the client understood and agreed with implicit payment terms, and as a result there was no communication prior to the work. This can lead to an unhappy client if his expectations of the payment terms were different than yours.
Also, if you have sent an invoice to a client and he has not paid by the time the invoice is due, do not hesitate to contact the client and politely inquire about payment. And, lastly, if a client becomes severely overdue, do not hesitate to stop working for him. You are not obligated to work for free.
|
-
-
Someone asked me why LINQ operators return an IEnumerable<T> instead of something more useful, like a List<T>. In other words, in the following code: List<Book> books = new List<Book>();
// ...
IEnumerable<Book> filteredBooks =
books.Where(book => book.Title.StartsWith("R"));
... we started with a List<Book>, so why isn’t the Where operator smart enough to return a new List<Book>, or modify the existing list by removing books that don’t match the Where condition?
Let’s talk about modifying the original list.
I hope you’ll agree that it would be odd for a query to modify a data source. Imagine sending a SELECT statement to a database and finding out later your SELECT removed all but one record from a table. Although the Where operator is just a method call that could change the underlying list of books, it’s better to return something new and leave the original list intact. You won’t find any LINQ operators that modify input , and this behavior produces many benefits. One obvious benefit is that you can think of the above code as a query, and it won’t surprise you by removing books from your original list.
What about creating a new List<T>?
It turns out that creating a new list can be quite expensive, but only because we often don’t need a List<T> returned. Think about the number of lists created in the following query (if each operator created a new list). var filteredBooks =
books.Where(book => book.Title.StartsWith("R"))
.OrderBy(book => book.Published.Year)
.Select(book => book.Title);
Here we would have three lists created (one each by the Where, OrderBy, and Select operators). We’d only needed a single list of titles as the result, but since the operators cannot modify their underlying data source (for the reasons outlined above), they would be forced to each create a new list, and most of that work would be wasted as two of the lists are immediately discarded.
Imagine if you only needed to count the number of books whose title starts with the letter R – in that case you wouldn’t want any of these lists being created and destroyed when you computed the result. It would all be wasted work.
Laziness Isn’t Always Bad
One of the principles of LINQ is to be lazy. A LINQ query won’t do any work unless you force the query to do the work. Even when a query does perform work – it does the least amount of work possible. If you wanted a List<Book> as a result, you’d have to force LINQ to create the list: List<Book> filteredBooks =
books.Where(book => book.Title.StartsWith("R"))
.ToList();
Instead of lists, LINQ works with a beautifully pure abstraction called IEnumerable<T>. It’s defined like so: public interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
The only thing you can do with an IEnumerable<T> is ask for an enumerator. An enumerator is something that knows how to visit each item in a collection. Some languages call these enumerator things “iterators”, because they iterate over a collection of objects, returning each object and moving to the next.
The in-memory LINQ operators, like Where, OrderBy, and Select, all work on inputs that implement IEnumerable<T>. That means the operators work on anything that can be enumerated over in a one-by-one fashion. The beauty is that there are so many data sources that these operators can work on, because IEnumerable<T> has such simple demands. Arrays are enumerable, lists are enumerable, dictionaries, trees, stacks, queues, files in a directory, elements in an XML document - all enumerable. Even a simple string is enumerable, since it is composed from a sequence of individual characters.
These same operators return IEnumerable<T>, because it’s the lowest common denominator for everything you’d ever need from a query. Plus, it’s lazy. You want to count the results? The Count operator will get the enumerator and move through the results, one by one, to sum the total number of items. You want to make a concrete list from the results? The ToList operator will get the enumerator and move through the results, one by one, adding each item to a new list it creates. Do you want just the first item in the results? Then the enumerator does just a little bit of work to find that first item. In most cases it does not need to iterate the entire collection to find the first item. Enumerators are lazy, too.
The important point is that the enumerator itself doesn’t perform any useful work. It’s you, or the other LINQ operators, that use the enumerator to iterate through the result and produce something meaningful. In the odd case that you never need to look at the result - no enumeration work is performed at all. No lists area created. Pure laziness!
Summary
The beauty of IEnumerable<T> is that it only says “you can get something to enumerate this”. To return something that offers the possibility of enumeration is very little work. And no work is needed unless you actually count the results, create a list from the results, or bind the results to a control for display.
The interface IEnumerable<T> is so wonderfully lazy it inspired me to write a short, short story. If you came to read about LINQ, skip the story as the words are entirely uninteresting and mostly devoid of meaning.
The Lazy Leopard and the List
The scientist approached the big cat with a notepad and a pencil in her hands. She was worried, of course. The cat was a predator, and likely to be hungry at this hour of the day. “I need to know”, she asked the cat, “do you keep a list of things to do each day?”
The cat stirred. He was a snow leopard with dark rosettes blotted onto his thick, cream colored fur. The big cat’s eyes were only half open, but he turned and focused them on her.
“I don’t keep a list, dear lady”, he said, followed by a rumbling yawn. “I keep an enumeration”.
“An enumeration?”, she asked.
“Yes, an enumeration”, he replied. “Lists are like the gold bracelet on your wrist, dear lady. Very tangible – very concrete things, lists are. Keeping a list of everything I might want to do is a burden and chore. I’d need to carry your paper, and your pencil”, he said, with his eyes focusing on her hands.
The scientist’s pencil raced across her notebook as she transcribed every word the leopard spoke. She glanced at him as he began to stare, and instinctively pulled herself a little further away.
The leopard continued. “With a list I’d have to add things, and remove things, and constantly reorder the things I want to do. Too much work”, he said, shaking his head. “Do you know what I can do with an enumeration?”, he asked.
She paused at the leopard’s question, and pushed her hair back - she wore glasses when she worked. After some thought, she asked, “Enumerate it?”
“Yes, dear lady”, said the leopard. “I can enumerate it. I enumerate the possibilities one by one, and find the perfect fit for this moment in my life. If I’m thirsty, I’ll find water. If I’m sleepy, I’ll find a place to sleep.” He tilted his head slightly to the right. “If I’m hungry, I’ll find food”, he said.
She finished writing the leopard’s last words and glanced up. Was that a tooth showing? Was he hungry now?
The cat started speaking again.
“One of the wonderful things about enumerations is they theoretically last forever. Lists have a beginning and an end – an Omega for every Alpha. With enumerations, you can keep asking for the next thing, over and over and over again. I ask for them when I’m ready to do something. If I’m tired of doing, they’ll still be there tomorrow. You might say it’s unpredictable behavior, I say I’m just being lazy. Either way, I can’t help it, it’s in my genes”. His soft voice trailed off with a tired tone.
“You intended to live forever?”, she asked. The leopard snarled. Or smiled. She couldn’t quite tell.
“No, dear lady”, he said. “I said the enumeration theoretically lasts forever. One day I’m sure my enumeration will run out of things to give me, or maybe I’ll just be too tired to ask for the next thing, so I’ll sleep forever. I don’t know how it ends. Maybe I should ask you.”
She looked at him again. She felt uneasy now, being here with a leopard. He seemed nice enough, as leopards go, and he certainly gave her interesting topics for research, but he was still a leopard. A carnivore. He was not a beast to be trifled with. She could never let her guard down again.
“I don’t know how it ends either”, she said, and closed her notepad. She tucked her pencil behind her ear, backed away from the cage, and left the leopard alone with his enumeration. 
|
|
|
|