# Wednesday, October 15, 2008

With ASP.NET MVC comes a component that is called the routing engine. In ASP.NET MVC it is responsible to assign a controller to an incoming request:

image

From an conceptional view the routing engine consists of two parts:

a) The RouteTable which stores the information which routes are defined

b) The UrlRoutingModule which finds matches to routes on incoming requests.

image

But the routing engine is not limited to MVC in its use. The ASP.NET 3.5 Routing Engine is a powerful instrument for URLRewriting.

Lets have a look how to use routing standalone or with classic ASP.NET (wow, now its already classic! Never dreamed that this would happen so fast... But hey, the .NET platform is nearly ten years old...):

1. First I added the HttpModule to you configuration file:

<httpModules>
  <add 
   name="urlRouting"   
   type="System.Web.Routing.UrlRoutingModule, 
         System.Web.Routing, 
         Version=3.5.0.0, 
         Culture=neutral, 
         PublicKeyToken=31BF3856AD364E35"/>

2. Second I created a routing handler by implementing the IRouteHandler interface which comes from System.Web.Routing. I've put a simple if-else together to route to different pages:

using System.Web;
using System.Web.Compilation;
using System.Web.Routing;

namespace devcoach.Web
{
    public class RoutingPageHandler 
        : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
         var VirtualPath = pathData.VirtualPath.Contains("articles") 
                ? "~/Default.aspx" 
                : "~/Default2.aspx";

            var handler = (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(
                VirtualPath,
                typeof(Page));

            return handler;
        }
    }
}
 

3. Third I registered the routes to the RouteTable from within the Global.asax file:

<%@ Import Namespace="devcoach.Web"%>
<%@ Import Namespace="System.Web.Routing"%>
<%@ Application Language="C#" %>
 
<script runat="server">  
static void RegisterRoutes()
{
    RouteTable.Routes.Add(
        new Route(
            "articles", 
            new RoutingPageHandler()));
            
    RouteTable.Routes.Add(
        new Route(
            "other", 
            new RoutingPageHandler()));        
}
void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes();
} 
 
And here we go already:
image 
 
Basic URLRewiting in a few minutes. Quite neat, eh. Definitely worth a try... 
 
Now listening to: Flobots - Handlebars
Article | ASP.NET | C#
Wednesday, October 15, 2008 1:17:33 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, October 08, 2008

Yep, this is a note to myself :-)

image

Life | Misc
Wednesday, October 08, 2008 3:08:24 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, July 24, 2008

I was searching for a colleague's blog in a "legacy search engine" ;-)... and found a page in Kay Giza's blog which linked "Niel Gräf" to somewhere. It wasn't his blog, It was a linked "Live Search":

http://search.live.com/results.aspx?mkt=de-de&FORM=TOOLBR&q="Nils+Gräf"&FORM=TOOLBR

Kay please don't take it personal... What we see is a foreign page calling into Live without encoding the URL properly. That is what every non technical publisher will do - because they do not know better!

1) Clicking the link will open Live.com and will also show show results - If you have German language settings:

image

But if you click on "Next Page" to brows the results:

image

2) If you have en-US settings you'll get nothing:
image

So what happens here?

1) Live.con does not encode the user input properly when using it to format links - that's bad!

2) Live.com strips out special characters - not nice.

Hope there will be improvement soon :-)

Thursday, July 24, 2008 11:32:39 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, July 15, 2008

In his last post Jeff Atwood summarized really really nice the discussions I have (and had over the last year) while helping customers on large scaling web sites, service-oriented back-ends or just the plain old data access topic.

Thanks Jeff!

All others: Go read!

Tuesday, July 15, 2008 1:14:12 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 10, 2008

I really enjoyed reading Nicks post here.

