SOLVED: Compiler error CS1519: Invalid token 'void' in class, struct, or interface member declaration

Posted on: Wednesday, 23 December 2009 17:00

This one has cropped up a couple of times in my development activities recently, but with just enough of a gap for me to have forgotten the solution and I had to figure it out again.

It happens in situations where the project worked fine a minute ago and then all of a sudden the project wont run. It has also happened in situations where I have made a small update and then some seemingly unrelated part of the site has broken.

Firefox - Clear Recent History

Posted on: Tuesday, 22 December 2009 19:07

I just accidentally stumbled upon a new feature / keyboard shortcut that I didn't know about in Mozilla Firefox. Its called Clear Recent History and it is a way for you to clear only a short range of your recent browser history.

If you press ctrl-shift-del then the following window is displayed:

firefox-clear-recent-history

Reading the ProviderUserKey when using the SqlMembershipProvider

Posted on: Monday, 21 December 2009 21:55

The ProviderUserKey gives access to a unique identifier for each of the members in your membership data store. If you're doing a large amount of lookup's or want to cross link to another table you will find this technique will give you better performance than using the UserName property.

SOLVED: TF31003 error when trying to connect to Team Foundation Server 2010 Beta 2

Posted on: Saturday, 5 December 2009 00:53

Welcome searchers! This post is not exactly light reading for the casual .net enthusiast so I will presume that if you're reading this you have probably landed here via a search engine after having a TF31003 problem crop up.

Installed software / background

  • Vista 64 bit
  • VS 2010 beta 2
  • TFS 2010 beta 2
  • Single server / basic installation
  • No errors on install
  • Cannot log in to the TFS system at all - no combination of user accounts will be accepted

Scenario

At any login point within TFS (such as in the add server dialog, or the Team Foundation Server Administration Console > Application Tier > Administer Group Membership link) you get an error pop up that contains the following message:

TF31003: Your user account does not have permission to connect to the Team Foundation Server at http://yourcomputer:8080/tfs. Ask your server administrator to add the appropriate permissions to your account.

How to automatically track events with Google Analytics and jQuery

Posted on: Wednesday, 2 December 2009 23:04

This article examines a way to use a feature of Google Analytics called Event Tracking. By using jQuery and the Google Analytics JavaScript API we will automatically track events on your site not seen by a standard analytics installation.

Update - VS2010 Beta 2 – Validation ($SCHEMA$): Element is not supported

Posted on: Saturday, 28 November 2009 11:30

Note: This is an update to an earlier post based on feedback that I have received from various commenter's.

If you have adopted beta 2 of Visual Studio 2010 then you might have spotted a large amount of green squigglies underneath the tags in your markup. When you have over them you see a message like this:

validation-schema-not-supported

Validation ($SCHEMA$): Element 'div' is not supported

Easily extracting links from a snippet of html with HtmlAgilityPack

Posted on: Thursday, 19 November 2009 23:36

The HtmlAgilityPack is a powerful library that makes screen scraping in asp.net a breeze. This is the second in a continuing series where I demonstrate a way for you to extract all the links from a snippet of html.

VS2010 Beta 2 – Validation ($SCHEMA$): Element is not supported

Posted on: Thursday, 12 November 2009 22:44

Note: Updated advice is now available over in this post explaining how to get around this problem without resetting your configuration.

If you have adopted beta 2 of Visual Studio 2010 then you might have spotted a large amount of green squigglies underneath the tags in your markup. When you have over them you see a message like this:

validation-schema-not-supported

Validation ($SCHEMA$): Element 'div' is not supported

I bet you didn't know that adding custom attributes to your web.sitemap was this easy!

Posted on: Wednesday, 11 November 2009 22:32

The site map file is a great place to store extra snippets of page-specific information. In this article we will explore how easy it is to add custom attributes to a site map by creating a user control to display a sitemap and adding custom attributes to filter out specific pages.

Advanced url rewriting for the rest of us - how to create a custom transform in UrlRewriter.net

Posted on: Sunday, 8 November 2009 16:58

Introduction

At first glance url rewriting can be a daunting task, but today we will see that it doesn't have to be. Every developer desires clean urls for their apps but because its not built into the language in a straight forward way its usually left on the "nice to haves" list.

The .net library does come with a few classes for performing url rewriting such as HttpContext.Current.RewritePath(); but it is a simple mechanism and you are largely left to code your own features into it. Today we are going to look at turning using a 3rd party library UrlRewriter.Net.

Microsoft Team Foundation Server 2010 Beta 2 Install Error - You must install Service Pack 2 or later to complete installation

Posted on: Monday, 2 November 2009 22:46

Have you have got an error when trying to install Microsoft Team Foundation Server 2010 Beta 2 which says:

"Windows Service Pack 2 Update Information"

You must install Service Pack 2 or later to complete installation. This service pack must be installed before you install this Microsoft Team Foundation product.

tfs2010beta2-installerror-sp2req

Learn exactly how you can restore a .bak file in SQL Management Studio with this step-by-step guide

Posted on: Saturday, 31 October 2009 01:24

This is a step by step guide which will show you how to restore a .bak file in Microsoft SQL Server Management Studio. This technique can be used to move databases between servers or restore an existing database to a previous state.

Here's a quick way to add English counties to your next sign-up form

Posted on: Friday, 30 October 2009 00:44

In the never-ending quest to speed up development and reduce the chance of user error I have packaged up a data source which can be used to populate your controls with a complete list of English counties.

Membership API documentation amended on MSDN

Posted on: Tuesday, 27 October 2009 19:00

In preparation for tonight's post I have just added some usage examples to the MSDN Membership API documentation. They are pretty straightforward but if you have any feedback on them then you can just update them on MSDN because they are community content:

I guess I will have to go back through and add them in again when 4.0 becomes the default MSDN version (unless they integrate it into the docs) but that's still a few months away so I figured it was worth adding to the current docs.

Burn! kick it Shout it vote it on WebDevVote.com

Join the voting frenzy with DotNetBurner's updated Live Writer plug-in

Posted on: Monday, 26 October 2009 23:31

If you haven't tried out the DotNetBurner.com plug-in for Windows Live Writer then now's the time to download:

Its a simple and time saving plug-in that will automatically insert those little kick / burn / shout counters you see at the bottom of many posts.

If you're a blogger and you're serious about sharing your content with the largest community that you can muster up then you owe to to your readers to take the extra step and make sharing your awesome content with others that little bit easier.

I'm not going to post a screenshot of what this looks like because I know somebody will want to click on it and get confused. If you want to see it then all you have to do is scroll down a few lines to see it in action.

A few minutes after I had installed it I fired off a quick email to the author, Thiago to suggest adding in support for WebDevVote.com's button as well. In less than 12 hours Thiago had added in the support and released a new version! (I don't think he spent all of the 12 hours coding).

So the total list of supported websites currently stands at 4:

  • DotNetBurner
  • DotNetShoutout
  • DotNetKicks
  • WebDevVote

Click on any of these voting buttons to visit the sites above:

Burn! kick it Shout it vote it on WebDevVote.com

All typed up and nowhere to post

Posted on: Sunday, 25 October 2009 18:00

