Entries Tagged 'ASP.NET' ↓

Make the ASP.NET DataPager SEO friendly?

Currently I’m working on a brand new .NET Framework v4 Project which is using all the new stuff of the new framework version. So I decided to try out the ASP.NET DataPager once more. It was introduced in previous .NET Versions already. However, at the beginning it only provided Javascript/Postback URLs which were not crawlable by searchengines. I mentioned that on Scott Gu’s Blog back in the day, maybe that helped the process to include a “QueryString” Option. You can define the DataPager using this options:

 <asp:DataPager runat="server" ID="DataPager1" PageSize="10" PagedControlID="listViewProducts" QueryStringField="pageNumber">

By using the “QueryStringField” option it at least won’t create uncrawlable Javascript/Postback Links. However, URLs like www.domain.com/?pageNumber=2 still won’t satisfy my needs. The best solution would be to integrate the Datapager with URL Routing. What we need for SEO is Static URLs like www.domain.com/page/2/ and nothing less! I saw a post on codeproject which explains how to extend the Datapager using that kind of searchengine friendly URLs, but it got some annoying limitations:

  • It does not support postback for paging.
  • Only the Next/Previous etc., pager style is supported, not a list of page numbers with direct jump capability.
  • There is no declarative way to display paging information (e.g., “showing items 1-10 from 100, page 1 of 10”).

Due to those facts I unfortunately still need to use my own custom solution. I would love to see a Datapager / URL Routing integration in the future!

Unrecognized attribute ‘targetFramework’

I’m currently playing around with ASP.NET 4.0 Beta 2. There are lots of bugs to fight with, but I’m looking forward to RC1, which should be available soon. It’s coming with a GoLive Licence, so when you put your ASP.NET v4.0 bits on IIS7, don’t forget to set your Application Pool to .NET Framework 4.x. Otherwise you will encounter the mentioned error:

Unrecognized attribute ‘targetFramework’. Note that attribute names are case-sensitive.

Looks like the Website Project Template is not working in Beta2, at least for me, or did they remove it completly? However, so far I wasn’t able to do a pre compilation of my website, I can’t find that feature in Visual Studio 2010.

Still sticking to the DataReader most of the time

Of course this is a big topic. We got LINQ, SubSonic and all the great ORM Mappers now, but when it comes to performance it’s still a critical decision. I never really cared much about that when developing Desktop Applications as you usually don’t have to deal with more than one user at the same time.

We run several Web Applications based on ASP.NET and many of them got more than 10 Million Pageviews per Day. So it is really critical to have a good Database Backend. I just want to talk about the direct Data Access, so I leave out all the caching stuff, that is a topic of its own. I tested the DataReader, the DataSet and some of the popular ORM tools. It’s a standard SELECT Query of 10.000 Database Rows. Here’s what I found out regarding performance:

Obviously the fastest way of accessing Data is still the DataReader with about 20-30ms.
The DataSet raises the bar to about 120ms already.
After that we got LINQ with about 210ms.
There’s ADO.NET with a whopping 400ms.
And the slowest ORM Mapper is unfortunately nHibernate 2.1 with around 580ms.

So if you have to develop the Data Access for big Web Applications you should still stick as much as possible to the DataReader, no matter how (un)comfortable it is, at least for the really critical sections.

By the way: Really big sites like Plenty Of Fish or MySpace which are based on ASP.NET are not using Caching at all. We’re talking about more than 1.2 billion page views/month here. It is not used because as soon as the data is put in the cache it’s already expired. Furthermore no components and just very simple structures including if, then and for loops. Obviously a Load Balancer makes very much sense here. You usually exclude a Database which is being used for searching to save load from the main database.

ORM Mappers are sweet, but it’s still critical to use them if your Website might go through the roof sometime.

Check For Row Existance Only

It’s something you need to take care of in almost every ASP.NET Application. What if you would just like to know if that specific row exists or not, in SQL Server 2005 or SQL Server 2008. For example: Did this user vote on that topic already or not? There are different possibilities for that kind of situation. However, I wanted the fastet solution. If it’s about a query which looks like this:

SELECT somefield FROM sometable WHERE somefield = ‘somevalue’

In this case ‘somevalue’ is used as a literal key value, which also has an index running on it.

So if this query will always return either 0 or 1 rows, then – from an I/O point of view – using SELECT COUNT(*) or using EXISTS will be equally fast.

