# Monday, October 27, 2008

image

The first day of PDC is almost gone. I met my former Boss Clemens Vasters had a nice conversation during lunch with John Lam and "a guy with a blue shirt" that I'm not allow to cite here :-).

image

Micheal Willers, Ron Jacobs and I talked about SOA, Dublin, OSLO and the sometimes hard job trying to explain people the problems they will have in the feature (commonly known as archtecture :-P).

image

I was a bit disappointed by the "ASP.NET 4.0 roadmap" because I expected more "visions" and ideas -  Phil Haack showed mostly stuff that is available today (actually really today on codeplex...).

Monday, October 27, 2008 11:22:20 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, October 20, 2008

In reply to Scott Hanselmann's post on freeing up disc space I'd like to share a batch that I've written some time ago to clear different temp directories for instance before I run a backup. the referenced file "cleanup.txt" just contains the text "yes" (w/o quotes) to automate the cacls command.

 

@Echo off
for /f "tokens=3 delims=\" %%i in ("%USERPROFILE%") do (set user=%%i) 2>&1

@Echo on

del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\WebsiteCache\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\Burn\Burn\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Media Player\Transcoded Files Cache\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Temp\*.*"
rmdir "C:\Users\%user%\AppData\Local\Temp" /S /Q
mkdir "C:\Users\%user%\AppData\Local\Temp"

del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Team Foundation\1.0\Cache\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\Temporary Internet Files\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\Temporary Internet Files\WebTempDir\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\WER\ReportArchive\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Windows\WER\ReportQueue\*.*"
del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS\*.*"

del /F /S /Q "C:\Users\%user%\AppData\Local\Microsoft\Media Player\Transcoded Files Cache\*.*"
rmdir "C:\Users\%user%\AppData\Local\Microsoft\Media Player\Transcoded Files Cache" /S /Q

del /F /S /Q "C:\Users\%user%\AppData\Roaming\Microsoft\Web Server Extensions\Cache\*.*"

rmdir  "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" /S /Q
mkdir "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files"
cacls "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" /g "System":F < "D:\Tools\cleanup.txt"
cacls "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" /e /g "Administrators":F < "D:\Tools\cleanup.txt"
cacls "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" /e /g "Network Service":F < "D:\Tools\cleanup.txt"
cacls "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" /e /g "IISWPG":F < "D:\Tools\cleanup.txt"

del /F /S /Q "C:\Windows\Temp\*.*"
rmdir  "C:\Windows\Temp" /S /Q
mkdir "C:\Windows\Temp"
cacls "C:\Windows\Temp" /g "System":F < "D:\Tools\cleanup.txt"
cacls "C:\Windows\Temp" /e /g "Users":F < "D:\Tools\cleanup.txt"
cacls "C:\Windows\Temp" /e /g "Administrators":F < "D:\Tools\cleanup.txt"
cacls "C:\Windows\Temp" /e /g "Network Service":F < "D:\Tools\cleanup.txt"

del /F /S /Q "C:\Windows\Downloaded Program Files\*.*"

rmdir  "C:\MSOCache" /S /Q
rmdir "C:\SWSetup" /S /Q

pause

Life | Misc
Monday, October 20, 2008 2:33:20 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, October 18, 2008

What is life without security. In the last posts I told you how to do URLRewriting with the ASP.NET 3.5 RoutingEngine and how to pass query strings to the destination Web Form. In this post I'll add some authorization code to let ASP.NET Authentication mechanisms play well.

The first step is to figure out which authentication mechanism has taken place in the local configuration file. For the case of forms based authentication it would be nice to redirect to the configured login Web Form, for all other authentication mechanisms we can only throw a security exception and set a HTTP status code.

I only wanted this operation to be executed once and therefore I implemented as static and thread safe property with a backing field and a lock object:

private static string s_authenticationType;
private static object s_authenticationTypeLock = new object();
private static string AuthenticationType
{
    get
    {
        if (string.IsNullOrEmpty(s_authenticationType))
        {
            lock (s_authenticationTypeLock)
            {
                if (string.IsNullOrEmpty(s_authenticationType))
                {
                    var authenticationSectionObject =
                        WebConfigurationManager.GetSection(
                        "system.web/authentication");

                    var authenticationSection =
                        authenticationSectionObject
                            as AuthenticationSection;

                    if (authenticationSection != null)
                    {
                        s_authenticationType =
                            authenticationSection.Mode.ToString();
                    }
                }
            }
        }
        return s_authenticationType;
    }
}

 

Now its time to check the authorization on the target Web Form:

if (httpContext != null &&
    !UrlAuthorizationModule.CheckUrlAccessForPrincipal(
        VirtualPath,
        httpContext.User,
        httpContext.Request.HttpMethod))
{
    if (AuthenticationType.
        Equals("forms", StringComparison.OrdinalIgnoreCase))
    {
        VirtualPath = FormsAuthentication.LoginUrl;
        queryString =
            new StringBuilder(
                string.Concat(
                    "?ReturnUrl=",
                    requestContext.HttpContext.Server.UrlEncode(
                        requestContext.HttpContext.Request.RawUrl
                        )));
    }
    else
    {
        throw (new SecurityException());
    }
}

Next I will add a login Web Form to the site and drop a LoginControl to the form:

image

And add some code behind:

using System;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class login : Page
{
    protected void OnLoggingIn(object sender, LoginCancelEventArgs e)
    {
        //TODO: add some auth logic or use membership...
        FormsAuthentication.RedirectFromLoginPage(
            "lennybacon", 
            false);
    }
}

Authorization requires an authorization and therefore I enable ASP.NET forms based authentication that also is compatible to ASP.NET Membership in the configuration file:

<configuration>
  <system.web>
    <authentication mode="Forms"/>
...

 

I can configure the authorization settings for the destination Web Forms are also in the web.config file by adding location sections:

<configuration>
  ...
  <location path="Default2.aspx">
    <system.web>
      <authorization>
        <deny users="?"/>
      </authorization>
    </system.web>
  </location>
...

 

Running the web site and clicking the link to the route (/other) that targets the Default2.aspx results in showing up the login.aspx.

image

Notice that the address bar has not changed - the usual roundtrip for redirecting to the loginURL is also "rewritten" inside of ASP.NET.

 

This way the security is easily plugged into the RoutingHandler class - Cool stuff! 

Article | ASP.NET | C#
Saturday, October 18, 2008 7:56:33 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, October 16, 2008

In the last post I showed how to use the ASP.NET 3.5 Routing Engine for URLRewriting purposes. I want to go further in this post by adding the ability to add variables into a route path and forward and append query string variables to the destination Web Form request.

A route can contain one or more variables expressed by its {name}.

 
RouteTable.Routes.Add( 
    new Route(
        "articles/{id}", 
        new devcoach.Web.RoutingPageHandler()));

 

Inside of the RoutingHandler we can iterate through the variables by accessing them by the RouteData property on the parameter passing the RequestContext:

 

var queryString = new StringBuilder("?");
foreach (var aux in requestContext.RouteData.Values)
{
    queryString.Append(
        requestContext.HttpContext.Server.UrlEncode(aux.Key));
    queryString.Append("=");
    queryString.Append(
        requestContext.HttpContext.Server.UrlEncode(
            aux.Value.ToString()));
    queryString.Append("&");
}
queryString.Remove(queryString.Length - 1, 1);

 

The problem now is that the method CreateInstanceFromVirtualPath of the BuildManager class does not allow us to pass for instance a query string as a parameter (I had this discussion recently with Holger at the speakers party of the Basta! confrence):

 

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

 

Passing URL Parameters (a query string) to the instance of the page created from its virtual path we can use the good old RewitePath method (which should be familiar for everyone who has rewritten URLs with ASP.NET 2.0):

 

HttpContext.Current.RewritePath(
    string.Concat(
        VirtualPath,
        queryString));

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

 

It feels a bit strange to use the old fashioned way of rewriting URLs just to pass a query string, but the routing handler will stay in control of the request and only the context  variables gets modified.

 Listening to: Elbow - Grounds for Divorce

Article | ASP.NET | C#
Thursday, October 16, 2008 4:26:29 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# 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 12:17:33 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  |