Not long after I started this blog I decided I wanted to start submitting my content to news sites. My motivation behind this was that there wasn't any point writing this content if nobody saw it and also that I wanted to get enough daily visitors so that I could start getting some comments and feedback posted for each of the articles.

With asp.net being a pretty small subset of the global internet community I had a limited audience. I asked around a bit, posted a thread on the forums and did some searches to try and find all of the places where you can announce your news.

Below is my annotated list of all news sites that I have found to announce my latest posts on.

The big players

  • asp.net announcements forums
    I wasn't that sure about this being viewed as potentially misusing the asp.net announcements forum. It is mainly filled with product launches, offers and such. I have been posting in it for a couple of weeks now and the admin haven't chased me out of town.
  • submit an article for article of the day on www.asp.net
    This is a simple form which you can fill out and submit your blog article for possible inclusion in the asp.net article of the day feature. The queue is pretty long and they have a bunch of guidelines as to what they will accept. I haven't been featured yet but with it being the focal point of the asp.net community I think this one is very worthwhile.
  • dotnetshoutout
    I have used this website as a news source ever since it launched. The articles that get voted up are generally of high quality; covering craftsman topics such as agile, best practices, new technologies. They have an active community of voters which keep the link content fresh and they have a vote button which you can embed in your posts (like at the bottom of this one).
  • dotnetkicks
    I think dotnetkicks was the original digg style news posting community for dot net although its popularity seems to have waned. I don't get as much traffic as the others above but it has brought me about 5% of my overall traffic in the last month make it a top 5 referrer.

    One annoying thing about this site is that it has a really short title limitation which means your poetic, descriptive post titles will have to be reworded or clipped. I also experience a regular problem submitting the news. When you press submit it will post the page and just refresh rather than submitting. Just keep trying until it works because when it goes through it has only ever put a single copy of the news on to the site.
  • dotnetburner
    This site seems to be running off the KiGG codebase (which is what dotnetshout out runs on). Update - Thiago pointed out in the comments below that it isn't running off KiGG any more as he has rewritten the code to make it cleaner and faster. It has a lot of fresh news and sports a nice Windows Live Writer plugin for integrating the vote buttons for several of the big sites.
  • dzone
    This was a new site that I found in a .net bloggers sidebar recently but unfortunately I can't remember which one now! (Sorry). The site covers all development topics and a range of languages. It gives me the impression of being a well established site with the front page news items having around 30-50 votes in the past 7 days.
  • dotnetslackers
    This is a news aggregation service which is actually invite only. If you can't get yourself on there then you have a good chance of getting your news into their daily newsletter if you post it in the asp.net announcements forum listed above.
  • webdevvote
  • aspnetspy
    These are two new sites that I found some time last week and just submitted my first news items to about 10 minutes ago. I don't have anything that deep any meaningful to say about them other than you should put them in your blog post announce bookmark list. Oh - webdevvote covers other web dev languages not just asp.net.

Some other sources

  • codedigest submit news
  • codeproject submit news
    I have submitted several pieces of news to the sites above but with no real success. I think the news they are looking for is more in the region of product announcements and events rather than every random blog post some guy decides to write.

Foreign language

These are all foreign language versions of the KiGG codebase. I haven't used any of them yet although the Russian and Chinese ones do feature English language news items on front page so I guess posts are welcome.

Additions to this list

I am interested in growing this list to include any and all asp.net news posting sources. Its easy to miss pockets of developers out there on the internet and I would like to share my content with the broadest range of people possible. If you know any more then please leave a comment.

Burn! kick it Shout it vote it on WebDevVote.com

A simple way to add some flair to your site with a favicon

Posted on: Saturday, 24 October 2009 21:03

I am going to explain how you can get that little icon that appears next to the url in the address bar on many of your favourite sites. You will also find it next to its name if you add it to your favourites.

Here are some sample favicon's taken from the Firefox address bar:

favicon-image-examples

So now that we're all on the same page as to what a favicon is I will get down to the technical side of it. The favicon is obviously an abbreviation of "favourites icon". Favourites are bookmarks in the IE world which is where this idea started out its existence.

The modern favicon standard (it was standardised in 2003) is a lot more flexible than its original inception.

A little background

The favicon was a 16x16 icon which had to be in the Microsoft icon format, placed in the root of your website, and called favicon.ico. Because of these requirements the browser could automatically detect if your site has a favicon available.

Now that it has been standardized you can put the file in any location. The number of file types has been expanded as well as the number of sizes of icon you can support.

Because you can put the favicon anywhere now you have to notify the browser by putting a <link> tag in your web pages. Before this was settled on there were two ways to define it - rel="icon" and rel="shortcut icon".

The final standardisation solved all the problems with the early versions of favicons. The fixed file name is known as url squatting which is frowned on. The file type was a Microsoft proprietary format. The <link> rel tag didn't follow the proper space-delimited list standardisations (it used two separate keywords to mean a single keyword).

Even with all of these problems solved I must admit that I still take a traditional approach my favicons. I save them as favicon.ico in the root of my websites, in MS icon format and do  belt and braces with the link tag by including both a rel="shortcut icon" and rel="icon". Its probably overkill but for such a simple feature I feel that adhering to the original standards means that my favicons will be supported by the widest possible number of browsers.

How do you make yours?

I am going to skip over the part where you make a 16x16 graphic and try to cram your logo into it. If you don't have any artistic skills yourself then you can turn to a friendly artist on your team or reach out to the community.

For some reason icon file format support has never been included in Photoshop so while you can make your brilliant 16x16 graphic in that program you will have to turn to a 3rd party to get it in the correct format.

There are various plugins for Photoshop available and online generators which can help you with this.

And don't forget that you aren't forced to use the ico file format with modern browsers, png, gif and jpeg are all valid formats.

How to you link in into your site?

Personally, as I said above, I call my icons favicon.ico in the root folder of my website. That would be enough to get it to show up in all modern browsers. I also put the <link> tags which look like this (xhtml snippet - remove the trailing / if you are working in html)

<link rel="icon" href="/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon" />

So now you know how to add that extra flair into your next website project. Its completely up to you if you want to follow my old school approach or if you want to take full advantage of the newer features such as multiple icon sizes, animated gifs and different filenames and locations - these will still work on the majority of modern browsers. You could always throw in a backup favicon.ico in the root for the old browsers "just in case".

Further Reading

kick it on DotNetKicks.com Shout it

The new Google-friendly 301 redirects in asp.net 4.0

Posted on: Friday, 23 October 2009 18:00

We are going to take a glance at one of the many new features in asp.net 4.0 and expand our redirection repertoire by embracing the 301 redirect.

Asp.net 4.0 is nearing closer and the amount of hype about the new Visual Studio is growing exponentially with the new Beta 2 release I decided to take a chance on it and install it on my home dev computer.

Its currently downloading part 11 of 36 components and in preparation I took a look at the new feature list. One of the first things that caught my eye is the new RedirectPermanent method which has been added to the HttpResponse class.

If you have a catalogue of products - say for example you had a client who's a lawnmower retailer. When the old models are replaced by new ones each year a page on your site might cease to exist. If any external sites (or even internal pages) had taken the time to create links to these pages then you would be presented with an error page the next time that link was clicked.