Why? Unfortunately SQL Server is not shortcutting an index seek if the value is being discovered in an intermediate index level. It also doesn’t shortcut it, if the value is out of range. So we always got a logical read for all index levels.

For the discussion COUNT(*) versus EXISTS, it does not matter whether the index on ‘somefield’ is clustered or not. However, the definition of the clustered index (if present) does affect performance. That’s about testing, you need to check out if the clustered on is faster or not. It mainly depends on the key size of the clustered index, the row size and the size of ‘somefield’. In theory, the fastest situation would be a clustered “and” nonclustered index on ‘somefield’. This will make the nonclustered index on ‘somefield’ the most shallow index possible, so the index seek on thisindex will use the least amount of I/O.

Finally handing over a resultset will be more costly than returning a return value.

404 Error while using ASP.NET URL Routing

I’m heavily using the new ASP.NET URL Routing feature introduced in .NET Framework 3.5 SP1 in my new ASP.NET Applications instead of traditional URL Rewriting. I actually wanted to use IIS7 URL Rewriting, but there’s no way to test your rewrite rules if you are using the built-in VS2008 Cassini Webserver for development (yet).

So I’ve set up some sweet URL Routing rules with Webforms and I have to say it works pretty good so far. However, sooner or later I stumbled upon the first problem. I used an UpdatePanel on a webform which went through the URL Routing mechanism. As soon as I hit the postback button I got the following error:

Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the quest on the server. The status code returned from the server was: 404.

Obviously because the form action attribute didn’t supply the full URL and that is the problem. You can fix it by adding this to your Page_Load:

form1.Action = HttpContext.Current.Request.RawUrl;

I just added it into the MasterPage Page_Load as I’m using URL Routing all over the Page. That’ll fix it.

I’ve also seen this:

if (!String.IsNullOrEmpty(Request.ServerVariables["HTTP_X_ORIGINAL_URL"]))
          form1.Action = Request.ServerVariables["HTTP_X_ORIGINAL_URL"];

However, that snippet doesn’t work for me, I actually don’t know why. If that’s the case for you, too, just use the RawURL snippet above (without an if block).

New .NET Logo

I just stumbled upon the new .NET Logo which will be replacing the old and rusty 8 years old .NET Logo. The new one looks way more professional.

Old .NET Framework Logo:
Old .NET Framework Logo

New .NET Framework Logo:
New .NET Framework Logo

Side note: There is a pretty interesting discussion going on about the Amazon EC3 W2K3 topic, if you didn’t check out the thread at the AWS forum yet you should have a look at it, check my previous blog post here.

Amazon launches Windows.. BUT

Yesterday Amazon launched a new EC2 Version including support for Windows and SQL Server.

Unfortunately it only runs Windows 2003 Server and SQL Server 2005. Now that we are all happy about Windows 2008, the new IIS7, the new URL Rewriting features and so on.

This really is a pity. I’d really like to use Amazon EC2, but I don’t want to take two steps back in development. Once you worked with IIS7 you don’t want to switch back to the old and clumsy IIS6. Especially URL Rewriting is so nice with IIS7.

There is a thread running on the EC2 Forum, but until now noone from Amazon replied. If you’re registered there you might want to drop a reply, too: http://developer.amazonwebservices.com/connect/thread.jspa?threadID=25660.


Thanks for all of your feedback. Our intention is to support the widest variety of options for our customers that we can. We are already working to support Windows 2008 in EC2, and anticipate being able to offer it publicly in the early part of next year.

C# CSV Import

An old topic, I agree. Unfortunately we still can’t forget about CSV files and I see so many questions popping up on forums and especially on my blog related to this topic. Not every company features APIs or XML files yet, so it’s always nice to be comfortable with CSV Readers or Libraries.

First of all: Don’t write your own CSV Parser! No matter if it’s a C# CSV Import or VB.NET. There are so many libraries, frameworks, etc. – you really don’t have to reinvent the wheel once again. It’s not just about using String.Split(“,”), you need to care for much more nasty stuff. Fortunately other people already went through the headaches for you!

So what to do? Use FileHelpers Library 2.0! Instead of calling array items by writing myarray[3] you can even use e.g. mycart.ID now, isn’t that beautiful? Here’s a little code example:

FileHelperEngine engine = new FileHelperEngine(typeof(AdRow));
    AdRow[] res = engine.ReadFile(filename) as AdRow[];       
    foreach (AdRow ar in res)
        Response.Write(ar.CartItem + "<br />");                          

It won’t get easier than that. I use it in several ASP.NET Projects and best of all: It’s free! Check it out and thanks to Marcos for creating it: FileHelpers 2.0. You will find tons of examples for reading and writing CSV Files.

URL Rewriting with IIS7

Finally Microsoft released the long anticipated IIS7 URL Rewrite Module. It really was about time! The key features look promising:

  • Rules-based URL rewriting engine
  • Regular expression pattern matching
  • Wildcard pattern matching
  • Global and distributed rewrite rules
  • Access to server variables and http headers
  • Various rule actions
  • Rewrite maps
  • UI for managing rewrite rules
  • GUI tool for importing of mod_rewrite rules

Quite comfortable that they even integrated a GUI Tool for importing Apache2 mod_rewrite rules. I’m not sure yet how strong URL Routing is, which first came up with the MVC CTPs and is now available for ASP.NET, too – I didn’t test it yet. For now I will give the new IIS7 Module a first shot as my current projects use URL Rewriting already and I think it’ll be easier to port my existing third-party URL Rewrite Engine to the new IIS7 one. I plan on not touching URL Routing until it reached the final status.

Get it here: IIS7 – using url rewrite module.

SubSonic 2.1 Beta released

Just in case you never heard about SubSonic yet, it’s a kickass DAL and I use it for a lot of my projects. Currently it supports SQL Server 2000 or 2005, MySQL and or Oracle (with SQLLite, SQLCE). They also offer a nice Starter-Kit which comes pre-wired with SubSonic, Membership, AJAX, Useful Utilities, and the FCK Editor. It’s based on the .NET 2.0 Framework but it’s automatically being converted by Visual Studio 2008 in case you use v3.5 already (which I strongly recommend).

With v2.1 they shipped a new Query Tool which is now fully capable of creating more complex queries, for example:

  Northwind.CustomerCollection customersByCategory = new Select()
        .InnerJoin(Northwind.OrderDetail.OrderIDColumn, Northwind.Order.OrderIDColumn)
        .InnerJoin(Northwind.Product.ProductIDColumn, Northwind.OrderDetail.ProductIDColumn)

Read more about the new version here. Check it out, I don’t want to miss it anymore ;).

WebForm_InitCallback is not defined

This error eventually pops up, if you use the AjaxControlToolkit Rating Control. The Rating Control just doesn’t work, nothing happens when you click on it or hover over it. You find a couple of threads about it in Google but none of them helped me. I completly rewrote my web.config, removed all HttpModules, checked my Rewrite Logic for possible .axd lockups and nothing helped. That’s the exact error:

WebForm_InitCallback is not defined
Line 226

Line 226 says WebForm_InitCallback();Sys.Application.initialize();.

After wasting about 4 hours I checked out the CSS definitions which are being used by the Rating Control:


I checked the path to the images set in those 3 CSS definitions and noticed that waitRatingStar was pointing to an invalid path – a non existing image. After fixing that path the error was gone!

Like so many times a trivial fault can cost you lots of time – and the error which is being thrown by this fault unfortunately really doesn’t point you into the direction of a missing image. Hopefully this saves someone else searching time on this ;).

Codeparser – implenting custom BB Codes the easy way

*** NOTE – The author discontinued this tool ***

BBCodes are well known through forum communities and is the abbreviation for Bulletin Board Code. The tags are usually indicated by rectangular brackets surrounding a keyword, the use of it is to make text formatting possible without having to write HTML. It’s safer, comfortable and easy to implent.

Every tag is being translated into markup language that web browsers understand, this is where Codeparser.NET joins the game:

codeparser.net is a free .NET based and highly configurable parser for BBCode. Since it is a component, it can be integrated with Windows as well as with web applications and web services.

It’s pretty easy to implent and you will find some pre-made examples for parsing Smilies, Lists, Links, Code and much more. Alternative replacements, syntax highlighting, invalid tag configuration, expression replacements, things you don’t want to miss when dealing with BBCodes. I recently used it for two ASP.NET Web Applications, it’s pretty straight forward. Define some rules, save them as parser.xml, create the parser object and just starting parsing:


If you use the dll for communities there’s just one thing to look after, people forget closing specific tags sometimes which will lead to an exception at the moment. One of the developer, Golo Roden, already told me that they are working on a better solution for this in a future version, for now just use a try/catch block if you deal with user input and do not validate the proper tag closings yourself:

    protected string ParseText(string txt)
            return parser.Parse(txt);
            return txt;

Here is a example of a parser.xml which is parsing Links and text formattings:

<?xml version="1.0" encoding="utf-8" ?>
    <throwExceptionOnInvalidTag value="False" />
    <tag name="url" replacement="&lt;a href=&quot;{1}&quot;&gt;{0}&lt;/a&gt;"
     alternativeReplacement="&lt;a href=&quot;{0}&quot;&gt;{0}&lt;/a&gt;" />
    <tag name="mail" replacement="&lt;a href=&quot;mailto:{1}&quot;&gt;{0}&lt;/a&gt;" />
    <tag name="email" replacement="&lt;a href=&quot;mailto:{1}&quot;&gt;{0}&lt;/a&gt;" />
    <tag name="b" replacement="&lt;span style=&quot;font-weight:bold;&quot;&gt;{0}&lt;/span&gt;" />
    <tag name="i" replacement="&lt;span style=&quot;font-style:italic;&quot;&gt;{0}&lt;/span&gt;" />
    <tag name="u" replacement="&lt;span style=&quot;text-decoration:underline;&quot;&gt;{0}&lt;/span&gt;" />
    <tag name="quote" replacement="&lt;table border=&quot;0&quot; cellpadding=&quot;8&quot; cellspacing=&quot;0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;alt2&quot; style=&quot;border: 1px inset ;&quot;&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;" />

I didn’t face any other problems after running it for about one month now, good job and I’m happy to recommend it to you guys! Head over to the -removed- homepage for more.

Grafiti CMS – a Major ASP.NET Attack on WordPress

PLEASE NOTE: This article is from 2007. Unfortunately Telligent didn’t manage it to turn this into an ASP.NET WordPress Killer.

Just released: Telligent (Creators of CommunityServer) Graffiti CMS – Beta 1, and believe me or not but I was able to set it up in about 20 seconds! This even beats the famous WordPress 5 Minutes installation. I installed it using an Access Database which is included containing some sample data. For small sites this works great, for bigger sites you want to use the SQL Server as datastorage.

The interface is pretty simple and fast, nevertheless, you probably notice some similarities to WordPress ;). It can be used for blogging, smaller content websites or even bigger projects are imaginable.

This could become the new ASP.NET WordPress.. or even more! With the power of ASP.NET it has great potential. It even has SEO friendly URLs included, out of the box of course! The functionality for tagging, categories, plugins, themes and all the stuff you need for starting through are also included.

As far as I know there will be two versions, one free version which runs on Access and one commercial version which runs on SQL Server.

Check it out, it’s really worth a try! I included some screenshots at the end of this post.

FYI: This CMS has been killed.

Grafiti Home Grafiti Site Options Grafiti Themes Grafiti Write Grafiti Write Options Grafiti Write Settings

ASP.NET Deployment – new WDP for VS2008 released

Microsoft just released the Customer Technology Preview (CTP) of Web Deployment Projects for Visual Studio 2008. It contains all the features that VS 2005 WDP release has and in addition has few other enhancements.

For example it only deletes the existing web now if the build succeeds, this will pretend breaking running IIS Applications if you used to deploy directly into the specific IIS Application folder. Additionally you can automatically create virtual Folders in IIS or replace existing ones – this works for IIS6 and IIS7.

Also nice to know is, that aspnet_merge is being automatically installed now when you install Visual Studio 2008. It’s placed in “%Program Files%\Microsoft SDKs\Windows\v6.0A\bin and of course WDP depends on it if you use the merge feature.

Get the December CTP 2007 here: VS 2008 WDP December CTP 2007.

There is no Unicode by order mark. Cannot switch to Unicode.

You were using LINQ and Visual Studio 2008 Beta 2? Switched to Visual Studio 2008 RTM and out of nowhere this error pops up? Lucky you, this one will be pretty easy to fix:

  1. Open up your DBML File.
  2. In the first line, switch the encoding from utf-16 to utf-8.

That’s it once again! I hope you enjoyed another RTM quick fix .. 😉