Category Archives: 2670

C# 5.0 Async/Await Demo Code

I’ve published the sample code I use to demonstrate the use of async/await in C# 5.0. You can find it here.

Projects

PauloMorgado.AyncDemo.WebServer

This project is a simple web server implemented as a console application using Microsoft ASP.NET Web API self hosting and serves an image (with a delay) that is accessed by the other projects.

This project has a dependency on Json.NET due to the fact the the Microsoft ASP.NET Web API hosting has a dependency on Json.NET.

The application must be run on a command prompt with administrative privileges or a urlacl must be added to allow the use of the following command:

netsh http add urlacl url=http://+:9090/ user=machine\username


To remove the urlacl, just use the following command:



netsh http delete urlacl url=http://+:9090/


PauloMorgado.AsyncDemo.WindowsForms



This Windows Forms project contains three regions that must be uncommented one at a time:



Sync with WebClient



This code retrieves the image through a synchronous call using the WebClient class.



Async with WebClient



This code retrieves the image through an asynchronous call using the WebClient class.



Async deadlock



This code how async operations can still deadlock.



Async with HttpClient with cancelation



This code retrieves the image through an asynchronous call with cancelation using the HttpClient class.



PauloMorgado.AsyncDemo.Wpf



This WPF project contains three regions that must be uncommented one at a time:



Sync with WebClient



This code retrieves the image through a synchronous call using the WebClient class.



Async with WebClient



This code retrieves the image through an asynchronous call using the WebClient class.



Async deadlock



This code how async operations can still deadlock.



Async with HttpClient with cancelation



This code retrieves the image through an asynchronous call with cancelation using the HttpClient class.

Patch For ASP.NET Vulnerability Available

Microsoft has published a Security Advisory (2416728) about a security vulnerability in ASP.NET on Saturday, September 18th. This vulnerability exists in all versions of ASP.NET and was publically disclosed late Friday at a security conference.

Scott Guthrie has provided information on workarounds (please see Important: ASP.NET Security Vulnerability and ASP.NET Security Vulnerability) to prevent attackers from using this vulnerability against their ASP.NET applications.

To help with Microsoft’s response to the new padding oracle vulnerability, a new forum was also set up: Security Vulnerability.

Microsoft has now announced the release of an out-of-band security update to address the ASP.NET Security Vulnerability.

Applying the update addresses the ASP.NET Security Vulnerability, and once the update is applied to your system the workarounds Scott has previously blogged about will no longer be required. But, until the update has been installed, those workarounds must be used.

You can learn more about this security update release from this reading the Microsoft Security Response Center Blog Post as well as the official Advance Notification Bulletin.

Important Links:

Is Your ASP.NET Development Server Not Working?

Since Visual Studio 2005, Visual Studio comes with a development web server: the ASP.NET Development Server.

I’ve been using this web server for simple test projects since than with Visual Studio 2005 and Visual Studio 2008 in Windows XP Professional on my work laptop and Windows XP Professional, Windows Vista 64bit Ultimate and Windows 7 64bit Ultimate at my home desktop without any problems (apart the known custom identity problem, that is).

When I received my new work laptop, I installed Windows Vista 64bit Enterprise and Visual Studio 2008 and, for my surprise, the ASP.NET Development Server wasn’t working.

I started looking for differences between the laptop environment and the desktop environment and the most notorious differences were:

System

Laptop

Desktop

SKU

Windows Vista 64bit Enterprise

Windows Vista 64bit Ultimate

Joined to a Domain

Yes

No

Anti-Virus

McAffe

ESET

After asserting that no domain policies were being applied to my laptop and domain user and nothing was being logged by the ant-virus, my suspicions turned to the fact that the laptop was running an Enterprise SKU and the desktop was running an Ultimate SKU. After having problems with other applications I was sure that problem was the Enterprise SKU, but never found a solution to the problem. Because I wasn’t doing any web development at the time, I left it alone.

After upgrading to Windows 7, the problem persisted but, because I wasn’t doing any web development at the time, once again, I left it alone.

Now that I installed Visual Studio 2010 I had to solve this. After searching around forums and blogs that either didn’t offer an answer or offered very complicated workarounds that, sometimes, involved messing with the registry, I came to the conclusion that the solution is, in fact, very simple.

When Windows Vista is installed, hosts file, according to this contains this definition:

127.0.0.1       localhost
::1             localhost


This was not what I had on my laptop hosts file. What I had was this:



#127.0.0.1       localhost
#::1             localhost


I might have changed it myself, but from the amount of people that I found complaining about this problem on Windows Vista, this was probably the way it was.



The installation of Windows 7 leaves the hosts file like this:



#127.0.0.1       localhost
#::1             localhost


And although the ASP.NET Development Server works fine on Windows 7 64bit Ultimate, on Windows 7 64bit Enterprise it needs to be change to this:



127.0.0.1       localhost
::1             localhost


And I suspect it’s the same with Windows Vista 64bit Enterprise.

New Book From Luís Abreu: ASP.NET 4.0 – The Complete Course (Portuguese)

ASP.NET 4.0 – Curso Completo

Thsi book, with several practical examples, presents how to build web applications using ASP.NET 4.0.

Starts by introducing the framework to build pages and controls and gradually introduces all the new features available.

More compact that its previous versions  (part of the content was moved to FCA’s site in the form of apendices), this new book gives emphasis to to the new features in ASP.NET 4.0 and targets both developers new to ASP.NET and developers moving from previous versions of ASP.NET.

This time there’s good new for Brazilian readers. The book will be distributed in Brazil by:

Zamboni Comércio de Livros Ltda.
Av.Parada Pinto, 1476
São Paulo – SP
Telf. / Fax: +55 11 2233-2333
E-mail: zambonibooks@terra.com.br

LINQ Com C#

Our book (LINQ Com C# (Portuguese)) isn’t still distributed in Brazil, but, if you want it, you can always try that distributer.

Web Site Globalization With ASP.NET Routing

For those who don’t know, I have this web site http://PauloMorgado.NET/ that I use both as a web presence besides my blogs and a playfield.

Because I write both in English and Portuguese, I wanted the web site to have both English and Portuguese versions. This is easily accomplished by using ASP.NET Globalization and Localization.

But I wanted to do more than guessing the user’s language form her/his web browser languages. I wanted something like the MSDN and TechNet web sites have where the culture is embedded in the URL which makes it easy for the user to choose in which language she/he wants to see the web site.

With the release of the ASP.NET Routing, this is as easy as writing a custom route handler that sets the culture for the request and returns the requested page handler.

Something like this:

public class GlobalizationRouteHandler : global::System.Web.Routing.IRouteHandler
{
    System.Globalization.CultureInfo culture;
    System.Globalization.CultureInfo uiCulture;

    public GlobalizationRouteHandler(System.Globalization.CultureInfo culture)
        : this(culture, culture)
    {
    }

    public GlobalizationRouteHandler(CultureInfo culture, CultureInfo uiCulture)
    {
        if (culture == null)
        {
            throw new ArgumentNullException("cultureInfo", "cultureInfo is null.");
        }

        if (uiCulture == null)
        {
            throw new ArgumentNullException("uiCulture", "uiCulture is null.");
        }

        this.culture = culture;
        this.uiCulture = uiCulture;
    }

    private GlobalizationRouteHandler()
    {
    }

    #region IRouteHandler Members

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        Thread.CurrentThread.CurrentCulture = this.culture;
        Thread.CurrentThread.CurrentUICulture = this.uiCulture;

        string path = "~/" + (requestContext.RouteData.Values["path"] as string);

        var physicalPath = requestContext.HttpContext.Server.MapPath(path);
        if (System.IO.Directory.Exists(physicalPath))
        {
            path = VirtualPathUtility.Combine(path, "Default.aspx");
        }

        var httpHandler = BuildManager.CreateInstanceFromVirtualPath(path, typeof(IHttpHandler)) as IHttpHandler;

        return httpHandler;
    }

    #endregion
}


And now it’s only a matter of registering the handled cultures:



routes.Add("en", new Route("en/{*path}", new GlobalizationRouteHandler(CultureInfo.GetCultureInfo("en-US"))));
routes.Add("pt", new Route("pt/{*path}", new GlobalizationRouteHandler(CultureInfo.GetCultureInfo("pt-PT"))));

Coupling ASP.NET Session State With Forms Authentication

Today I was talking with João about a way to couple the lifetime of the ASP.NET session state with the lifetime of Forms Authentication ticket.

My idea was to store the session ID in the UserData property of the forms authentication ticket upon logon and retrieve it with a custom session ID manager.

The login code would be something like this:

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
    bool isPersistent = this.Login1.RememberMeSet;
    string username = this.Login1.UserName;
    var ticket = new FormsAuthenticationTicket(
        0,
        username,
        DateTime.Now,
        DateTime.Now.AddMinutes(2),
        isPersistent,
        Guid.NewGuid().ToString("N"));

    // Encrypt the ticket.
    var encryptedTicket = FormsAuthentication.Encrypt(ticket);

    // Create the cookie.
    this.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket));

    // Redirect back to original URL.
    this.Response.Redirect(FormsAuthentication.GetRedirectUrl(username, isPersistent));
}



For the purpose of this test I am using a Guid as the session ID.




The session ID manager will return this session ID when queried by the session state HTTP module:




public class SessionIdManager : global::System.Web.SessionState.ISessionIDManager
{
    #region ISessionIDManager Members

    public string CreateSessionID(HttpContext context)
    {
        return GetDummySessionIdOrRedirectToLoginPage(context);
    }

    public string GetSessionID(HttpContext context)
    {
        return GetSessionIdFromFormsIdentity(context);
    }

    public void Initialize()
    {
    }

    public bool InitializeRequest(HttpContext context, bool suppressAutoDetectRedirect, out bool supportSessionIDReissue)
    {
        supportSessionIDReissue = false;
        return GetSessionIdFromFormsIdentity(context) == null;
    }

    public void RemoveSessionID(HttpContext context)
    {
    }

    public void SaveSessionID(HttpContext context, string id, out bool redirected, out bool cookieAdded)
    {
        redirected = false;
        cookieAdded = false;
    }

    public bool Validate(string id)
    {
        return true;
    }

    #endregion

    private static string GetSessionIdFromFormsIdentity(HttpContext context)
    {
        var identity = context.User != null ? context.User.Identity as FormsIdentity : null;

        if ((identity == null) || (identity.Ticket == null) || string.IsNullOrEmpty(identity.Ticket.UserData))
        {
            return GetDummySessionIdOrRedirectToLoginPage(context);
        }
        else
        {
            return identity.Ticket.UserData;
        }
    }

    private static string GetDummySessionIdOrRedirectToLoginPage(HttpContext context)
    {
        if (context.Request.CurrentExecutionFilePath.Equals(FormsAuthentication.DefaultUrl, StringComparison.OrdinalIgnoreCase)
                        || context.Request.CurrentExecutionFilePath.Equals(FormsAuthentication.LoginUrl, StringComparison.OrdinalIgnoreCase))
        {
            return Guid.NewGuid().ToString("N");
        }
        else
        {
            FormsAuthentication.RedirectToLoginPage();
            return null;
        }
    }
}



NOTE: Although this might work, it’s just an intellectual exercise and wasn’t fully tested.


PowerShell For The .NET Developer

Some time ago I needed to have the validationKey of the machineKey element of an ASP.NET application changed and found out that ASP.NET doesn’t provide a command-line tool (or any other) to do this.

Looking around I found several applications and code samples to do it, but to have a system administrator do this I needed to test and document the application and it was to much work for such task.

I’ve always been a supporter of the idea of PowerShell but I never used it my self. Just because I almost always have Visual Studio open and writing a simple console application is quicker and easier than learning PowerShell.

This time I decide that I would do a PowerShell script instead.

In C# I would have done something like this:

class Program
{
    private static string GenerateKey()
    {
        var buff = new byte[64];
        (new System.Security.Cryptography.RNGCryptoServiceProvider()).GetBytes(buff);
        var sb = new System.Text.StringBuilder();
        foreach (var b in buff)
        {
            sb.AppendFormat("{0:X2}", b);
        }
        return sb.ToString();
    }

    private static void Main(string[] args)
    {
        var path = args[0];
        var config = System.Web.Configuration.WebConfigurationManager.OpenMachineConfiguration(path);
        var systemWeb = config.GetSectionGroup("system.web") as System.Web.Configuration.SystemWebSectionGroup;
        var machineKey = systemWeb.MachineKey;
        machineKey.ValidationKey = GenerateKey();
        config.Save(System.Configuration.ConfigurationSaveMode.Modified);
    }
}


How would it be in PowerShell? As simple as this:



function GenerateKey
{
    [System.Byte[]]$buff = 0..63
    (new-object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($buff)
    $sb = new-object System.Text.StringBuilder(128)
    for($i = 0; ($i -lt $buff.Length); $i++)
    {
        $sb = $sb.AppendFormat("{0:X2}", $buff[$i])
    }
    return $sb.ToString()
}

[System.Reflection.Assembly]::LoadWithPartialName("System.Web")
$config = [System.Web.Configuration.WebConfigurationManager]::OpenWebConfiguration("<path>")
$systemWeb = $config.GetSectionGroup("system.web");
$machineKey = $systemWeb.MachineKey
$machineKey.ValidationKey=GenerateKey
$config.save("Modified")



Wonder how I got from no knowledge of PowerShell to this? Simple. Something that every real .NET developer has and loves: .NET Reflector (with a PowerShell add-in, of course).

Typemock Is Launching The ASP.NET Bundle – Get Free Licenses


Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle – and for the launch they are giving out FREE licenses to bloggers and their readers.


The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator and Ivonna, the ASP.NET Isolator add-on, for a discounted price.


ASP.NET Bundle launch giveaway:
For the ASP.NET Bundle launch Typemock are giving away free licenses to bloggers and their readers.


How do I get the free license?


Are you a blogger, webmaster, or internet columnist? Get your free license by helping Typemock launch their new ASP.NET Bundle, the ultimate ASP.NET unit testing solution.


Post the text below on your blog (as is, with links) and tell them about it . If you are in the first 60 to mail us after posting, your license will be on its way!


If you have an ASP.NET dedicated blog, you’ll get a license automatically (even if more than 60 submit) during the first week of this announcement.


8 bloggers will also get an additional 2 licenses (each) to give away / raffle to their readers or friends.


A few simple requirements:


  1. You must own a website, blog space or internet column, older than 2 months, or get permission from the owner of such a site.
  2. Your post must include the text below (including the links) between *Begin* and *End*.

*Begin*


Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.


Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle – and for the launch will be giving out FREE licenses to bloggers and their readers.


The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.


Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.


The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you’ll get a license automatically (even if more than 60 submit) during the first week of this announcement.


Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.


Go ahead, click the following link for more information on how to get your free license.


*End*


Once you post this in your site, just drop them a line at asp@typemock.com with your name and the post URL to get your free license.


Hurry up – this offer is limited to the first 60 bloggers, or to ASP.NET dedicated bloggers who will post this in the first week.


Make sure to follow their Blog, Site or Twitter for updates on this event.


Unit Test Today! Get Typemock Isolator!