The more savvy ones out there would probably have used the following code in the old page:

Response.Redirect("~/grass-guzzler-2010.aspx");

This would have worked as far as the visitor to the page was concerned. In the background however the code issued by the server would be a 302 redirect. This kind of redirect means that it is a temporary redirect.

As far as search engines are concerned you are constantly telling them not to update their internal indexes or pass over existing page rank to this new page.

But the problem is that this isn't a temporary redirect its a permanent one, and for that you will need to issue a permanent 301 redirect.

You have just learned about this at a great time in your life because starting with asp.net 4.0 this feature is built into the .net library in the form of RedirectPermanent().

Using the same code above you make the minor change to make it look like this:

Response.RedirectPermanent("~/grass-guzzler-2010.aspx");

We have just looked at the simple update you can make to your change so that you can easily create search engine friendly, permanent 301 redirects on your sites.

Further Reading

kick it on DotNetKicks.com Shout it

Why asp.net accidentally corrupts your base64 encoded strings if you pass them as a query string (its nothing personal)

Posted on: Thursday, 22 October 2009 18:00

We are going to investigate one of the gotchas when using base 64 encoded data with the asp.net Request.QueryString array.

If you try to extract a base64 encoded string from a query string then it will get corrupted. This is because a valid base64 encoded string will more than likely have plus + symbols it. As far as a url is concerned a plus symbol has a special meaning - it is the url encoded equivalent of the whitespace character.

This means that when you retrieve them from the Request.QueryString collection asp.net innocently performs its due diligence and url decodes the incoming string, replacing all + symbols with spaces.

If you try to decode the remaining base64 string you will get an error because its not in a valid format.

Is this going to happen to me?

One thing to note - this will only occur if you have a third party external system pass you a plain base64 encoded string without url encoding it first. If you're putting the base64 string into your query string via some asp.net code then you will not experience this particular bug.

How do I work around this?

The trick to work around this is to do a string.Replace(" ", "+") on any base64 encoded strings that have come from a QueryString before you use them.

string validBase64String = Request.QueryString["data"].Replace(" ", "+");

And that's safe?

Its safe to do this because a space character is not a valid character in a base64 encoded string. Based on this fact you can be sure that if there are any space characters then you already have a broken base64 string on your hands. Doing the Replace() is not going to corrupt your data any further.

kick it on DotNetKicks.com Shout it

Dynamic meta description and keyword tags for your MasterPages

Posted on: Wednesday, 21 October 2009 18:00

Today we're going to look at a technique for dynamically inserting meta tags into your master pages. By taking control of the head tag and inserting your own HtmlMeta you can easily customise these tags.

You might have noticed that when you create a new master page in visual studio your <head> tag gets decorated with a runat="server" attribute.

Asp.net doesn't add this kind of decoration to any other html tags (although you are free to add it if you want). So what makes the head tag special?

By adding the runat="server" you're giving actually converting the control into a HtmlHead control. That doesn't particularly matter for this tutorial other than to note that given a reference to the head control you get all the extras that come with asp.net controls such as access to its controls collection.

Why would you bother?

Neither the page meta description or meta keywords tags will do much for your sites ranking so why would you take the time to do this?

Well Google has gone on record to say that the keywords tag is not taken into account when ranking your score. Honestly I don't think its worth the effort to add the keywords into sites any more. I have seen some people give the opinion that it future proofs your site and that if Google ever does implement it into the algorithm then you will be ready. That seems like a fairly weak premise to base your decision on.

The description tag on the hand can be valuable. Perhaps not for ranking well in the search engines directly but more for the social engineering aspect. When you have get your result to appear in the search engine the text displayed from your meta description could make the difference between somebody clicking your site or your competitors.

Introducing the HtmlMeta control

The HtmlMeta control lets us wrap up <meta> tags via asp.net code. To add a meta description we need to create an instance, set the name property, the content property, and then add it to the head:

HtmlMeta meta = new HtmlMeta();
meta.Name = "description";
meta.Content = "this is a meta description tag";
head.Controls.Add(meta);

Its the exact same code for the keywords tag - you just change the name.

Public Properties

Instead of copying this code in every time you want to add meta tags to your page you can wrap these two concepts up in public properties which are easy to set.

The code would go in the code-behind file for your master page and would look something like this:

public string MetaDescription
{
    set
    {
        HtmlMeta meta = new HtmlMeta();
        meta.Name = "description";
        meta.Content = value;
        head.Controls.Add(meta);
    }
}

public string MetaKeywords
{
    set
    {
        HtmlMeta meta = new HtmlMeta();
        meta.Name = "keywords";
        meta.Content = value;
        head.Controls.Add(meta);
    }
}

If you get red squigglies under the HtmlMeta in visual studio then you have probably just forgotten to include the System.Web.UI.HtmlControls namespace that it lives in:

using System.Web.UI.HtmlControls;

Further reading

kick it on DotNetKicks.com Shout it

How to revert the close tab functionality in Firefox 3.5 back to 3.0

Posted on: Tuesday, 20 October 2009 18:00

In the Firefox 3.5 release the default close tab behaviour has been changed.

The new behaviour is to immediately close the browser when the last tab is closed. This mirrors the way that Internet Explorer handles its tabs and probably makes more sense for the masses.

Personally I had grown fond of the safety net of being able to have zero active tabs. A couple of reasons off the top of my head are that it means you don't accidentally close your browser and have the delay of waiting for it to load up again. You also wont lose your undo close tab / page history cache which is wiped when the browser is closed.

So I set off to find out if there was an extension that would restore this functionality. I didn't find one but I did find some tips that basically let me restore the feature I wanted.

Part one - Don't close the browser with the last tab

The first issue was to get the browser to stop closing as soon as the last tab was closed. This turned out to be pretty simple:

  1. Type about:config into the address bar of Firefox
  2. Agree to the dialog that appears so that you can view and edit the configuration settings
  3. Locate the following configuration item:
    browser.tabs.closeWindowWithLastTab
  4. Set its value from true to false

Part two - Show me the close buttons

This second part is purely cosmetic and optional. The UI was changed so that the final tab didn't have a close button on it any more - to prevent normal users from closing the browser unexpectedly.

The aim is to add a piece of css in to the userchrome.css which is a file tucked away in Firefox for exactly this reason - allowing user modifications to the chrome. The chrome is basically the UI layer of Firefox if you were wondering.

  1. Go to your profile directory, which on Vista is here:
    %appdata%\Mozilla\Firefox\Profiles\
    (Just paste it into the search in your start menu)
  2. Open up your active profile folder. There will probably be only one profile folder in there - it will be called a random string of letters and numbers.
  3. Go into the Chrome folder and open up userchrome.css in notepad (or create it if it doesn't exist).
  4. Enter the following css into it:
/* Add tab-close-button to last tab*/
.tabbrowser-tabs[closebuttons="alltabs"] > 
 .tabbrowser-tab > .tab-close-button {
  display: -moz-box !important;
 }
.tabbrowser-tabs:not([closebuttons="noclose"]):not([closebuttons="closeatend"]) > 
 .tabbrowser-tab[selected="true"] > .tab-close-button {
  display: -moz-box !important;
 }

Sources

The tricks in this article were found in the following forum thread:

Further Reading

If you're a Firefox user then please consider checking out my Firefox extension called "Good Deeds".

Its a simple extension which loads up a website called TheRainforestSite.com once a day so that you can click the button on that page. Every time you click that button the advertising money which is earned on the following page is contributed towards saving the rainforest.

Using the RequiredFieldValidator attribute InitialValue to control valid selections in your DropDownLists

Posted on: Monday, 19 October 2009 18:00

The RequiredFieldValidator is a common utility in the asp.net coders validation toolkit. Its simple to use and probably represents one of the most common requirements for validation - that data must be there.

Its official definition is:

Evaluates the value of an input control to ensure that the user enters a value.

Using it to require TextBox content is an obvious and straightforward use but using it to validate DropDownList selections might not occur to you straight away.

How would you stop the user from submitting the form with "Please select" selected in the sample DropDownList below?

<asp:DropDownList ID="DropDownList1" runat="server" ValidationGroup="DropDownSample">
   <asp:ListItem>Please select</asp:ListItem>
   <asp:ListItem>Lincolnshire</asp:ListItem>
   <asp:ListItem>Nottinghamshire</asp:ListItem>
</asp:DropDownList>

InitialValue is the key. To use it you simply setup your RequiredFieldValidator as you normally would but add in the extra InitialValue attribute set to the string of text that you don't want to be submitted.

The RequiredFieldValidator for the DropDownList above would look something like this:

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" InitialValue="Please select" ControlToValidate="DropDownList1" ErrorMessage="Please select a shire" />

A Real World Databound Example

The technique above is great for ensuring that your users properly select values for your DropDownLists. In the real world however you'll usually find yourself needing to bind the data to your drop down. So the issue becomes how do you combine your initial value text with the data that's bound?

There is an attribute called AppendDataBoundItems="True" which you can add to a DropDownList. This means that when you databind your dropdown the options you have hard coded in will not be overwritten.

So if you added the first starter ListItem with the text of "Please select" and databind your DropDownList it will be preserved at the top with your data below. This means you don't have to do any special tricks to get your default text included in your data set.

In the sample below I have included a datasource which randomly generates a list of numbers. Its a good example of how to create your own bindable data objects, but its not the focus of this article.

<asp:DropDownList ID="DropDownList2" runat="server" ValidationGroup="DataBoundDropDownSample"
    AppendDataBoundItems="True" DataSourceID="ObjectDataSource1">
    <asp:ListItem>Please select</asp:ListItem>
</asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="Select" TypeName="RunTingsProper.Sample.Data.SimpleIntegerData">
</asp:ObjectDataSource>
<div>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" InitialValue="Please select"
        ControlToValidate="DropDownList2" ValidationGroup="DataBoundDropDownSample" ErrorMessage="Please select a number" /></div>
<asp:Button ID="Button2" runat="server" Text="Select" ValidationGroup="DataBoundDropDownSample" />

Download these examples

You can download these examples to play around with here:

Bonus tip - InitialValue can also be used for TextBox's

The text that you set in the InitialValue can also be used on other input controls. In theory you can use it to prevent any value that you like being entered into a TextBox. The TextBox doesn't have to have that value embedded at the start - it just can't be submitted with that value.

In practice this doesn't really come in useful very often; usually if you do need this kind of feature you can solve your problem more succinctly with a RegularExpressionValidator.

Bonus tip #2 - You can use more than one validator on a control

Don't forget that you can add more than one RequiredFieldValidator to work on a single control. This means that should you find yourself wanting to prevent more than one selection in a DropDownList you could wire up as many RequiredFieldValidators (each with their own InitialValue attributes) as you need to solve the problem.

Further Reading

kick it on DotNetKicks.com Shout it

The secret newline symbol for html encoded controls

Posted on: Sunday, 18 October 2009 18:00

ASCII Character 10 is an under loved character in the ASCII set. It lurks around there right at the beginning in the non-displayed range and most of the time you use it you don't even realise it.

Well you probably already guessed from the subject of this post that this mysterious symbol is actually the newline character.

A lot of controls automatically html encode their output, and rightly so, its asp.net's way of protecting you from cross site scripting attacks and it also makes your site much more likely to show you a green light when you post it through the w3c validator.

But sometimes you want a specific markup to be displayed. Whether its you or your boss that's the perfectionist you need that newline and your <br /> or \n have failed you.

So how do you encode the newline? ASCII 10 to the rescue!

The entity looks like this:

&#010;

and it can be used in your html encoded strings because its already html encoded!

I actually found this tip tucked away in a thread on the asp.net forums (see further reading). It was half way down the thread and it didn't even get marked as the answer! Credit where credits due - thanks for this tip Mohamed Alsakaf!

Usage Example

<asp:Button ID="Button1" runat="server" Text="An example of a&#010;long button&#010;with complete control over the newlines" />

Further Reading

kick it on DotNetKicks.com Shout it vote it on WebDevVote.com

Easy default roles for new users with the CreateUserWizard

Posted on: Saturday, 17 October 2009 14:08

Here's a scenario for you: You have an admin panel and you want to let the administrators of the site create extra admin accounts when they need to. Your site uses asp.net membership and roles and you need an easy way to make sure the new admin is added to the administrator role at creation.

To implement this on your site you only need a couple of lines of code.

  1. Open the page in your admin panel which has the CreateUserWizard in it.
  2. Make sure that you have disabled automatic login for newly created users.
  3. Single click on the CreateUserWizard in design view.
  4. Bring the properties window up by pressing F4 if its not already visible.
  5. Click the lightning rod to view the events.
  6. Double click on the CreatedUser event.
  7. Put the code from the event below into your newly created event.
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
    CreateUserWizard cuw = (CreateUserWizard)sender;

    string RoleToJoin = "Administrator";

    if (!Roles.IsUserInRole(cuw.UserName, RoleToJoin))
    {
        Roles.AddUserToRole(cuw.UserName, RoleToJoin);
    }
}

If your Roles isn't lighting up then you are missing a reference to the System.Web.Security namespace which can be added by inserting the following code into the top of your code-behind:

using System.Web.Security;
kick it on DotNetKicks.com Shout it

The sneaky Open Command Window Here feature in Windows Vista

Posted on: Friday, 16 October 2009 18:00

I am by no means the first to blog this (most people probably blogged this about three years ago when Vista came out!) but I keep using it recently and I thought maybe some people have forgotten this in the last few years.

That's often the problem with a really cool tip - if you don't keep using it then you forget it. Sometimes when you're in the middle of things you half remember it but don't know how to find the exact trick quicker than it is to do it the "hard way".

Isn't it lucky for me then that now I'll always know that this tip can be refreshed in my mind with a quick search of my blog?

For the rest of you this might be your only chance for the next three years so listen up :)

How to get a Open Command Window Here option in the context menu of a folder

To get the Command Prompt Here option you simply have to hold down the shift key and right click on your folder. The context menu that pops up looks pretty similar to the one you always get except that it has an extra entry that says "Command Prompt Here":

open-command-window-here

Bonus knowledge - network drive mapping

While researching this blog post (yes I did research for a tip this simple) I found this little tidbit over on this post:

(Reproduced entirely without permission - sorry Tim!)

What's really cool about this is that if the target folder is a network location, Windows Vista silently maps a network drive to that location before opening the folder (so that your command prompt has a valid path containing a drive letter) and then deletes the network drive once the command prompt is closed.

Source: Tim Sneath's Blog

He actually has a pretty interesting series of Vista tips if you are up for the distraction:

Yes you can have your javascript style curly brace positioning if you really want to

Posted on: Thursday, 15 October 2009 18:00

This question came up on the forums the other day. Basically somebody wanted to change the auto formatting features of Visual Studio so that their curly braces didnt get pushed down on to their own lines every time they wrote the next line.

An example of how visual studio will auto-format your methods out of the box:

public bool IsEnabled()
{
  return true;
}

However the user wanted to keep the first curly brace on the same line as the method signature like:

public bool IsEnabled() {
  return true;
}

It's a matter of personal style. Personally I think it is less readable because it reduces the scanability of the code - you have to schwip your eyes over to the end of the method signature (which can be a variable length) to check where the start of the curly braces are.

Anyway I appreciate everyone has their preferences so this is how you set it up if you are excited about this same-line curly brace option:

  1. Click Tools | Options…
  2. Scroll down to the Text Editor node
  3. Expand the C# node
  4. Expand the Formatting node
  5. Click on the New Lines node
  6. You will see a list of options like in the image below which give you full control over when Visual Studio should put your open brace on a new line

newlinesforbraces

Visual Web Developer 2008 Users

You might be wondering if this option is available to you, or you might have tried to follow the tutorial above and found out you cant find the nodes I described?

Well it is possible to configure this in VWD 2008 - the only difference is that after step 1 you need to tick the little checkbox that says "Show all settings".

An easy way to keep your dev and live server urls in sync

Posted on: Wednesday, 14 October 2009 18:00

A common setup for your live server is to run your website on the root of the domain. By this I mean if you wanted to go to the homepage of your site you would type in

http://www.example.com/

When you are working on your dev copy of the site with Cassini on localhost (the built in dev web server) though you find your urls look more like

http://localhost:4865/YourProjectName/

If you're working purely with asp.net components in your site then you can always rely on the squiggly notation (called the tilde) to ensure your urls are mapped to what is called your "Application Root".

So you could have an <asp:Image> that has an ImageUrl attribute which looks like this:

<asp:Image runat="server" ID="Image1" ImageUrl="~/Images/thumb1.gif" />

And this would get turned into the proper url(either /Images/thumb1.gif or /YourProjectName/Images/thumb1.gif).

The trouble is that in most projects you need to use some links that don't mesh into the tilde enabled mapping systems such as the urls inside your CSS files - or even linking the CSS files into your template.

If all this is sounding like a familiar problem then this tip is for you. The trick we need to perform is to make Cassini run your dev website on the root of the localhost domain rather than in a subdirectory. That way a single url can be used on both your dev and live servers.