[...]

  • If you take a group of well-meaning and intelligent engineers,
  • and you give them a process that looks like a normal software development process**, and you train them on it, and they believe that this process works...
  • and you add SOA...
  • you get JaBOWS (Just a Bunch of Web Services).

    [...]

    Many companies out there trying to get on the SOA road fail by believing a tool can lead the way.

    We at devcoach use to say: SOA is not about engineering or architecture. It's a mind setting.

    Therefore a tool can at maximum support you on the long road towards service orientation.

  • Tuesday, June 10, 2008 9:54:40 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
    # Friday, October 19, 2007

    A few days ago a developer at a customer asked me how he could simplify the following code as he identified a pattern: X tries and the error handling.

    public PlanungsGruppenLesenA PlanungsGruppenLesen(
        PlanungsGruppenLesenF param)

    {

        PlanungsGruppenLesenA ret = new PlanungsGruppenLesenA();

     

        if (ret.PlanungsGruppen == null)

        {

            throw new ArgumentNullException("param.PlanungsGruppen");

        }

        int nRetry = 0;

        while (nRetry < DBWerkzeug.MaxWiederholungen)

        {

            try

            {

                using (XXX_POC.POC db =

                    new XXX_POC.POC(
                        DBWerkzeug.GetConnectionString()))

                {

                    var q =

                        from p in db.Stammdaten_Planungsgruppe

                        orderby p.Name.ToLower()

                        select new PlanungsGruppeDM

                        {

                            ID = p.Rowid,

                            Name = p.Name

                        };

                    ret.PlanungsGruppen = q.ToList<PlanungsGruppeDM>();

                }

            }

            catch (ChangeConflictException e)

            {

                nRetry++;

                if (nRetry >= DBWerkzeug.MaxWiederholungen)

                {

                    ret.FehlerText = e.Message;

                    ret.HatFehler = true;

                    throw;

                }

            }

            catch (Exception e)

            {

                ret.FehlerText = e.Message;

                ret.HatFehler = true;

                throw;

            }

        }

        return ret;

    }

    I ended up with this:

    public PlanungsGruppenLesenA PlanungsGruppenLesen(
        PlanungsGruppenLesenF param)

    {

        PlanungsGruppenLesenA ret = new PlanungsGruppenLesenA();

     

        if (ret.PlanungsGruppen == null)

        {

            throw new ArgumentNullException("param.PlanungsGruppen");

        }

        ret.PlanungsGruppen = CatchExceptions<PlanungsGruppeDM>(

            delegate

            {

                using (XXX_POC.POC db =

                    new XXX_POC.POC(
                        DBWerkzeug.GetConnectionString()))

                {

                    var q =

                        from p in db.Stammdaten_Planungsgruppe

                        orderby p.Name.ToLower()

                        select new PlanungsGruppeDM

                        {

                            ID = p.Rowid,

                            Name = p.Name

                        };

                    return q.ToList<PlanungsGruppeDM>();

                }

            },

            ret);           

        return ret;

    }

    What calls the encapsulated X tries and the error handling:

    public delegate List<T> MachMal<T>();

     

    public static List<T> CatchExceptions<T>(MachMal<T> machMichFertig, BasisA ret)

    {

        int nRetry = 0;

        while (nRetry < DBWerkzeug.MaxWiederholungen)

        {

            try

            {

                return machMichFertig();

            }

            catch (ChangeConflictException e)

            {

                nRetry++;

                if (nRetry >= DBWerkzeug.MaxWiederholungen)

                {

                    ret.FehlerText = e.Message;

                    ret.HatFehler = true;

                    throw;

                }

            }

            catch (Exception e)

            {

                ret.FehlerText = e.Message;

                ret.HatFehler = true;

                throw;

            }

        }

        return null;

    }

    But I'm not quite sure If this made stuff really easier ;-)

    C# | Projects
    Friday, October 19, 2007 4:20:12 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
    # Saturday, October 06, 2007

    Pretty helpful while working on WCF services with JSON serialization and AJAX:

    REGEDIT4

    [HKEY_CURRENT_USER\Software\Classes\Mime\Database\Content Type\application/json]
    "CLSID"="{25336920-03F9-11cf-8FD0-00AA00686F13}"
    "Extension"=".json"

    Saturday, October 06, 2007 11:59:18 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
    # Friday, August 31, 2007

    Last friday we (Stephan Oetzel and me - JustCommunity e.V.) held the NRW07 (Germany's biggest software developer and IT professional community conference) in my hometown Wuppertal at die Börse.

    The organization of the event and founding the company devcoach were the reason why it was pretty quite around my blog the last months - so sorry for that.


    Photo by Thomas Freudenberg

    The event was a huge success. we had around 130 people (including speakers) - a great audience from all over the country.

    We hat 4 tracks each filled up with 6 sessions including one dedicated IT-Pro track. We were proud to host Craig Murphy and Oliver Sturm from the UK community again. Thanks for puting the "tech" into the event to Sascha Dietl, Thomas Freudenberg, Marcel Gnoth, Marcus Hoeltkemeier, Mischa Hüschen, Lars Keller, Constantin Klein, Patrick Lauer, Nico Lüdemann, Carsten Möhrke, Craig Murphy, Sebastian Noack, Jens Schaller, Frank Solinske, Oliver Sturm, Roland Weigelt, Thomas Weinert, Michael Willers.

    I also gotta shout out many thanks to our sponsors (especially Christian Schütz from HP, platinum sponsor) and the organization team for making NRW07 happen. Upfront Sylvia Marx (Ping her If you need design stuff like a blog & web design!) who filled the role of our Art Director and managed most of the merchandising stuff (look at the cool shirts!!!).

    The day was filled with amazing things. Night before we had a fabolous geek dinner and Craig podcasted me. In the morning I really enjoied the audience in my talk about SOA on the client and User Interface Patterns. We had tasty Subway catering. And last but not least a unforgettable after event party that ended up early early next morning.

    Craig and Thomas pointed me to facebook.com where a lot of post-NRW07 things (photos etc.) happen - so have a look over there and at Karim's and Kai's blog, saopbox!

    Hope you liked it as well - if you haven't had the chance to make up your own mind... 2008 is near.

    off for vacation

    --Daniel

    Friday, August 31, 2007 10:24:31 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
    # Monday, July 30, 2007

    This morning I downloaded Visual Studio 2008 Beta 2.0 and installed it over the day. As always when a new version is out I'm looking forward to use the new features, but... As always I start missing the Add-Ins I usually use in the old version of the IDE - especially this is the case with ReSharper. So I tried out a few things and finally got it to run.

    1) Add the path to ReSharper's Bin directory to the "Add-In File Paths" (Tools |Options | Environment | Add-in/Macro Security)

    2) Import the following text as *.reg file to your registry (modify path to ReSharper to fit you setup if necessary). 

     

    REGEDIT4

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Menues]
    "{0c6e6407-13fc-4878-869a-c8b4016c57fe}"=",2007,5"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\InstalledProducts\Resharper]
    "Package"="{0c6e6407-13fc-4878-869a-c8b4016c57fe}"
    "UseInterface"=dword:00000001

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages\{0c6e6407-13fc-4878-869a-c8b4016c57fe}]
    @="JetBrains.ReSharper.VS, Version=3.0.471.2, Culture=neutral, PublicKeyToken=null"
    "Class"="JetBrains.ReSharper.VS.Customization.ReSharperPkg"
    "Assembly"="JetBrains.ReSharper.VS"
    "InprocServer32"="C:\\Windows\\system32\\\\mscoree.dll"
    "CodeBase"="C:\\Program Files\\JetBrains\\ReSharper\\v3.0\\vs8.0\\\\Bin\\JetBrains.ReSharper.VS.dll"
    "CompanyName"="JetBrains s.r.o."
    "ProductName"="ReSharper"
    "ProductVersion"="3.0"
    "MinEdition"="standard"
    "ID"=dword:0000029a

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{0024BEE0-BCE9-484F-AFA7-B5647916C26B}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper StackTraceManager"
    "DefaultCaption"="Stack Trace Explorer"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{04612F0D-0B03-4D82-8726-14E6D4143E6C}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper FileStructureView"
    "DefaultCaption"="File Structure"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{1EA986C6-340F-42C8-892E-F5779818D569}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper SearchResultsWindow"
    "DefaultCaption"="Find Results"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{1EA986C6-340F-42C8-892E-F5779818D569}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper SearchResultsWindow"
    "DefaultCaption"="Find Results"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{532DDD98-F6A6-4A76-A84E-4AEA5211F733}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper UnitTestExplorerWindow"
    "DefaultCaption"="Unit Test Explorer"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{7DD08AD7-93B2-491F-A0E8-EE2BB4E78240}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper ErrorsView"
    "DefaultCaption"="Errors"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{AB97F511-6AF2-4D27-B468-E4048600093E}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper HierarchyResultsWindow"
    "DefaultCaption"="Type Hierarchy"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{AE42D903-E5A3-417D-BA25-3CE77B315EED}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper TodoExplorerWindow"
    "DefaultCaption"="To-do Explorer"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{B2BC9916-E3E6-43A8-AD5F-3BDB95F53DB5}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper UnitTestSessionsWindow"
    "DefaultCaption"="Unit Test Sessions"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\ToolWindows\{BE8B4DEB-7D8A-454D-91A8-31C32BE2BD94}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper Resharper.CodeBehindToolwindow"
    "DefaultCaption"="Code Behind"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\ToolWindows\{1067D97D-D956-4E91-849C-07DE62F0E620}]
    @="{0C6E6407-13FC-4878-869A-C8B4016C57FE}"
    "Name"="ReSharper BuildOutput"
    "DefaultCaption"="Build Output"

    Monday, July 30, 2007 8:41:27 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [5]  | 
    # Monday, July 23, 2007

    1 x Intel Core 2 Duo E6850 (4096Kb/2x3Ghz) 64bit (Conroe)
    1 x Arctic Freezer 7 Pro
    4 x 2048MB DDR2
    1 x Chieftec "Bravo-Series" Tower (400W) Black
    3 x HITACHI DeskStar 250GB (SATA II)
    1 x ABIT IN9 32X-MAX WiFi "Beast"
    1 x DVD-RW SATA
    1 x NVIDIA Geforce Club3D 8600GT (512MB)

    Monday, July 23, 2007 8:32:54 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |