October 2007 - Posts

Persistence, Persistence, Persistence
27 October 07 08:26 AM | Scott Mitchell

'Genius is 1% inspiration and 99% perspiration.' -- Thomas Edison

In his most recent blog entry, Jeff Atwood shares his secret on How to Achieve Ultimate Blog Success In One Easy Step: set a goal to write x blog entries per week, and then do it. It doesn't, Jeff claims, matter whether you have any writing talent, whether you have any audience, or whether you have anything interesting to say - just start blogging and keep blogging regularly, and good things will come.

Jeff's advice is a bit trite and does come off as sounding a little like one of those motivational speakers that gives talks to high school students in a Thursday afternoon assembly. The problem is that Jeff makes it sound like persistence is all you need in order to succeed at blogging, but that's not true. In mathematical terms, persistence is a necessary, but not sufficient condition. Taking things to a logical extreme, if persistence trumped quality and content, then surely someone would have created a computer program by now to generate ham fisted essays and would have this generator pumping out a new entry a day for thousands of blogs, and each blog would have a loyal readership in the thousands or tens of thousands, and this clever soul would be richer than Google.

I don't mean to discount the importance of persistence. Persistence will make you better at what you do and will help you stand out from the crowd, but persistence alone is not enough to achieve 'ultimate success' in any field.

But who needs to be an 'ultimate success' anyway? I think most people are content to be a 'success,' and persistence and practice will dramatically increase your chances for success in any given task. You may not be the smartest programmer in your workplace, but I am positive that if you read a new book each month relating to the technology you use, if you put in one extra hour a day to review other programmers' code, if you just make a repeated and consistent effort to be a better programmer, then you will become a better programmer and your improvements will quickly become noticed by others. You may never be the best programmer in your workplace (although you might), but persistence and hard work will unquestionably improve your skills and value to the company.

The main reason why persistence is such a hallmark of success is because very few people have the motivation or drive to make a schedule and stick with it. The very act of sustained effort already puts you ahead of 90% of the crowd.

Finding the motivation to stick with a schedule can, of course, be hard (otherwise everyone would demonstrate a level of sticktoitiveness. The easiest way to keep at a particular task is to, obviously, choose a task that you thoroughly enjoy. So if you are considering taking on a new job or avocation, make sure you choose something that you love to do! I can't stress this enough. Too many people choose a career path based on what other people want them to do, or based on how much money they think they can earn, but you will ultimately have a higher quality of life if you instead find a job in a field you love. You will do better at your job, your days will be more interesting and rewarding, and you'll likely make more money in the long run than working in a job you dislike.

This 'do what you love' concept also applies to hobbies. If you are going to start blogging and want to become a blog superstar like Jeff, first of all make sure that you like writing, and second, pick a topic that wholely interests you.

Another tip: remove distractions. With so many entertainment options it's easy to procrastinate, to find an excuse, to move on to something else, to Alt+Tab off to something more interesting. By removing distractions you lessen this likelihood. For me, one distraction I've kept out of my life since 2001 is a rich TV experience. Yes, we have a TV, but it's an old 19 inch cube with an antennae that can pick up about seven fuzzy English-speaking channels. I've often contemplated getting cable or a satellite, and once had gone so far as to have a technician come out and do an initial visit for DirecTV, but in the end I have stuck with our current television situation because I know upgrading would just introduce one more distraction into my life.

Of course, there are times when we must work hard on an activity that is not enjoyable (for, hopefully, a short time). In that case, start by identifying the end goal, the reason for the struggle. Next, make a written schedule outlining what days and times the undesirable task will be performed. Then stick with it. Each day remind yourself of the end goal, and take note of your progress. Know that tomorrow is one day closer to that goal.

Let me close with two more quotes by Thomas Edison, who really had some great insight into hard work and persistence:

'Opportunity is missed by most people because it is dressed in overalls and looks like work.'

'I never did a day's work in my life. It was all fun.'

Filed under:
November's Toolbox Column Online
24 October 07 04:26 PM | Scott Mitchell

My Toolbox column in the November 2007 issue of MSDN Magazine is avaiable online. The November issue examines three products:

This month's issue reviewed Matt Gibbs and Dan Wahlin's Professional ASP.NET 2.0 AJAX. Here is an excerpt from the review:

Most AJAX-related books offer a rather exhaustive low-level look at the technologies involved. But that level of detail is unnecessary for a developer who wants to quickly get started building AJAX-enabled ASP.NET apps. These developers will find Matt Gibbs and Dan Wahlin's Professional ASP.NET 2.0 AJAX (Wrox Press, 2007) to be just what the doctor ordered. The book focuses on core AJAX concepts such as asynchronous postbacks, the browser's Document Object Model, and making HTTP requests via script—and each is explained in terms familiar to ASP.NET developers. Working with the Microsoft ASP.NET AJAX library is also explored, as is using the UpdatePanel control, the ASP.NET client library, ScriptManager, and the controls in the AJAX Toolkit.

As always, if you have any suggestions for products or books to review for the Toolbox column, please send them into toolsmm@microsoft.com.

Filed under:
Returning the Just-Inserted ID Value Using Typed DataSets
23 October 07 01:45 PM | Scott Mitchell

Probably the most frequent question I field from readers of my Working with Data in ASP.NET 2.0 tutorial series is, How do get the just-inserted ID value from the DAL? This is an important area, and one that I should have authored a tutorial on. There are many situations in which the just-inserted ID value is needed. For example, after a user adds a new record to the database you might want to automatically redirect them to the details page for that new record, something like, ~/Details.aspx?ID=X. In this case you need to know the just-inserted ID because that value is used in the querystring.

I did briefly discuss one technique for accomplishing this in the first tutorial. I showed how you could add a stand-alone Insert method to the TableAdapter and define the query so that it returns the newly inserted record (i.e., doing a SELECT SCOPE_IDENTITY() immediately after running the INSERT statement). Visit this screenshot to see the TableAdapter Query Configuration Wizard step that specifies the INSERT/SELECT statements. In addition to adding the SELECT statement, you also need to set the ExecuteMode property of the method to Scalar. Once this method has been added to the TableAdapter, calling it inserts the product and returns the just-inserted ID:

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim new_productID As Integer
new_productID = productsAdapter.InsertProduct(...)

While I illustrates this technique, I failed to use it in any subsequent data tutorials. Instead, the subsequent tutorial created a Business Logic Layer (BLL) that used the TableAdapter's batch Update() method to handle inserts and updates. The good news is you can instruct the TableAdapter to return information about the just-added record for those records added via the batch update pattern. When creating the TableAdapter, click the Advanced button in the wizard and check the 'Refresh the DataTable' option (see below). This causes the DataTable to be “refreshed” after adding or updating a record via the built-in DataTable data modification methods.

Next, update your BLL methods. For example, the tutorials create an AddProduct() method in the ProductsBLL class that returns a Boolean indicating whether a product was inserted or not. Modify this function to return an integer instead (since the ProductID field in the database is an int) and then adjust the method so that the code at the end looks like this:

' Add the new product


' Return the newly inserted ProductID value...

Dim newProductID As Integer = product.ProductID

Return newProductID

The AddProductsRow is a method in the Products table's DataTable. After the row is added, it is 'refreshed' and the resulting, newly-inserted ProductID value is available via the object's ProductID property.

Now, how do you work with the newly-inserted ProductID value from the presentation layer? If you call the BLL programmatically, just work with the return value of the AddProduct() method:

Dim productAPI As New ProductsBLL

Dim newProductID As Integer

newProductID = productAPI.AddProduct(...)

That was pretty easy.

If you're using an ObjectDataSource to do the insert then you can grab the value returned by the InsertMethod in the Inserted event handler:

Protected Sub ProductDataSource_Inserted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceStatusEventArgs) Handles ProductDataSource.Inserted

Dim newProductID As Integer

newProductID = e.ReturnValue


End Sub

I have a very simple demo illustrating this. The demo is in VB and uses ad-hoc SQL queries, although the concepts are the same when using C# or working with stored procedures. Download the demo here.

Happy Programming!

Filed under:
Working with Multiple Versions of the SourceGear Vault Client
21 October 07 09:20 AM | Scott Mitchell

A number of clients I do offsite consulting work for use SourceGear Vault as their source code control (SCC) program. I'm a big fan of Vault - it's easy to use remotely over HTTP or HTTPS, integrates seamlessly with Visual Studio, and provides all of the standard SCC features (history, diff, rollback, branching, labels, and so forth).

