<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The World is mine &#187; Asp.net</title>
	<atom:link href="http://grozeille.com/tag/aspnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://grozeille.com</link>
	<description>Just another Wordpress.com weblog</description>
	<lastBuildDate>Sat, 07 Jan 2012 12:00:31 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='grozeille.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The World is mine &#187; Asp.net</title>
		<link>http://grozeille.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://grozeille.com/osd.xml" title="The World is mine" />
	<atom:link rel='hub' href='http://grozeille.com/?pushpress=hub'/>
		<item>
		<title>100% de couverture de test avec ASP.Net</title>
		<link>http://grozeille.com/2010/10/25/100-de-couverture-de-test-avec-asp-net/</link>
		<comments>http://grozeille.com/2010/10/25/100-de-couverture-de-test-avec-asp-net/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 21:48:02 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[coverage]]></category>
		<category><![CDATA[NUnit]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[SpecFlow]]></category>

		<guid isPermaLink="false">http://grozeille.com/?p=470</guid>
		<description><![CDATA[Dans ma quête de la couverture de test absolue, j&#8217;ai décider de tester mon application ASP.Net avec des tests fonctionnels. Pour cela, j&#8217;utilise le combo: Specflow+Selenium. En terme de rédaction du test, cela donne ça: Grâce à Specflow, je peux donc rédiger mon scénario en anglais, très lisible par l&#8217;utilisateur qui va pouvoir ainsi exprimer [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=470&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Dans ma quête de la couverture de test absolue, j&#8217;ai décider de tester mon application ASP.Net avec des tests fonctionnels.<br />
Pour cela, j&#8217;utilise le combo: <a href="http://specflow.org/">Specflow</a>+<a href="http://seleniumhq.org/projects/remote-control/">Selenium</a>.</p>
<p>En terme de rédaction du test, cela donne ça:</p>
<p><pre class="brush: plain;">
﻿Feature: Test with ASP.net
	In order to get test coverage of my ASP.Net Application
	As a developper
	I want to run an embeded ASP.Net server in my NUnit test

@selenium
Scenario: Say Hello to Michel
	Given I'm on the default page
	When I enter the name &quot;Michel&quot;
	And I click the &quot;SayHello&quot; button
	Then the message is &quot;Hello Michel&quot;
</pre></p>
<p>Grâce à Specflow, je peux donc rédiger mon scénario en anglais, très lisible par l&#8217;utilisateur qui va pouvoir ainsi exprimer son besoin.<br />
Ces phrases sont ensuite couplées à des méthodes C# qui effectuent une partie du test. Exemple:</p>
<p><pre class="brush: csharp;">
[When(&quot;I click the \&quot;SayHello\&quot; button&quot;)]
public void IClickTheSayHelloButton()
{
    selenium.Click(&quot;SayHelloButton&quot;);
    selenium.WaitForPageToLoad((1 * 60 * 1000).ToString());
}
</pre></p>
<p>On remarque ici que j&#8217;utilise Selenium pour simuler le scénario et effectuer un click sur un bouton de la page.</p>
<p>Petite astuce: le scénario est &#8220;tagué&#8221; @selenium. Grâce à ce tag, je peux indiquer qu&#8217;il faut initialiser Selenium à chaque début de scénario tagué ainsi.</p>
<p><pre class="brush: csharp;">
[BeforeScenario(&quot;selenium&quot;)]
public void BeforeScenario()
{
    var firefoxPath = Path.GetFullPath(
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @&quot;..\..\..\Libs\Firefox\firefox.exe&quot;));
    var selenium = new DefaultSelenium(&quot;localhost&quot;,
                                       4444,
                                       @&quot;*firefox &quot; + firefoxPath,
                                       &quot;http://localhost:8123&quot;);
    ScenarioContext.Current[&quot;selenium&quot;] = selenium;
    selenium.Start();
}
</pre></p>
<p>OK, je suis content avec ça, je peux maintenant rédiger des tests fonctionnels lisibles et les automatiser à l&#8217;aide de Selenium.<br />
Mais cela ne me donne pas la couverture du code de mon application .Net qui se trouve hébergée sur un serveur IIS <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Afin d&#8217;avoir la couverture du code de toute l&#8217;application, j&#8217;ai alors décider d&#8217;exécuter l&#8217;application ASP.Net à l&#8217;intérieur du processus du test unitaire!<br />
Afin d&#8217;héberger l&#8217;application ASP.net, j&#8217;utilise pour cela la librairie de Mono: <a href="http://www.mono-project.com/ASP.NET">XSP</a>.<br />
Pour cela, quelques lignes de codes suffisent:</p>
<p><pre class="brush: csharp;">
[BeforeTestRun]
public static void BeforeTestRun()
{
    const int port = 8123;
    string path = Path.GetFullPath(@&quot;..\..\..\MyApp.Web&quot;);
    const string webServerFileName = &quot;Mono.WebServer2.dll&quot;;

    string sourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, webServerFileName);
    string destinationPath = Path.Combine(Path.Combine(path, &quot;bin&quot;), webServerFileName);

    File.Copy(sourcePath, destinationPath, true);

    var websource = new XSPWebSource(IPAddress.Any, port);
    webAppServer = new ApplicationServer(websource);
    webAppServer.AddApplication(&quot;localhost&quot;, port, &quot;/&quot;, path);
    webAppServer.Start(true);
}

[AfterTestRun]
public static void AfterTestRun()
{
    webAppServer.Stop();
}
</pre></p>
<p>Simple non?</p>
<p>Voila alors le résultat:<br />
<a href="http://grozeille.files.wordpress.com/2010/10/coverageaspnet.png"><img class="aligncenter size-medium wp-image-471" title="CoverageASPNet" src="http://grozeille.files.wordpress.com/2010/10/coverageaspnet.png?w=630" alt="" /></a></p>
<p>Afin de pouvoir tester par vous même, vous pouvez télécharger les sources depuis <a href="http://bitbucket.org/grozeille/testwithaspdotnet/src/">http://bitbucket.org/grozeille/testwithaspdotnet/src/</a>, lancer le serveur Selenium à l&#8217;aide de <strong>&#8220;SeleniumServer.bat</strong>&#8220;, lancer les tests avec &#8220;<strong>Test.bat</strong>&#8220;, et voir le rapport de couverture de code avec<strong> Libs\PartCover .NET 2\PartCover.Browser.exe</strong> en ouvrant le fichier <strong>Coverage.Xml</strong>.<br />
Ça, ça rox du poney!<br />
<a href="http://grozeille.files.wordpress.com/2010/10/affiche-mon-petit-poney-le-film-my-little-pony-the-movie-1986-1.jpg"><img class="aligncenter size-medium wp-image-472" title="affiche-Mon-Petit-Poney-le-film-My-Little-Pony-The-Movie-1986-1" src="http://grozeille.files.wordpress.com/2010/10/affiche-mon-petit-poney-le-film-my-little-pony-the-movie-1986-1.jpg?w=233&#038;h=300" alt="" width="233" height="300" /></a></p>
<br /> Tagged: <a href='http://grozeille.com/tag/net/'>.Net</a>, <a href='http://grozeille.com/tag/aspnet/'>Asp.net</a>, <a href='http://grozeille.com/tag/coverage/'>coverage</a>, <a href='http://grozeille.com/tag/nunit/'>NUnit</a>, <a href='http://grozeille.com/tag/selenium/'>Selenium</a>, <a href='http://grozeille.com/tag/specflow/'>SpecFlow</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/470/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=470&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/10/25/100-de-couverture-de-test-avec-asp-net/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/coverageaspnet.png" medium="image">
			<media:title type="html">CoverageASPNet</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/affiche-mon-petit-poney-le-film-my-little-pony-the-movie-1986-1.jpg?w=233" medium="image">
			<media:title type="html">affiche-Mon-Petit-Poney-le-film-My-Little-Pony-The-Movie-1986-1</media:title>
		</media:content>
	</item>
		<item>
		<title>Spring.Net, ASP.Net, Session et multithreadind</title>
		<link>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/</link>
		<comments>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 19:22:00 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[Spring.net]]></category>

		<guid isPermaLink="false">https://grozeille.wordpress.com/?p=452</guid>
		<description><![CDATA[Pour commencer, je vous préviens, ce billet s’adresse à ceux qui savent développer en ASP.Net. Je ne plaisante pas! J’ai vu un trop grand nombre de gens prétendre savoir faire des applications Web sans savoir m’expliquer le protocole HTTP! Donc voici un petit test d’entré: Comment fonctionne un HttpHandler? Pourquoi ne pas utiliser les UpdatePanels? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=452&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Pour commencer, je vous préviens, ce billet s’adresse à ceux qui savent développer en ASP.Net.<br />
Je ne plaisante pas! J’ai vu un trop grand nombre de gens prétendre savoir faire des applications Web sans savoir m’expliquer le protocole HTTP!<br />
Donc voici un petit test d’entré:</p>
<ul>
<li>Comment fonctionne un HttpHandler?</li>
<li>Pourquoi ne pas utiliser les UpdatePanels?</li>
<li>A quoi sert un MembershipProvider et comment s’en servir?</li>
</ul>
<p>Si ces questions vous paressent obscures et que vous êtes plutôt un développeur “glisser-déposer”, alors je vous propose de vous “glisser-déposer” sur un autre blog <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Pour les autres, j’ai un aveu à vous faire: je viens de découvrir qu’il n’est pas possible d’afficher 2 pages ASP.Net en simultané si elles accèdent à la Session.</p>
<p><span id="more-452"></span></p>
<p>J’ai cru que j’étais sous l’effet d’une drogue… mais non, c’était bien vrai.<br />
J’ai alors voulu en avoir le cœur net, et j’ai fouillé de nombreux forums… c’est la que j’ai découvert que d’autres l’on découvert après 5 ans d’expériences en ASP.Net!!!</p>
<p>Certes, on ouvre rarement 2 pages Web d’un même site, mais il est plus fréquent d’avoir 2 appelles Ajax en simultané.<br />
C’est mon cas, car j’aime Ajax, j’aime le Web, et j’utilise une technique “Comet” appelé “Long Pooling”. Cela consiste à faire un appelle Ajax potentiellement infinie, qui va se terminé seulement si le serveur à quelque chose à nous dire. Cela permet d’avoir un système de notification très simple à implémenter.</p>
<p>Pour vulgariser, au lieu d’avoir ça:</p>
<blockquote><p>Client: “Tu veux me dire quelque chose?”<br />
Server: “Non”<br />
Client: “Tu veux me dire quelque chose?”<br />
Server: “Non”<br />
Client: “Tu veux me dire quelque chose?”<br />
Server: “Mais lâche moi sale client!!!”</p></blockquote>
<p>En long polling ça donne ça:</p>
<blockquote><p>Client: “Bon, tu me préviens si t’as un truc à me dire&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230; ouai, j’ai un truc pour toi, un nouveau message”<br />
Client: “OK, je le traite, bon, tu me préviens si t’as un autre truc à me dire&#8230;”</p></blockquote>
<p>Et sinon, en C# ça donne ça:</p>
<p><pre class="brush: csharp;">
public string LongAjaxCall()
{
    string result = null

    while(result == null)
    {
        lock(this.notificationList)
        {
            if(notificationList.Count &gt; 0)
            {
                result = new JavaScriptSerializer().Serialize(this.notificationList.ToArray());
                this.notificationList.Clear();
            }
        }
        if(result == null)
            Thread.Sleep(500);
    }
}
</pre></p>
<p>En général, le serveur n’a pas les mêmes choses à dire aux différents clients, c’est pourquoi on utilise la Session. Mais cette dernière est verrouillée par le long pooling, l’utilisateur ne sera alors pas en mesure d’ouvrir une nouvelle page si l’appelle Ajax ne se termine pas, ce qui est plutôt fâcheux.</p>
<h2>Et Spring.Net dans tout ça?</h2>
<p>J’utilise massivement Spring.net, pas seulement pour l’IOC, mais pour bien d’autres choses que ce merveilleux framework offre.<br />
Dans le cadre d’une application Web, il est possible d’avoir un “scope” pour les instances des objets:</p>
<ul>
<li><strong>application</strong>: un singleton pour toute l’application Web</li>
<li><strong>session</strong>: l’instance n’existe que dans le cadre d’une session ASP.Net</li>
<li><strong>request</strong>: l’instance n’existe pour pour la duré de la requête HTTP</li>
</ul>
<p>J’utilise pas mal le scope “Session”, afin d’instancier des “contrôleurs” différents pour chaque utilisateurs. Je peux ainsi conserver un état à l’aide des membres de mes contrôleurs (ou conserver une connexion SQL, etc.).</p>
<p>Je vous propose alors de jeter un œil à mon exemple afin de comprendre mon problème: <a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src">http://bitbucket.org/grozeille/testaspsessionmultithread/src</a><br />
Cette solution contient un premier exemple “<a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Bad/">TestASPSessionMultithread.Bad</a>” qui illustre mon problème.</p>
<p>L’exemple est simple:<br />
Vous avez une première page “<em>Default.aspx</em>” qui permet d’ajouter une “<em>string</em>” à une liste à l’aide du button “<em>add</em>” qui effectuera un appelle Ajax.<br />
Vous pouvez alors ensuite déclencher un “<em>long pooling</em>” à partir du boutton “<em>long polling</em>” qui va demander au serveur de renvoyer les nouveaux items.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/image.png"></a><a href="http://grozeille.files.wordpress.com/2010/10/longpooling01.png"><img class="aligncenter size-medium wp-image-462" style="border:1px solid black;" title="LongPooling01" src="http://grozeille.files.wordpress.com/2010/10/longpooling01.png?w=300&#038;h=231" alt="" width="300" height="231" /></a></p>
<p>Dans cet ordre, tout va bien. Par contre, si vous faite un “<em>long pooling</em>” en premier, le boutton “<em>add</em>” restera bloqué et il sera donc impossible d’ajouter un nouvel item.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/longpooling02.png"><img class="aligncenter size-medium wp-image-463" style="border:1px solid black;" title="LongPooling02" src="http://grozeille.files.wordpress.com/2010/10/longpooling02.png?w=300&#038;h=260" alt="" width="300" height="260" /></a></p>
<p>De même, vous pouvez tester aussi la page “<em>Other.aspx</em>” qui simule un lourd traitement qui prend 5 secondes. Quand vous essayer d’ouvrir la page “<em>Other</em>” et que vous tentez de recharger la page “<em>Default</em>” en parallèle, cette dernière va attendre la fin du chargement de la page “<em>Other</em>”.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/longpooling03.png"><img class="aligncenter size-medium wp-image-464" style="border:1px solid black;" title="LongPooling03" src="http://grozeille.files.wordpress.com/2010/10/longpooling03.png?w=300&#038;h=140" alt="" width="300" height="140" /></a></p>
<p>A noter aussi que j’affiche le <em>“creation time</em>” des différents contrôleurs. Puisque Spring.Net permet d’avoir du <span style="text-decoration:underline;">LazyLoad</span>, on voit que le <em>OtherController </em>est créé après le <em>DefaultController</em>.</p>
<p>Si vous regardez le code en détail, vous pouvez voir que je gère les appelles Ajax à l’aide d’un <em>HttpHandler </em>custom.<br />
Je pense que le code est suffisamment bien commenté pour le comprendre, et pour ceux qui ont la flemme de récupérer le source depuis BitBucket, voici l’extrait:</p>
<p><pre class="brush: csharp;">
public class BadAjaxHttpHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        // get the name of the controller and the action from the URL
        var action = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
        var controller = context.Request.Url.Segments[context.Request.Url.Segments.Length - 2]
            .Replace(&quot;.ajax&quot;, string.Empty)
            .Replace(&quot;/&quot;, string.Empty);

        // get the instance of the controller thanks to its name
        var instance = ContextRegistry.GetContext().GetObject(controller);

        // get the method of the controller thanks to reflection
        var method = instance.GetType().GetMethod(action, BindingFlags.Instance | BindingFlags.Public);
        var args = new List();
        foreach (var item in method.GetParameters())
        {
            args.Add(TypeDescriptor.GetConverter(item.ParameterType).ConvertFromString(context.Request.Params[item.Name]));
        }

        // invoke the method of the controller
        var result = method.Invoke(instance, args.ToArray());

        // return the JSON value of the method result
        context.Response.Write(new JavaScriptSerializer().Serialize(result));
        context.Response.StatusCode = 200;
        context.Response.End();
</pre></p>
<p>On remarque que pour accéder à la session nous avons ici besoin d’implémenter l’interface “<em>IRequiresSessionState</em>”, mais la aussi, comme c’est en lecture/écriture, cela verrouille la session le temps de la requête HTTP.</p>
<h2>Comment résoudre le problème?</h2>
<p>La solution est dans le projet “<a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Good.Unsecured/">02-TestASPSessionMultithread.Good.Unsecured</a>”.</p>
<p>Pourquoi “Unsecured” ? On verra ça plus tard.</p>
<p>La solution est simple, il suffit d’accéder à la Session en “lecture seule”.<br />
En effet, il peut être problématique d’ajouter une même clé depuis 2 thread concurrents, mais une fois que la clé est créée, c’est à vous de gérer la concurrence de la valeur.</p>
<p>Exemple:</p>
<p><pre class="brush: csharp;">
Session[“list”] = new List(); // problème de concurrence, donc session verrouillée

((List)Session[“list”]).Add(“toto”); // ce cas est une lecture seule de la session, mais à vous de gérer la concurrence pour la collection
</pre></p>
<p>Comme Spring.Net est en quelque sorte une “grosse collection d’instance”, et que Sprint.net utilise une seule clé “spring.object”, cela s’applique aussi <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Par défaut, les pages sont en accès Write à la session. Pour changer cela, il faut ajouter une option dans l’ASPX:</p>
<p><pre class="brush: xml;">
&lt;%@ Page EnableSessionState=&quot;ReadOnly&quot;  %&gt;
</pre></p>
<p>Il a fallut un petit changement dans le HttpHandler Ajax aussi:</p>
<p><pre class="brush: csharp;">
public class AjaxHttpHandler : IHttpHandler, IReadOnlySessionState
</pre></p>
<p>Cette nouvelle interface “<em>IReadOnlySessionState</em>” parle d’elle même <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Et voila! C’est tout! Ca marche, plus de problème de concurrence!<br />
Enfin… non ce n’est pas tout, on a un petit problème, c’est que Sprint.net ne pourra plus jamais initialiser la session sans accès en écriture <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /><br />
Il faut donc trouver un “bootstrap” qui accède à la session en écriture juste le temps de créer le contexte Spring.Net.</p>
<p>L’astuce est donc de faire une redirection vers un HttpHandler particulier “<em>SpringSessionHttpHandler</em>” si la session est nouvelle. Il peut alors accèder à la session en écriture grâce à l’interface “IRequiresSessionState” pour initialiser le contexte et rediriger vers la page d’origine.</p>
<p>Ceci est fait lors du “<em>OnLoad</em>” car nos pages héritent de “<em>SessionPage</em>”.</p>
<p><pre class="brush: csharp;">
public class SessionPage : Page
{
    protected override void OnLoad(EventArgs e)
    {
        // build the spring.net session
        if (Session.IsNewSession)
        Response.Redirect(&quot;SpringSessionHttpHandler?ReturnUrl=&quot; + Server.UrlEncode(Request.Url.ToString()), true);

        base.OnLoad(e);
    }
}
</pre></p>
<p>Le code du HttpHandler est très simple: il force la création du contexte Spring dans la session, puis redirige sur la page d’origine qui elle a un accès en lecture seule sur la session.</p>
<p><pre class="brush: csharp;">
public class BadAjaxHttpHandler : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            // get the name of the controller and the action from the URL
            var action = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
            var controller = context.Request.Url.Segments[context.Request.Url.Segments.Length - 2]
                .Replace(&quot;.ajax&quot;, string.Empty)
                .Replace(&quot;/&quot;, string.Empty);

            // get the instance of the controller thanks to its name
            var instance = ContextRegistry.GetContext().GetObject(controller);

            // get the method of the controller thanks to reflection
            var method = instance.GetType().GetMethod(action, BindingFlags.Instance | BindingFlags.Public);
            var args = new List&lt;object&gt;();
            foreach (var item in method.GetParameters())
            {
                args.Add(TypeDescriptor.GetConverter(item.ParameterType).ConvertFromString(context.Request.Params[item.Name]));
            }

            // invoke the method of the controller
            var result = method.Invoke(instance, args.ToArray());

            // return the JSON value of the method result
            context.Response.Write(new JavaScriptSerializer().Serialize(result));
            context.Response.StatusCode = 200;
            context.Response.End();
        }
</pre></p>
<h2>Mais quel astuce géniale! &#8230;mais pourquoi “Unsecured” ?</h2>
<p>Vous pouvez remarquer que j’affiche l’ID de la session dans la page.<br />
L’identifiant de session est stocké par défaut dans un cookie. J&#8217;ai tout de même changé le nom de ce dernier, car si je laisse la valeur par défaut, je risque d’avoir un conflit avec une autre application (erreur de débutant)</p>
<p><pre class="brush: xml;">
&lt;sessionState cookieName=&quot;TestSession&quot;/&gt;
</pre></p>
<p>Normalement, le cookie est “sécurisé”, cad qu’il n’est pas accessible depuis du Javascript malicieux.<br />
Mais bon, un cookie ça reste quand même pas super sécurisé.</p>
<p>Si vous voulez tester un vol de session, il vous suffit de copier/coller l’ID de la session dans un cookie d’un autre navigateur.</p>
<p>Comment faire alors pour sécuriser le tout? Vous avez pour cela différentes solutions:</p>
<ul>
<li>implémenter votre propre gestion d’ID de session avec &lt;sessionState customProvider=&#8221;MonType&#8221;&gt;, et vérifier l’identité à l’aide de critère comme l’IP du client</li>
<li>coupler la session avec l’authentification</li>
</ul>
<p>C’est cette dernière solution que je vais vous présenter, car c’est la plus simple.<br />
L’authentification en ASP.Net se fait à l’aide du MembershipProvider, que vous pouvez implémenter vous même. Le framework .Net va alors gérer l’identité à l’aide d’un cookie aussi, mais ce dernier est beaucoup plus sécurisé et vous pouvez y faire confiance.<br />
Je vais alors stocker dans la session la valeur du cookie d’authentification, et vérifier donc l’identité avant d’accéder à la session.</p>
<p>Vous pouvez vérifiez cela par vous même à l’aide du projet <a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Good.Secured/">03-TestASPSessionMultithread.Good.Secured</a><br />
Si vous tentez de voler le cookie d’authentification pour l’utiliser sur un autre navigateur, vous serez alors déconnecté. Si vous tentez de voler le cookie de session, vous serez alors aussi déconnecté.</p>
<p>Les pages hérites alors de “<em>SecuredSessionPage</em>”, et vont alors vérifier le cookie de session dans le &#8220;<em>OnLoad</em>&#8220;:</p>
<p><pre class="brush: csharp;">
// if the user tried to steal the session of another user
if (Page.Request.Cookies[FormsAuthentication.FormsCookieName] == null ||
    !Equals(Page.Request.Cookies[FormsAuthentication.FormsCookieName].Value, Session[FormsAuthentication.FormsCookieName]))
{
    this.Logout();
}
</pre></p>
<p>Je vous laisse ensuite découvrir l&#8217;implémentation de l&#8217;authentification, mais ce n&#8217;est pas le sujet de ce billet et il n&#8217;y a rien de plus classique.</p>
<h2>Conclusion</h2>
<p>Si comme moi vous utiliser Spring.net avec ASP.net et que vous avez des problèmes de lenteur, essayer cette astuce <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /> Tagged: <a href='http://grozeille.com/tag/net/'>.Net</a>, <a href='http://grozeille.com/tag/aspnet/'>Asp.net</a>, <a href='http://grozeille.com/tag/springnet/'>Spring.net</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/452/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=452&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling01.png?w=300" medium="image">
			<media:title type="html">LongPooling01</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling02.png?w=300" medium="image">
			<media:title type="html">LongPooling02</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling03.png?w=300" medium="image">
			<media:title type="html">LongPooling03</media:title>
		</media:content>
	</item>
		<item>
		<title>Episode Bonus: Microsoft m&#8217;a entendu? ou pas.</title>
		<link>http://grozeille.com/2010/07/09/episode-bonus-microsoft-ma-entendu-ou-pas/</link>
		<comments>http://grozeille.com/2010/07/09/episode-bonus-microsoft-ma-entendu-ou-pas/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 20:52:18 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Blabla]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[easyphp]]></category>
		<category><![CDATA[webmatrix]]></category>

		<guid isPermaLink="false">http://grozeille.com/?p=414</guid>
		<description><![CDATA[J&#8217;interromps mes épisodes car la news est quand même de taille: Microsoft lance WebMatrix J&#8217;avais dit qu&#8217;il manquait un équivalent à EasyPhp pour .Net, et on m&#8217;a fait remarqué d&#8217;un &#8220;IIS Express&#8221; pointait le bout de son nez&#8230; WebMatrix est donc un gros Setup qui t&#8217;installe sur ta machine un IIS Express, un base de donnée [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=414&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>J&#8217;interromps mes épisodes car la news est quand même de taille: Microsoft lance <a href="http://www.microsoft.com/web/webmatrix/">WebMatrix</a></p>
<p>J&#8217;avais dit qu&#8217;il manquait un équivalent à EasyPhp pour .Net, et on m&#8217;a fait remarqué d&#8217;un &#8220;IIS Express&#8221; pointait le bout de son nez&#8230;<br />
WebMatrix est donc un gros Setup qui t&#8217;installe sur ta machine un IIS Express, un base de donnée Express, et un IDE Express (et d&#8217;autres trucs Express).</p>
<p>Je n&#8217;ai pas encore eu le temps de tester tout ça, mais on voit déjà la grosse machine commerciale!<br />
Le site Web est très bien fait, avec plein de mots à la mode: <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">D.R.Y</a>, MVC, TDD, une petite screenshot de <a href="http://nerddinner.codeplex.com/">NerdDinner</a>, tout pour plaire <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Il y a un gros effort sur l&#8217;aspect &#8220;Communauté&#8221;, on peut facilement installer une application Web, .Net/PHP/autres, en quelques clicks.<br />
A noter aussi le gros effort sur la documentation, tutoriel et compagnie,  pour que tout le monde puisse &#8220;faire du Microsoft rapidement&#8221;.</p>
<p>J&#8217;ai l&#8217;air de ne pas aimé? Ça se voit?</p>
<p>Bon, premièrement, je suis sous Ubuntu à cet instant précis ou je vous écris.<br />
Ensuite, les vidéos Silverlight ne fonctionnent pas: Moonlight crash sous Google Chrome, et sous Firefox la vidéo ne se lance pas.<br />
Enfin, si vous faite joue joue avec WebMatrix, vous allez vouloir déployer ça quelque part&#8230;<br />
Ça tombe bien, Microsoft recommande pleins de &#8220;Hosting partner&#8221; avec du Windows Server 2008 R2&#8230; et du SQLServer bien sûr.</p>
<p>Revenons à EasyPHP.<br />
Avec EasyPHP, vous avez un vrai Apache (pas une version Express) avec un vrai MySQL (pas une version Express).<br />
Il existe aussi bien sûr des &#8220;EasyPHP like&#8221; avec du PostgreSQL, tout est possible.<br />
Vous pouvez ensuite héberger cela sur du Windows si vous voulez&#8230; ou du Linux.</p>
<p>Bon, c&#8217;est vrai, EasyPHP n&#8217;installe pas un IDE, il va falloir en trouver un gratuit.<br />
Ca doit être plutôt rareun IDE gratuit, d&#8217;après ce que l&#8217;on voit sur le site de WebMatrix:<br />
Je cite: &#8220;Cerise sur le gâteau, c&#8217;est entièrement gratuit.&#8221;</p>
<p>Allez, parce-que je suis gentil, voici 3 IDE PHP gratuit:</p>
<ul>
<li><a href="http://www.phpide.de/">http://www.phpide.de/</a></li>
<li><a href="http://www.php-editors.com/">http://www.php-editors.com/</a></li>
<li><a href="http://www.phpide.de/">http://www.phpide.de/</a></li>
</ul>
<p>Le gros + de WebMatrix, c&#8217;est quand même de pouvoir télécharger n&#8217;importe quel application Web (ASP.Net et PHP) en quelques clicks. La, j&#8217;avoue, rien à dire.</p>
<p>Je vous laisse maintenant apprécier  la grandeur commerciale de Microsoft, je pense qu&#8217;ils vont réussir leur coup avec WebMatrix.</p>
<br /> Tagged: <a href='http://grozeille.com/tag/net/'>.Net</a>, <a href='http://grozeille.com/tag/aspnet/'>Asp.net</a>, <a href='http://grozeille.com/tag/easyphp/'>easyphp</a>, <a href='http://grozeille.com/tag/webmatrix/'>webmatrix</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/414/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/414/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/414/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=414&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/07/09/episode-bonus-microsoft-ma-entendu-ou-pas/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>
	</item>
		<item>
		<title>Timeout WCF au bout d&#8217;un certain nombre d&#8217;appels</title>
		<link>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/</link>
		<comments>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 23:20:52 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[Spring.net]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://grozeille.wordpress.com/?p=50</guid>
		<description><![CDATA[Rien de plus stressant que de passer une journée entière sur un bug. Surtout si on n&#8217;a aucune idée du problème (pas d&#8217;exceptions, ni d&#8217;erreurs dans les logs) et que les recherches sur Internet sont infructueuses. Contexte : une application Web Asp.Net communique avec un service WCF. Problème : au bout d’un certain nombre d’appels [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=50&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Rien de plus stressant que de passer une journée entière sur un bug. Surtout si on n&#8217;a aucune idée du problème (pas d&#8217;exceptions, ni d&#8217;erreurs dans les logs) et que les recherches sur Internet sont infructueuses.<br />
<strong>Contexte</strong> : une application Web Asp.Net communique avec un service WCF.<br />
<strong>Problème</strong> : au bout d’un certain nombre d’appels (invariant) l’application Web n’arrive plus à joindre le serveur (Timeout).</p>
<p><span id="more-50"></span>Pour conserver une trace de mon incompétence, voici donc la <strong>solution</strong>:<br />
Pour qu&#8217;on puisse dialoguer avec un service WCF dans une page Asp.net, je leur injecte un proxy à l’aide de Spring (voir <a href="http://www.springframework.net/doc-latest/reference/html/web.html#web-di">Spring.net pour le web</a>). Pour cela, j’utilise une &#8220;factory de proxy&#8221; à l’aide de l’interface <a href="http://www.springframework.net/doc-latest/reference/html/objects.html#d0e4032">IFactoryObject</a>.<br />
Crédule que j’étais, j’imaginais que le fait de retourner <code>true</code> pour la propriété <code>IsSingleton</code> allait faire en sorte que Spring.net ne fasse appel qu’une seule fois à la méthode <code>GetObject()</code>.<br />
Et bien non ! C&#8217;est à vous d’être cohérent: même si <code>IsSingleton</code> retourne <code>true</code>,  rien ne vous empêche de toujours retourner une instance différente dans la méthode <code>GetObject()</code>.</p>
<p>Pour en revenir à mon problème, vous l’aurez compris : ma méthode <code>GetObject()</code> retournait à chaque fois un nouveau proxy vers le service WCF.<br />
<strong>Résulat</strong> : à chaque fois que Spring avait besoin d’injecter mon proxy à une page (postback par exemple), je créai une nouvelle connexion au serveur WCF. J&#8217;ai fini par atteindre le nombre de connexion max, et le serveur ne répondait plus.</p>
<p>Il est tout de même dommage que les <a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx">traces WCF</a> ne m&#8217;ont pas révélé d&#8217;exception expliquant cette limite max de connexion <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Pour approfondir le sujet sur les <code>IFactoryObject</code> :<br />
Un objet qui implémente <code>IFactoryObject</code> doit toujours être un singleton, si ce n’est pas le cas on obtient une exception:<br />
<pre class="brush: xml;">
&lt;object id=&quot;maFactory&quot; type=&quot;MonAssembly.MaFactory, MonAssembly&quot; singleton=&quot;false&quot;/&gt;
</pre><br />
<code><br />
=&gt; IFactoryObject must be defined as a singleton - IFactoryObjects themselves are not allowed to be prototypes.<br />
</code></p>
<p>La propriété <code>IsSingleton</code> de la factory indique seulement ce qu’elle est censée faire&#8230; mais sans aucune obligation/vérification du comportement. Dans mon cas, je retournais <code>true</code> mais rien ne m&#8217;a empêché de créer une nouvelle instance à chaque appel&#8230;</p>
<p>Dans le cas particulier d&#8217;une application Asp.net, on peut avoir des &#8220;presque singleton&#8221; en changeant le <code>scope</code>:<br />
<pre class="brush: xml;">
&lt;object id=&quot;maFactory&quot; type=&quot;MonAssembly.MaFactory, MonAssembly&quot; scope=&quot;application&quot;/&gt;
</pre></p>
<ul>
<li>scope=&#8221;application&#8221; : c&#8217;est un singleton de toute l&#8217;application web. Firefox et Safari m&#8217;affiche toujours 1.</li>
<li>scope=&#8221;session&#8221; : c&#8217;est un singleton pour chaque session cliente. Firefox et Safari m&#8217;affiche toujours 2 (1 instance pour Firefox +  1 instance pour Safari).</li>
<li>scope=&#8221;request&#8221; : c&#8217;est un singleton dans le cadre de la requête. Firefox et Safari vois le compteur s&#8217;incrémenter à chaque rafraichissement de la page.</li>
</ul>
<p>Pour <a href="http://www.springframework.net/doc-latest/reference/html/objects.html#d0e2577">plus d&#8217;infos sur les scopes</a>.</p>
<p><strong>Conclusion(s)</strong> :</p>
<ol>
<li>Ce n&#8217;est pas la propriété <code>IsSingleton</code> qui détermine si Spring va faire appelle une ou plusieurs fois à votre Factory. C&#8217;est à elle de fournir le comportement adéquat.</li>
<li>Un singleton n&#8217;en est pas toujours un&#8230; ça dépend du contexte. Dans tous les cas, pour éviter les erreurs comme la mienne, n&#8217;oublier pas d&#8217;utiliser la <code>destroyMethod</code> pour libérer les ressources. (l&#8217;interface <code>ILifeCycle</code> de Java <a href="http://jira.springframework.org/browse/SPRNET-753">n&#8217;existe pas encore</a> dans Spring.net  mais la <a href="http://www.springframework.net/roadmap.html">1.2 sort en RC1 début mai</a>&#8230;).</li>
<li>Un &#8220;Timeout&#8221; peut vouloir dire &#8220;trop de connexion au serveur&#8221; <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Cette fameuse Factory de proxy WCF sera fournie dans Spring.net 1.2. j&#8217;aurais perdu moins de temps en <a href="http://forum.springframework.net/showthread.php?t=2936">prenant les sources des nightbuilds</a>&#8230; vive l&#8217;OpenSource!</li>
</ol>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/grozeille.wordpress.com/50/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/grozeille.wordpress.com/50/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&amp;blog=173450&amp;post=50&amp;subd=grozeille&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>
	</item>
	</channel>
</rss>
