Archive for ASP.NET:
If you get the NullReferenceException error when dealing with web services, it might have to do with AutoEventWireUp being set to false. If you get an error pointing at something like foreach (ServiceDescription description in serviceDescriptions), it might also have to do with AutoEventWireUp set to false.
For instance, if you set AutoEventWireUp to false globally, in Web.Config, your web services will fail.
There's a fix for this though, although it's a bit of a different one.
You just have to locate the DefaultWsdlHelpGenerator.aspx file in C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG (or similar) and add this line to the top:
<%@ Page AutoEventWireup="true" %>
When trying to debug in Visual Studio, you get the following error:
Breakpoint will not currently be hit. No symbols loaded for this document.
After some research, I came up with a solution: delete temporary ASP.NET files. This is how you do it:
- Locate your temporary ASP.NET files and delete them. They're probably located in C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files.
- Rebuild your project and attach to process and you should be fine - the breakpoint should be hit.
If you get the System.IO.IOException: The file exists error, it's probably because your C:/Windows/Temp folder is absolutely full with temporary files. In fact, if you have more than 65535 files in your temp folder, the method GetTempFileName will throw this error.
To resolve this, just remove all temporary files in C:/Windows/Temp. It might take some time, but it will solve the problem.
Here's the stack trace I got:
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
System.IO.Path.GetTempFileName()
When working with ASP.NET, particularly Web Forms up until version 4 of the ASP.NET framework, one might want to think a bit at the naming of the controls used.
I often stumble upon control names looking like this: ChoicesPlaceHolder, MessageLabel and similar. That's clear and decent naming, but it can be improved.
Me and fellow developers have found a simple yet useful and clear naming convention, based on a prefix and a descriptive control name (using Hungarian notation).
This is how it can look instead: phChoices, lblMsg
Naming is particularly important when dealing with nested controls and ContentPlaceHolders. Using better naming, you can improve and reduce this rendered control id:
ctl00_ContentPlaceHolderAllColumns_ContentPlaceHolderAllContentColumns_
ContentPlaceHolderSubNavigation_SubNavigation_RepeaterNavigation_ctl06_
HyperLinkNavigationPageLink
To this id:
ctl00_cphAllColumns_cphAllContentColumns_cphSubNav_SubNav_rptNav_
ctl06_hlNavLnk
Pretty much better, huh? Plus it saves bandwidth.
Also, think twice about where you put runat="server". Is it needed on all controls?
Here's a table with common controls, their prefix and an example naming.
Table: Common ASP.NET Web Forms control and naming
| ASP.NET Control | Prefix | Example |
| Button |
btn |
btnSend |
| CheckBoxList |
cbl |
cblColourCombinations |
| ContentPlaceHolder |
cph |
cphMain |
| DropDownList |
ddl |
ddlNavChoices |
| Label |
lbl |
lblMsg |
| Literal |
lit |
litMsg |
| Panel |
pnl |
pnlLogin |
| PlaceHolder |
ph |
phArticles |
| RadioButtonList |
rbl |
rblPaymentChoices |
| TextBox |
tb |
tbUserName |
Solr is an advanced search coming from Apache's Lucene project. Thanks to SolrNet, a .NET library for Solr, it is quite convenient to use Solr for search in ASP.NET. I'll show you how. (You can also download the sample app right off, if you'd like to)
Install Apache Tomcat and Solr
First of all, make sure you get the latest version of Apache Tomcat and Solr. (I installed Tomcat 7 and Solr 1.4.1 (zip version) as of September 2010.)
Tomcat installation
When installing Tomcat, make sure to remember the port you specify (normal for Solr is 8983). After installation, the Apache Tomcat Properties window should popup. If not, find Configure Tomcat in the start menu and make sure the web server's started. If it's started, you should find the default Tomcat startpage if you browse to http://localhost:8983.
Solr installation
Before you install Solr, stop the Tomcat web server (through the Configure Tomcat window).
When you've downloaded the Solr zip file (make sure it's the zip version!), unzip the archive and find the dist folder. In the dist folder, find the apache-solr-1.4.1.war file and copy it to C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps, renaming it to solr.war.
Now, we also need to create the Solr folder, which will host our Solr configuration files, indexes and so on. I created C:\Solr. You'll also need to copy the contents of the apache-solr-1.4.1\example\solr folder to your newly created Solr folder. When you're done, you should at least have the bin and conf folder.
Finally, we need to tell Tomcat where our Solr folder is located. Open up the Configure Tomcat window, navigate to the Java tab and add this row to Java Options:
-Dsolr.solr.home=c:\solr
It should look like this:

Now, you should first start the web server and then be able to navigate to http://localhost:8983/solr. Installation and basic configuration done!
Quick look at the configuration files
The Solr configuration files are important - you will use them to tell Solr what should be indexed and not. The most important config files are schema.xml and solrconfig.xml. These are located in the C:\Solr\conf folder.
Easier use of Solr with the SolrNet library
SolrNet is a great .NET library for Solr, making it all easier. Download assemblies (and samples) on the SolrNet Google Code page.
Sample ASP.NET app with SolrNet for download
I've developed a sample web application for you, using SolrNet for search in ASP.NET.
Basically, you've got some data in the SQL Server database and use SolrNet to find items in the search index and present all you want from the database.
Here's what you should know:
- Map fields to Solr using attributes (Player.cs in the classes folder)
- This is sample code, not everything might be suitable for a production environment
- You should use Linq to Sql, NHibernate or similar for better scaling and easier data access
Download the sample Solr app
I'd like to thank A. Friedman for his contribution to the Solr and ASP.NET world. Here's his great blog post on Solr and SolrNet.
Code snippets using SolrNet
Here's some code snippets from my Solr app. You can find them in the source code, although I found it being a good idea to post code for a couple of common actions using Solr and SolrNet for search.
Search the index and bind to Repeater:
var search = new DefaultSearcher()
.Search(query, 10, 1);
rptResults.DataSource = search.Result;
rptResults.DataBind();
Re-index all data:
new SolrBaseRepository.Instance<Player>().Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<Player>>();
var players = new PlayerRepository().GetPlayers();
solr.Add(players);
solr.Commit();
Remove from index:
new SolrBaseRepository.Instance<Player>().Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<Player>>();
var specificPlayer = new PlayerRepository().GetPlayer(id);
solr.Delete(specificPlayer);
solr.Commit();
Adding multiple fields to the search index
By standard, Solr lets you index one field only, thanks to the defaultSearchField in schema.xml. It's easy to turn on indexing of multiple fields though, using copyField and an additional field which takes multi values.
What you have to do is to edit schema.xml a bit:
- Setup the fields you want to get indexed, using field.
- Create an additional field called "text", setting its multiValued property to true.
- Use copyField to copy data to this additional field.
- Use this additional field, "text", as the defaultSearchField.
Here's how:
<fields>
<field name="id" type="int" indexed="true" stored="true" required="true" />
<field name="firstname" type="text" indexed="true" stored="false" required="false" />
<field name="lastname" type="text" indexed="true" stored="false" required="false" />
<field name="text" type="text" indexed="true" stored="false" multiValued="true" />
</fields>
<copyField source="firstname" dest="text" />
<copyField source="lastname" dest="text" />
<uniqueKey>id</uniqueKey>
<defaultSearchField>text</defaultSearchField>
<solrQueryParser defaultOperator=uot;AND" />
Debugging Solr
If you encounter any problems with Solr, try this to get it working:
- Turn off elevate.xml handler (comment appropriate lines in solrconfig.xml).
- Case sensitive configuration files - make sure you spell copyField, multiValued etc correctly.
- In solrconfig.xml, make sure you use matching data types to those you've defined in your ASP.NET app.
More Solr
Solr is really powerful and gives you a lot of options. I recommend the Solr Wiki for more information on what actually is possible.
When experiencing Forms Authentication problems in IIS 7, step through this list to make sure everythings in place for Forms Authentication to work:
-
Make sure Forms Authentication is enabled for your website in IIS.
In IIS 7, browse to your website, go to Authentication and make sure Forms Authentication is set to Enabled, like this:

-
Make sure your Web.Config settings looks something like this:
<authentication mode="Forms">
<forms name="aspxFormsAuth" defaultUrl="/Admin"
loginUrl="/Admin/Signin.aspx" protection="All" timeout="90" />
</authentication>
Also, make sure you've not missed the location element:
<location path="admin">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
-
Make sure <modules> in <system.webServer> has the runAllManagedModulesForAllRequests attribute set to true:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
If you got the 403.14 error, this might solve it.
-
Finally, you could try the ordinary iisreset or aspnet_regiis -i command. Make sure you run aspnet_regiis -i on c:\Windows\Microsoft.NET\Framework\v4.0.30319 (or Framework64 if you're running a 64 bit OS).
If you, like me, like to take a deep plunge into Visual Studio debugging, you might've encountered the dreaded Web server process termination error, "The web server process that was being debugged has been terminated by Internet Information Services":

It's very irritating when you're in the middle of a debugging session and it's stopped by the error message above. But - there's a solution! As the error message tells us, you can configure application pool settings in IIS.
This is how to do make sure you'll be able to debug forever:
- Pop up your IIS and find the correct Application Pool
- Right click and choose Advanced Settings
- Below Process Model, find Ping Enabled and make sure it says False:

- Done!
Recently I got this error message, basically telling me I was using an unknown server control. In this case, the ListView control. First thing that comes to mind is if the control itself exists in .NET 3.5, which I was using. Of course it does!
Next thing, I was reading about the solution to this being to completely reinstall .NET Framework 3.5 and .NET Framework 3.5 SP1.
However, I solved it by adding two lines to the Web.Config controls element instead, saving me a lot of time.
Here's the code:
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
Developers often ask me what they can do to improve web standards on their ASP.NET website. There are a number of tricks available and I thought I'd share them with you.
Web.Config magic
First thing to do, is to make sure you've got your Web.Config ready for web standards. This is really simple, as there's only some copy and paste needed. What you want to do is setting xhtmlConformance mode to Strict and make use of browserCaps, both in the system.web section, like this:
<system.web>
<xhtmlConformance mode="Strict" />
<browserCaps>
<case match="W3C_Validator*">
TagWriter = System.Web.UI.HtmlTextWriter
W3CDomVersion = 1.0
</case>
</browserCaps>
....
</system.web>
Use the best .NET controls at your disposal
Countless of times you see .NET controls such as Label and Panel used. Not good, since both render extra HTML output. A label renders an extra span and a Panel renders an extra div, thus affecting the markup of the website - and at worst even breaking the layout.
To the rescue, comes the Literal and PlaceHolder controls. The Literal and PlaceHolder don't render extra markup, and I've never ran into a single problem using them instead.
Also, I like to use the Repeater as often as I can, since I don't always trust third party controls.
Set CSS class on the first listing item
You might have seen class="first" set on the first item in a listing, a number of times. For some, this is a pain to address. However, nothing could be easier than setting a specific CSS class on the first item in a listing. You just have to use the onItemDataBound event on your control. Here's how it might look:
<asp:Repeater ID="rptListing" OnItemDataBound="cssAddons" runat="server">
<ItemTemplate>
<li<asp:Literal ID="cssClass" Visible="false" runat="server"> class="first"</asp:Literal>>
<%#Eval("Item") %>
</li>
</ItemTemplate>
</asp:Repeater>
And the codebehind:
protected void cssAddons(object sender, RepeaterItemEventArgs e)
{
ListItemType type = e.Item.ItemType;
if (type == ListItemType.Item)
{
if (e.Item.ItemIndex == 0)
{
Literal litCssClass = (Literal)e.Item.FindControl("cssClass");
if (litCssClass != null) litCssClass.Visible = true;
}
}
}
You should never be forced to rebuild a project when doing layout changes - that's why one would prefer to use a hidden Literal with the CSS class in the ItemTemplate, and toggling the visibility if it's the first item in a listing.
Customized web controls and CompositeControl
A lot of you are perhaps writing your own web controls. Take note though, inheriting from CompositeControl will make your web controls render an extra span. There's a simple solution to this - just override the Render method in your control, like this, and you're set:
protected override void Render(HtmlTextWriter writer)
{
RenderContents(writer);
}
Some reminders - naming conventions and id's
When it comes to ASP.NET and naming web controls, things can get messy. You want to name your controls as short as possible, without making the name totally meaningless. You particularly want to name your ContentPlaceHolders in a smart way, to avoid id's like this:
ctl00_ContentPlaceHolderContent_ContentPlaceHolderMain_ContentPlaceHolderWidePageWithoutTopImage_ContentPlaceHolderWidePage_ContentPlaceHolderPageContent_ButtonSend
I regularly prefix my web controls, rpt for Repeater, cph for ContentPlaceHolders and so on.
Another problem in ASP.NET Web Forms is id's. If you use runat="server" with a HTML element, the id might look like in the example above. You must avoid this as much as you can, since the altered id's might break the layout. Some might say you should use CSS classes instead, but that's not the way to go. CSS classes aren't meant to be used instead of id's.
In ASP.NET 4, you can actually choose how your id's are rendered, through the ClientIdMode property. A welcome change!
More reading
Remember this is aimed at ASP.NET Web Forms websites, even though part of the tricks can be used in an MVC environment too!
Very often you add a namespace or register an assembly on top of an ASP.NET page, like this:
<%@ Page Language="C#"
AutoEventWireup="True"
CodeBehind="Default.aspx.cs"
Inherits="ProjectName._Default" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="ProjectName.Classes" %>
<%@ Register Assembly="ProjectName" Namespace="ProjectName.Controls" TagPrefix="cc" %>
It works to do once or twice, but when you need to add these namespaces and controls on several different pages, it quickly becomes maintenance hell.
What to do? Use Web.Config instead.
You just have to declare your namespaces and controls in the system.web section, like this:
<system.web>
<pages>
<namespaces>
<add namespace="System.IO" />
<add namespace="ProjectName.Classes" />
</namespaces>
<controls>
<add assembly="ProjectName" namespace="ProjectName.Controls" TagPrefix="PN" />
</controls>
</pages>
</system.web>
Then you will be able to write code like
<%=Toolbox.FormatHtml("....") %>
instead of code like
<%=ProjectName.Classes.Toolbox.FormatHtml("....") %>
A clear improvement. You also won't need to register your controls everywhere to use them.
If you haven't been using this feature (it already came in ASP.NET 2.0!) it's time now!
When you want to put together a number of strings in ASP.NET, the StringBuilder is very handy. Instead of using concatenation, StringBuilder both looks better and improves performance. You can simply append a set of strings to the StringBuilder and return it, like this:
public static string BuildNumbers()
{
StringBuilder sb = new StringBuilder();
sb.Append("<ul>");
for (int i=0; i<500; i++)
{
sb.Append(string.Format("<li>{0}</li>",i));
}
sb.Append("</ul>");
return sb.ToString();
}
However, sometimes you might want to add a web control to the StringBuilder. A bit more tricky.
What you want to do, is to dynamically create the control and use StringWriter together with HtmlTextWriter to render the control inside the StringBuilder. Like this, when you want a LinkButton:
public static string BuildNumbers()
{
StringBuilder sb = new StringBuilder();
sb.Append("<ul>");
for (int i=0; i<500; i++)
{
sb.Append(string.Format("<li>{0}</li>",i));
}
LinkButton lnkBtn = new LinkButton();
lnkBtn.ID = "lnkBtnSubmit";
lnkBtn.Text = "Submit";
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
lnkBtn.RenderControl(tw);
}
}
sb.Append("</ul>");
return sb.ToString();
}
I ran into problems with IIS and ASP.NET after I installed Windows 7, so I thought I'd share my then successful installation process with you.
Clean install of Win 7
First of all, a clean installation of Windows 7 is preferred. I recommend you this because it's otherwise possible you encounter a strange problem which has to do with an upgrade.
A clean installation of Windows 7 will always minimize your problems, plus it's the best start you can get.
First instructions
To minimize upcoming problems, the best thing to do is to install the .NET developer tools before you install anything else.
Make sure you install these tools before anything else and your installation will probably as smooth as anything.
My successful installation process went like this:
- Enable IIS and ASP.NET
- Install SQL Server 2008 + Management Studio (plus ASP.NET MVC)
- Install Visual Studio 2008 + Service Pack 1
Enable IIS and ASP.NET
After the installation of Windows 7 is done, it's first time for IIS and ASP.NET.
You'll have to enable these features through Windows Features which is located under Programs and Features in the Control Panel.
In the Windows Features window, make sure the following options are ticked:
- Internet Information Services (you can also activate IIS 6 under Web Management Tools->IIS 6 Management Compatibility)
- ASP.NET (under World Wide Web Services->Application Development Features)