The only complaint I have about Vault is with the Vault Client. As the Vault Server software has evolved, its protocol has changed. This is understandable. In adding new features and squashing old bugs, I could see how the low-level communication protocol between the client and server might need to change over time.

Fine. But what's annoying as all else is that the clients are not backwards compatible. That is, if I have one customer that uses Vault Server 4.0 and another that uses Vault Server 3.0 (which are two versions that use different protocols), in an ideal world I'd be able to use the latest client software (Vault Client 4.0) and it would be smart enough to use the appropriate protocol depending on the server I connect to.

Unfortunately, this is not the case. Instead, I need to fire up Vault Client 4.0 when working with customer A and Vault Client 3.0 when working with customer B. It is quite possible to install multiple versions of the Vault Client on the same machine in different directories (like C:\Program Files\SourceGear\Vault 3.0 and C:\Program Files\SourceGear\Vault 4.0), but the real kicker comes when you throw Visual Studio integration into the mix. Visual Studio identifies the SCC provider it uses through a registry setting. In short, this means when I want to work with customer A I need to edit the registry so that it points to the Vault Client 4.0 executable in C:\Program Files\SourceGear\Vault 4.0. When I need to switch over to working with customer B's code base, I need to go back into the registry and modify that setting to point to the Vault 3.0 executable in C:\Program Files\SourceGear\Vault 3.0. (In actuality, I have one customer that uses 3.0, one that uses 3.5, and one that uses 4.0, all of which require different protocols, different client executables, and registry modifications when switching from one customer to another.)

The side-by-side installation process and registry keys that need to be modified are detailed here: Installing Multiple Versions of the Vault Client.

To help expedite the process of modifying the registry settings, I created .reg files that enable me to modify the registry setting by double-clicking the .reg file (rather than having to use regedit). Simply create a file for each Vault version you need to use with .reg extensions - like Vault_3_0.reg, Vault_3_5.reg, and so on - and then edit them with Notepad, entering the following text:



The particular path to the Vault IDE file depends on the version and where you installed the file. See Installing Multiple Versions of the Vault Client for more information.

Filed under:
Stepping into the .NET Framework Code
04 October 07 07:16 PM | Scott Mitchell

Earlier this week Microsoft announced that they would be releasing the .NET Framework code (and later, libraries like WPF and LINQ) to the public in a quasi-open source model under the Microsoft Research License (MS-RL). In short, it grants developers access to the source code for 'reference use,' which Microsoft defines as:

... use of the software within your company as a reference, in read only form, for the sole purposes of debugging your products, maintaining your products, or enhancing the interoperability of your products with the software, and specifically excludes the right to distribute the software outside of your company.

So there won't be any (legal) forks of the .NET Framework, for instance. Another hallmark of open source software is developer contributions. The idea is that if a developer spots a bug, she can correct it and submit a patch that can then be reviewed and integrated into the open source product. At this time, Microsoft is not offering any sort of ability for developer-submitted patches. Instead, feedback is to be directed to Microsoft through a feedback web page.

This announcement, by itself, isn't really anything new. After all, the .NET Framework libraries are unobfuscated and their source code is viewable through disassemblers like Reflector. The real news here is that this code can be seamlessly integrated into the Visual Studio 2008 debug-time experience. Scott Guthrie details this capability in his blog entry Releasing the Source Code for the .NET Framework Libraries. In short, you can configure Visual Studio 2008 to point to a URL that provides the debugging symbols and code for the .NET Framework. With this configuration set, you can step-into the .NET Framework source code directly from within your application, enjoying the same debug-time user experience and functionality.

This functionality is pretty neat. Sure, you can do the same thing through Reflector, but in doing so you have to hunt and peck through the code in Reflector. With this new feature in VS2008, you can step through the actual lines of code and use debugging windows like the Call Stack, Locals, Watch, and so on. But this is no panacea: if you find a bug in the framework code or if you find some internal behavior you'd like to change, you're still out of luck. It's not like you can go and modify the framework library code. Moreover, it's not like internal .NET Framework methods will now magically be accessible to external programs. But it will simplify understanding what's happening underneath the covers of the framework and will hopefully encourage more developers to roll up their sleeves and poke around in the bowels of .NET.

Filed under:
More Posts


My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.