The steps are pretty simple:

  1. In the Solution Explorer window you select your Project node
  2. In the Properties window (press F4 if you can't see it) you change the "Virtual path" attribute from /ProjectName to /

The two windows look like this in Visual Studio 2008:

how-to-change-site-root

Shout it kick it on DotNetKicks.com

I didn't want you logged in! How to prevent new users being signed in with CreateUserWizard

Posted on: Tuesday, 13 October 2009 19:55

This one has come up twice in the past week as an unknown feature of the CreateUserWizard. I've seen developers performing complicated code-behind magic to try and prevent the user being logged in and others simply asking if its possible.
The default behaviour of the CreateUserWizard is that when it has created the user it logs that new user in.
You might not want this for a few reasons:
  1. You are in an admin panel and you don't open up your signup's to the public.
  2. You have some extra coding in place that sends out a verification email before they are let into the system
  3. You want to review the accounts by hand before you activate them
  4. Some other mysterious reason

Well the way to prevent it is to add the following attribute to your CreateUserWizard control:

LoginCreatedUser="False"

Its a simple as that - when the newly created user is created they are not logged in.

Further Reading


kick it on DotNetKicks.com

Sending An Email Using Telnet

Posted on: Thursday, 8 October 2009 18:12

Note: This was originally posted on a site that I used work on but its no longer online.  I still find this tutorial handy when I am testing mail out so I thought I would repost it here for easy access.

When I am setting up an external mail server for a client I sometimes find it useful to test it out by sending the raw commands via telnet. The process is pretty straight forward. I am going to run through it twice in this article depending on the reason you're here:

Getting telnet in Windows Vista

If you follow the tutorial below in vista you will hit a problem almost straight away - telnet is not installed by default in Windows Vista. I have written a separate guide explaining how to install telnet in Windows Vista.

I want to learn what it means

  1. Start off by clicking the Start button and selecting Run...

  2. Type telnet and press enter. Microsoft Telnet Client will start. It looks like a standard dos box.

  3. Type the following command, replacing mail.server.co.uk with the url or ip of your mail server.

    open mail.server.co.uk 25

    25 is the standard SMTP port. Press enter at the end and you will connect to your mail server. If this doesn't work then this is the first sign you have problems.

    Some things to check are:

    • Did you spell everything correctly?
    • Are you connected to the internet?
    • If you typed a domain, have you tried the IP?
  4. Next step is to introduce yourself to the mail server. Replace yourname with any string you like, its simply used to indentify the sending in the email servers logs.

    helo yourname
  5. Tell the mail server who is sending the email. Replace you@yourname.co.uk with your own email address. Many mail servers will let you get away with a fake email address here, but if you are testing then I would recommend using a real one.

    MAIL FROM: you@yourname.co.uk
  6. Next you have to give the destination email address. Replace them@server.co.uk with your target address.

    RCPT TO: them@server.co.uk
  7. To send the body of your message you start off with a DATA command followed by enter. The response from this command will tell you how to end your message. Its almost always a full stop (.) on its own on a new line, but you should note this down.

  8. Type your message.

  9. End the message with the command you were instructed to in step 7 (probably a .).

  10. At this point your email address has been sent. If you want to send another message then you should start over. If not then its good practice to close your connection gracefully by issuing the QUIT command.

I just need reminding

If you have used telnet before and know the basics but just need reminding of the details then this quick reference guide should get you through with the minimum of hassle.

open mail.server.co.uk 25
HELO unique-identifier
MAIL FROM: you@yourcompany.co.uk
RCPT TO: them@server.co.uk

DATA
type your message here
. [or whatever identifier you are told to use after DATA]
QUIT
  

If any of these commands don't make sense then hop back up to the top of the page and read the full explanation!

How to install telnet in Windows Vista

Posted on: Wednesday, 7 October 2009 22:09

This is just a quick little tutorial which walks you through the steps to install telnet in Windows Vista as its not there by default.

It was written to accompany another upcoming tutorial I am working on but if you just landed here from a search engine then I guess its just as handy!

Is telnet already installed?

Before you follow this you better check you haven't already installed it and forgotten!

  1. Press Start Key on the keyboard and the R key together
  2. Type telnet into the run dialog
  3. Press enter

If you see a message that says "Windows cannot find 'telnet'. Make sure you typed the name correctly, and then try again." with an OK button then press OK and carry on with this tutorial.

Installing telnet

  1. Click the Start orb
  2. Choose Control Panel
  3. In the top right corner search box type "feature"
  4. Click the link that says "Turn Windows features on or off"
  5. Wait a short while for Windows to figure out which features you already have turned on
  6. Scroll down to the entry "Telnet Client"
  7. Tick the checkbox
  8. Click OK
  9. Wait another short while
  10. When its done you can close the control panel.

Features I Want To See In Asp.Net 4.0

Posted on: Sunday, 4 October 2009 12:57

I know this is probably a bit late in the pipeline now but I just wanted to jot down some features that I want to see in the next version of asp.net.

Visual Studio

  • recent Projects actually showing recent projects, like the last 8 projects I opened, and let me delete them from the list at will
  • make the RSS feed work in the start page!
  • integrate an easy to use feature into vs that lets me compile user controls into assemblies and hook them into other projects without having to jump through hoops of dodgy assembly names, stub files, registering items web.config, msbuild steps, and all the trouble.
  • give me a Dreamweaver quality site-sync to upload my files (the one in vwd 2008 cant connect to my server for some reason, it worked in vwd 2005 though it wasn't as good as Dreamweaver)

ASP.NET

  • fix this bug that prevents us from nesting templates in usercontrols
  • extend usercontrols to support more of the server control attributes like the ToolBoxData, type converters, etc OR
  • give server controls a design surface
  • add an "add to default sitemap" checkbox in the add new item dialog so I dont forget to put my pages in my .sitemap file
  • don't make me use lines like <@ MasterType VirtualPath="~/Templates/Main.master" %> in every content page that I want to access the master page.

MSDN

  • Add some documentation which explains the proper way to do SitemapPathResolve (see community content section) without crashing your server.

Platform Installer

  • fix the bug that occurs when you want to install sql 2008 over 2005 - the first time I wanted to use it and it force me to go back to the old school!

Change the default OS on a dual boot system

Posted on: Saturday, 3 October 2009 22:41

I have Windows 7 RC1 installed as well as Windows Vista. Up until a few minute ago I had been frantically hitting F8 every morning when I turned my pc on to stop it booting into Windows 7.

Windows 7 seems like a great system but I haven't installed all my programs and made a commitment to it. Plus I need to get a new sound card for it.

To change the default operating system is quite easy these days (if i recall correctly back in the day you would have had to edit a boot.ini file by hand and hope you got the syntax right)

This guide is for Windows Vista.

  1. Open up the "System" panel using one of these methods
    1. Click start, right click on your Computer link and choose Properties
    2. Press the Start + Break key combination (the top right key which also says Pause)
    3. Click start, choose control panel, and type system in the top right search box
  2. Click Advanced system settings in the Tasks menu down the left hand side
  3. Click the Advanced tab
  4. Click the Settings button in Startup and Recovery
  5. Use the drop down "Default operating system" to choose your OS.
  6. Click OK on all the windows until you are back to System dialog.

And that's all there is to booting up cleanly in your preferred OS.

Bonus tip

In case you didn't go ooh and aah when I mentioned the Start + Break key combo earlier then I recommend you try it now. When I sit down at a new pc to fix it for somebody its normally the first thing I use to see if the spec (processor and ram) meets the OS requirements. Its useful in more scenarios than that though such as getting networking info and getting a clickable device manager link up really fast.

Master user friendly date of birth selection with the AjaxControlToolkit Calendar extender

Posted on: Friday, 2 October 2009 21:19

The latest version of the AjaxControlTookit is out (September 2009 release) and it brings with it two new controls (Seadragon Image Viewer and AsyncFileUpload).

This release also has a heavy focus on quality with over 20 bugs fixed.

The most important one that caught my eye was the new Calendar attribute called DefaultView. This simple attribute will let you open up the calendar in a year -> month -> day order which means collecting date of birth information is now a lot more user friendly.

In previous releases you could switch to the year mode by clicking on the title bar of the calendar twice and experienced users knew this but the vast majority of the internet population didn't. For me this meant that I had to result to having "tip" messages on my forms so that I could be fairly sure that my poor users wouldn't sit there clicking backwards on the calendar for the whole day!

So bug number 9601 has been fixed and now we can do it easily. How easily? Well let me show you!

Code Sample

<asp:TextBox ID="DateOfBirth" runat="server" />
<cc1:CalendarExtender ID="DateOfBirth_CalendarExtender" runat="server" Enabled="True"
   TargetControlID="DateOfBirth" DefaultView="Years" />

As you can see the DefaultView attribute is set to years and when you click in the TextBox the Calendar pops up in year selection mode.

Downloadable Sample

An interactive downloadable sample can be downloaded here:

Further Reading

Introduction To The HtmlAgilityPack Library

Posted on: Sunday, 27 September 2009 13:29

If you haven't heard of the HtmlAgilityPack before then you could be in for a treat. It's an open source library on codeplex which greatly eases html screen scraping.

What is screen scraping?

Screen scraping is the term for downloading a web page and then parsing its html to pull out information from it. In the old days before RSS feeds this was the only way to get at a websites information. With the advent of syndicated content and web services it has become a lot easier to get information from other sites but there are still situations where you need to go back to screen scraping to get the job done.

One example of a reason that you would still want to use this technique in a modern day environment is a price comparison site. When the complete stock information is not made available you have to read the data out of the website. Other reasons include weather data monitoring, website change detection (such as the release of a new version of software) and getting meta information from a page.

Doesn't .net support this natively?

The .net library comes with built in classes to manipulate XML documents with ease however in most cases you wont get won't get very far trying to screen scrape with these libraries. This is because they require standards compliant mark-up which is not very common for web sites. The XML standard has a strict policy of failing at the first error so unless you give it perfectly formatted code you wont be able to use these classes.

The HtmlAgilityPack provides a set of classes that makes it easy for you to download html pages into memory and then query them using XPath syntax. It doesn't matter if the page isn't standards compliant, the library will just do the best with what it has.

Where can I download it?

The codeplex project is located at the following location:

To download it just click the Download Now button located down the right hand side of the page and then press I Agree to accept the codeplex license agreement.

The pack comes with a couple of examples to get you started and there are most posts in this series here on this site.

More In This Series

This article is part of a series. You can find more posts in this series here:

Further reading

kick it Shout it vote it on WebDevVote.com

HtmlAgilityPack Article Series

Posted on: 13:25

This is an index post which will pull together the various HtmlAgilityPack posts on here. If you don't know what the HtmlAgilityPack or the idea of Screen Scraping is then you should read the first introductory article, otherwise you can dive right in!

Article Index

Where to get an asp.net 2.0 compatible AjaxControlToolkit

Posted on: Thursday, 17 September 2009 23:01

(Updated: To include the latest controls asp.net 2.0 users are missing out on)

This is just a simple link so that I don't have to keep finding it and explaining the situation each time the topic comes up.

Asp.net 2.0 support

The AjaxControlToolkit doesn't support asp.net 2.0 any more. This means that if you are still using asp.net 2.0 then you will have to download an older release.

The last version that was released with 2.0 support was toolkit version 1.0.20229. Download it here:

Asp.net 3.5 support

If you're looking for the latest 3.5 version then I suggest heading directly to the front page of the site so that you can get the latest version. Actually this url seems to automatically redirect you to the latest version available:

But if it breaks for you in the future then use this link and click the download button in the top right:

What's missing for asp.net 2.0 users?

The following controls (at the time of writing) are missing from the older AjaxControlToolkit:

  • HTMLEditor
  • ComboBox
  • ColorPicker
  • MultiHandleSlider
  • Seadragon Image Viewer
  • AsyncFileUpload

Round off time to the nearest minute

Posted on: 07:59

Say you have a DateTime object like this:

DateTime someTime = DateTime.Parse("00:00:38");

Rounding Up

How would you round this up to the nearest minute? There isn't a built in function to do this so you have to use a little bit of maths to get there. There are 60 seconds in a minute. We already have 38 seconds on the clock. So we need to add on 60 - 38 = 22 more seconds.

In code this looks like:

DateTime RoundUp = DateTime.Parse("00:00:38");
RoundUp = RoundUp.AddSeconds(60 - RoundUp.Second);

Now our RoundUp contains "00:01:00".

Rounding Down

To round down we use the same idea:

DateTime RoundDown = DateTime.Parse("00:01:38");
RoundDown = RoundDown.AddSeconds(-RoundDown.Second);

Note

The AddSeconds() method doesn't actually alter the DateTime its working on - it just returns a new one. This is why I assigned the DateTime to itself in the examples above.

Farewell VSJ print edition

Posted on: Tuesday, 15 September 2009 19:27

In the first page of VSJ there is a small message from the editor which discreetly announces that this month will be the final month of VSJ in print. I will miss reading this publication which has become a part of my life over the past year.

Being a massive geek it was a nice fix when I found myself being forced to leave my computer for a few minutes such as when I have to wait for somebody.

The magazine is still going to continue as an online publication but if I am honest I wont be reading it. There is already enough content to read when I am at my computer and I dont have time to get through all of it!

So thats that then. Does anybody know of any other great .net focused print magazines?

A better way to reference your wizard steps using named steps

Posted on: Saturday, 12 September 2009 10:52

Note: this article uses the plain vanilla <asp:Wizard> but the concepts apply equally well to its popular counterpart <asp:CreateUserWizard>.

By far the most common way that I see wizard steps reference in code snippets is by their index.

Something like this is common:

void Wizard1_NextButtonClick(object sender, System.Web.UI.WebControls.WizardNavigationEventArgs e)
{
     if (Wizard1.ActiveStepIndex == 1)
     {
          // jump to step three
          Wizard1.ActiveStepIndex = 3;
     }
}

This was actually taken from some MSDN documentation. But what's the problem with this? It works doesn't it?

Yes it works today but the problem is when you come back in a few weeks and want to re-order your steps, or add a new one in somewhere. Suddenly all those numbers seem to have a lot less meaning. Its a chore to change the steps over and its not something that will get caught by the compiler of you miss one or get it wrong.

There is a better way though because you don't have to tie yourself down to the index. The trick in a nutshell is to give each of your <asp:WizardStep>'s an ID. By default the Visual Studio GUI doesn't do this but you can add them in yourself. This gives you a meaningful name that you can use and its not tied to the order of the steps.

Example 1 - Finding a control in a WizardStep

The first challenge that is enhanced by this technique is finding controls that are inside wizard steps. Instead of having to go through the Wizard control you can now use FindControl() directly on your WizardStep because you have a way to access it.

TextBox firstName = (TextBox)StepNameHere.FindControl("FirstName");

Example 2 - Comparing against CurrentStepIndex

The second example is my favourite trick because I didn't find out about it for a while after I had started using named WizardSteps.

If you have a WizardStep called StepBillingDetails for example, you can use the Wizard1.WizardSteps.IndexOf() to find the index of that named step. This turns your named step into an integer which can be used to compare against properties such as ActiveStepIndex property of the Wizard and CurrentStepIndex in your NextButtonClick event.

protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
    Wizard w = (Wizard)sender;

    // check if billing details step has been completed
    if (e.CurrentStepIndex == w.WizardSteps.IndexOf(StepBillingDetails))
    {
        // user has just completed the wizard step "StepBillingDetails"
    }
}

Example 3 - Predictable Hot Jumping

From looking back at the first example that I gleaned from MSDN you can probably see how we can improve it using these new techniques. While it is a slightly contrived example (I doubt I would always want to unconditionally jump from step one to step three) it does illustrate my point.

Lets take a look at what it looks like now that it uses named steps:

void Wizard1_NextButtonClick(object sender, System.Web.UI.WebControls.WizardNavigationEventArgs e)
{
     Wizard wizard1 = (Wizard)sender;

     if (wizard1.ActiveStepIndex == wizard1.WizardSteps.IndexOf(StepPersonalDetails))
     {
          // jump to step three
          wizard1.ActiveStepIndex = wizard1.WizardSteps.IndexOf(StepOrderComplete);
     }
}

Complete Sample

Here is a complete sample demonstrating how to take advantage of named WizardSteps with both of the techniques described above.

Markup:

        <asp:Wizard ID="Wizard1" runat="server" 
            onnextbuttonclick="Wizard1_NextButtonClick">
            <WizardSteps>
                <asp:WizardStep ID="StepPersonalDetails" runat="server" Title="Personal Details">
                    <asp:TextBox ID="FirstName" runat="server"></asp:TextBox>
                </asp:WizardStep>
                <asp:WizardStep ID="StepBillingDetails" runat="server" Title="Billing Details">
                </asp:WizardStep>
                <asp:WizardStep ID="StepOrderComplete" runat="server" Title="Order Complete">
                    First Name: <asp:Label ID="FirstNameLabel" runat="server" Text="Unknown"></asp:Label>
                </asp:WizardStep>
            </WizardSteps>
        </asp:Wizard>

Code behind:

    protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
    {
        Wizard w = (Wizard)sender;

        // check if we just completed the first step
        if (e.CurrentStepIndex == w.WizardSteps.IndexOf(StepPersonalDetails))
        {
            // find the first name control
            TextBox firstName = (TextBox)StepPersonalDetails.FindControl("FirstName");

            // check it has a value
            if (!String.IsNullOrEmpty(firstName.Text))
            {
                // find the label on the last page
                Label firstNameLabel = (Label)StepOrderComplete.FindControl("FirstNameLabel");

                // assign the value
                firstNameLabel.Text = firstName.Text;
            }

            // jump to order complete step
            w.ActiveStepIndex = w.WizardSteps.IndexOf(StepOrderComplete);
        }
    }

Downloadable version:

Further Reading

Not a whole lot of further reading for you to today as I have really said everything I wanted to say. Here is one just for completeness:

You will find a few gotcha's on there that aren't related to this article but things that might trip you up in the future.

Using aspnet_regsql via the command line to setup membership roles and profiles only

Posted on: Monday, 24 August 2009 19:29

When you setup the asp.net membership, profile, etc using the aspnet_regsql wizard its pretty much an all or nothing affair - it adds all of the possible features in one go with no option to select which features are added.

When setting up the login systems you only need to add the following feature support: Membership, Role Manager and Profiles. The two remaining features (Personalization and SQL Web event provider) are not needed.

So to only install the features you require you should use the command line version of the tool.

Note: The version listed below (v2.0.50727) is valid for both .net 2.0 and .net 3.5. Without going into the technical details .net 3.5 is a layer on top of 2.0 and the same tool is used for both versions.

If you are working with a version that is newer than 3.5 then check that versions folder for an updated version of this tool as it may be updated in future versions.

Getting the command window open (Windows Vista)

  1. Click the start button then copy and paste this into the search box C:\Windows\Microsoft.NET\Framework\
  2. While holding the shift key down, right click on the folder called "v2.0.50727".
  3. You will see the normal context menu but with an extra option called "Command Window Here"

Getting the command window open (Older versions of Windows)

  1. Click the start button, select Run.
  2. Type "cmd" without the speech marks and press enter
  3. Copy this line of text: cd C:\Windows\Microsoft.NET\Framework\v2.0.50727\
  4. Right click in the command prompt window and choose paste.
  5. Press enter

Setting up the database

Now that you are in the correct location you should type the text below into the command line.

aspnet_regsql.exe -E -S .\SQLEXPRESS -A mrp -d databasename

The -E, -S, -A and -d are all case-sensitive so make sure you type the line exactly!

Replace SQLEXPRESS with the instance name of your database server - if you're using the free version of Sql Server then you will almost certainly be called .\SQLEXPRESS. The .\ bit at the start means "this computer" so if your sql server is on a different server then put the computer name there such as COMPUTER\SQLEXPRESS.

Replace databasename with the name of the database you want to add these features to.

What do the command line parameters mean?

You can get a full explanation of all the options available by typing:

aspnet_regsql -?

Here is a run down of the parameters we used:

-E Auth with windows credentials -S server instance -A services to add (membership, roles, profiles) -d database name

REMEMBER - Parameters are case sensitive

Did it work?

Press enter and you should see this:

Start adding the following features:
Membership
Profile
RoleManager

.......

Finished.

C:\Windows\Microsoft.NET\Framework\v2.0.50727>

A final tip

One thing that I did not realise the first time I used these features is that you can use an existing database when you set these tables up. In my first site that I used these features I ended up with two databases like ClientDatabase and ClientDatabaseAspNetDB because I thought that it would overwrite my data! This is NOT the case! You can specify the same database you are using for all your other development.

Further Reading

kick it Shout it vote it on WebDevVote.com

Setting a default button so your users can press enter to submit your form

Posted on: Thursday, 20 August 2009 20:03

You might have noticed that when you press enter to submit a form in your asp.net page it just refreshes the page instead of submitting as you would expect.

The reason behind this is that asp.net web forms uses the <form> html tag to power the whole postback mechanism. This means that the default behaviour of submitting the form is still occurring but as far as asp.net is concerned you have just submitted its postback form with no commands so it just refreshes.

DefaultButton property

Anyway enough of the back story. The way around this is to set the DefaultButton property. The DefaultButton property was added to the HtmlForm and Panel classes in asp.net 2.0.

You can set this programmatically:

Panel1.DefaultButton = Button1.UniqueID;

or via the code markup:

<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
</asp:Panel>

Per panel

The best use of the DefaultButton property is at the Panel level. The asp.net webforms postback model defines a single html form that all elements of the page are contained in.

If you have for example a login button and a search box in your masterpage, a feedback form in the content area then you have several logical forms contained behind the scenes in a single html form tag. Your users will expect to press enter in the search box and trigger a search. They dont want to see your feedback form validators kicking up a fuss.

By putting each logical form inside an you can set the default button to improve the user experience.

At the form level

As I have already hinted you can also do this at the page level by setting the DefaultButton on the behind-the-scenes page level form tag. As you will already see this is not a good idea for serious projects but you may want to set it in certain circumstances.

If you are in a content page of a masterpage then you will need to do it in the code behind:

this.Form.DefaultButton = this.Button1.UniqueID;

Accessibility

As an added bonus you are also improving the experience of visually impaired or otherwise disabled visitors. By defining the default button you are helping the screen reader software to have a fighting chance at understanding your asp.net page.

Gotcha - Buttons and ImageButtons only (not LinkButtons)

You can't set a <asp:LinkButton> as your DefaultButton. Technically you are supposed to be able use any control which implements IButtonControl but you cannot use the LinkButton. I think this is probably something to do with the fact that LinkButton is a javascript postback while the other buttons render out to proper form elements.

Further Reading

ModalPopupExtender Sys.ArgumentNullException Error

Posted on: Thursday, 13 August 2009 19:30

Are you are seeing this javascript error when you try to run a page with a ModalPopupExtender in it?

Error: Sys.ArgumentNullException: Value cannot be null.
Parameter name: element

Then the fix is probably pretty simple - you have put incorrect ID's in either the OkControlID or CancelControlID attributes.

You don't have to specify the OkControlID or CancelControlID's to use the ModalPopupExtender but if you do and you later rename the control or you simply mistype when setting it up the compiler will not catch this.

The error message could be more helpful but hopefully you will have found this article in your favourite search engine without much trouble!

Here is the official documentation and demo page for this control:

Using a CompareValidator to check input is a valid date

Posted on: Tuesday, 28 July 2009 23:27

The CompareValidator can do more than just compare two controls. You can also compare it against several of the main .net data types such as Date, Integer, Double and Currency.

To do this you would set Operator="DataTypeCheck" and instead of setting the ControlToCompare or ValueToCompare attributes as you normally would you use the Type="Date" (or any of the data types I have listed above).

Here is an example page which illustrates a very simple usage of it:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CompareValidatorExample._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>CompareValidator Date Validation</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            CompareValidator Date Validation</h1>
        <asp:TextBox ID="TextBox1" ValidationGroup="CompareValidatorDateTest" runat="server"></asp:TextBox>
        <asp:Button ID="ButtonSubmit" runat="server" ValidationGroup="CompareValidatorDateTest" Text="Validate Date" /><br />
        <asp:CompareValidator ID="CompareValidator1" Display="dynamic" ControlToValidate="TextBox1"
            Type="Date" Operator="DataTypeCheck" Text="Please enter a valid date" runat="server"
            ValidationGroup="CompareValidatorDateTest" />
    </div>
    </form>
</body>
</html>

The ValidationGroup attribute

Here is another little side-tip; the ValidationGroup attribute that I have spread throughout this code is a great way to avoid confusion later on when you end up with more than one group of form items in a page. If for example you have a login box in the top corner of your page then the ValidationGroup attribute will let you stop the "username required" validator firing when you click the Submit button on this example.

Advanced Validation

The CompareValidator is one of those controls that provides great basic features but quickly runs out of steam when your websites require a little bit more customisation.

Two things to watch out for when using the CompareValidator in this way is that the Date type will take the format of whatever locale the server is running in. As a UK developer I have sometimes found the server running in an American locale when I uploaded the site which flipped the month and day around.

Another caveat is currency validation - no currency symbols allowed!

To get around these limitations you have the option of using regular expressions via the RegularExpressionValidator or going all-out and developing your own validators by inheriting the base class BaseValidator.

Further Reading