Use Web Platform Installer to install SQL Server and ASP.NET MVC
Microsoft Web Platform Installer is an awesome tool which will help you install programs, modules and much more related to .NET development. Use Web Platform Installer to install the following:
- SQL Server 2008 + SP1
- SQL Server Management Studio Express
- ASP.NET MVC
Once you've downloaded and installed Web Platform Installer, activate the features under the Web Platform tab:

The installer will automatically download and install all your selected features. Gone are the days with meaningless steps in the SQL Server installation process!
Mind, you can also choose to install a whole lot of other features, but I recommend you to save them for later.
Install Visual Studio 2008 + SP1
Final step is to install Visual Studio 2008 and Service Pack 1.
Once this is done, you should be set and everything should be fine.
If problems occur
If you encounter any problems, it's always a good shot to use your search engine to find anything related to the problem.
I tried a lot of different solutions though and no solution helped me - a clean installation and the above installation flow solved my problems.
If you've been looking for an ASP.NET Twitter module, look no further. I've coded a C# module in order to consume a given Twitter feed. Download the Twitter module for easy use in your own project.
How to use
You can either show the latest Twitter message or any given number of Twitter messages with this module - all you have to do is to point out a Twitter username and the number of messages to show.
Here's a code example on how you can show 5 Twitter messages in a Repeater.
Code-behind:
string userName = "dileno";
List<TwitterFeed> messages = TwitterFeed.Fetch(userName, 5);
if (messages.Count>0)
{
rptTwitterMessages.DataSource = messages;
rptTwitterMessages.DataBind();
}
Repeater in code-front (aspx/ascx):
<asp:Repeater ID="rptTwitterMessages" runat="server">
<HeaderTemplate><ul></HeaderTemplate>
<FooterTemplate></ul></FooterTemplate>
<ItemTemplate><li><%#((TwitterFeed)Container.DataItem).Message %> (<a href="<%#((TwitterFeed)Container.DataItem).Link %>"><%#((TwitterFeed)Container.DataItem).PubDate %></a>)</li></ItemTemplate>
</asp:Repeater>
Download the Twitter module
You can download the C# module with complete source code and code examples:
(zip, 16 kB)
Short instructions for implementation
- Drop the TwitterFeed.cs file into your project.
- Use the code in Default.aspx.cs to customize the Twitter messages.
- Update your appSettings.Config with the key TwitterFeedUrl, which you find in this project's appSettings.Config file.
Using different locales
When I developed this blog, I wanted to use the en-GB locale to be able to present correct formats for dates and numbers.
It is simple to set a specific locale for a whole web application - you just have to add the <globalization> tag under <system.web> in Web.Config and set the culture and uiCulture attributes, like this:
<globalization culture="en-gb" uiCulture="en-gb"/>
So far - so good. Dates and numbers have the correct format and everything looks well - until in comes the database.
I use Sweden's best web hosting provider (according to a study published in 2009) and this means the SQL Server database's collation is set to Finnish_Swedish_CI_AS - as it should be.
Having a website and a database with different locales gives you problems. Trust me.
Out-of-range datetime value
The main problem I ran into was a database insert of an incorrect date - the date I tried to insert obviously had an en-GB format while my database expected a date with sv-SE format. This generated an out-of-range datetime value error.
At first, I tried rewriting the date to a correct format, but quickly realized it was wrong to do so. I ended up with one of the two correct solutions for this problem.
Solutions
The two solutions are:
- Update database collation to match your website locale
- Update SQL query to use parameters
I ended up with the latter one - updating my SQL query to use paremeters instead.
This is also how you want to insert and update your database tables - by using parameters with your command object (unless you use any ORM solution like NHibernate, but that's another blog post).
Here's a SQL query where parameters are used (disregard the lousy error handling):
string strSQL = "INSERT INTO mytable(user,password) VALUES(@user,@password)";
SqlConnection objConn = new SqlConnection(connString);
SqlCommand objCmd = new SqlCommand(strSQL, objConn);
objCmd.Parameters.AddWithValue("@user", "username");
objCmd.Parameters.AddWithValue("@password", "secretpassword");
try
{
objConn.Open();
objCmd.ExecuteNonQuery();
}
catch { }
finally
{
objConn.Close();
}
Conclusion
When developing a database driven website, make sure you know the website's locale and the database's collation. Also, use parameters with your SQL queries, not only when dealing with dates and numbers, but always. You don't know what input might try to sneak into the database otherwise.
The DataBinder.Eval method is often used when you want to bind data to a control's template. What DataBinder.Eval really does is to cast Container.DataItem to its specific type, like this:
<%# DataBinder.Eval(Container.DataItem, "Heading") %>
DataBinder.Eval uses .NET reflection in order to cast Container.DataItem to its specific type. The use of reflection in this method will give you a performance loss.
If performance is of importance in your application or if you know what type Container.DataItem is, it's better to use an explicit cast instead:
<%# ((DbDataRecord)Container.DataItem)["Heading"] %>