<?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/"
	>

<channel>
	<title>Le blog de Hinault Romaric Donfack &#187; ASP.NET</title>
	<atom:link href="https://blog.developpez.com/lilroma/pcategory/net/asp-net/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/lilroma</link>
	<description>Bienvenue sur ce blog. Vous y trouverez du .NET, du .NET...  encore du .NET, toujours du .NET et très peu de chose sur moi</description>
	<lastBuildDate>Sat, 27 Aug 2016 14:24:30 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>ASP.NET Core : Tests unitaires d’une application MVC avec MsTest V2</title>
		<link>https://blog.developpez.com/lilroma/p13101/net/asp-net-core-tests-unitaires-dune-application-mvc-avec-mstest-v2</link>
		<comments>https://blog.developpez.com/lilroma/p13101/net/asp-net-core-tests-unitaires-dune-application-mvc-avec-mstest-v2#comments</comments>
		<pubDate>Sat, 27 Aug 2016 14:24:30 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[MsTest V2]]></category>
		<category><![CDATA[Tests Unitaires]]></category>
		<category><![CDATA[Visuall Studio 2015]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/lilroma/?p=112</guid>
		<description><![CDATA[ASP.NET Core apporte une refonte complète de la solution de développement Web de Microsoft. Le recours à un nouvel environnement d&#8217;exécution (DNX) et son architecture entrainent une incompatibilité avec de nombreux outils. En effet, si vous développez un projet ASP.NET &#8230; <a href="https://blog.developpez.com/lilroma/p13101/net/asp-net-core-tests-unitaires-dune-application-mvc-avec-mstest-v2">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>ASP.NET Core apporte une refonte complète de la solution de développement Web de Microsoft. Le recours à un nouvel environnement d&rsquo;exécution (DNX) et son architecture entrainent une incompatibilité avec de nombreux outils.</p>
<p><a href="http://blog.developpez.com/lilroma/files/2016/08/aspnetcore.png"><img src="http://blog.developpez.com/lilroma/files/2016/08/aspnetcore-300x218.png" alt="aspnetcore" class="alignnone size-medium wp-image-113" /></a></p>
<p>En effet, si vous développez un projet ASP.NET Core qui utilise uniquement le CoreCLR, vous ne devez qu’utiliser les dépendances qui offrent une prise en charge du CoreCLR.</p>
<p>Depuis l’annonce de .NET Core, de nombreux éditeurs de librairies se sont activés pour offrir une prise en charge de cette version, c’est notamment le cas des outils de tests, dont<strong> MSTest</strong>. </p>
<p>Microsoft a publié il y a quelques semaines une préversion de la V2 de MsTest, qui introduit une architecture unifiée et apporte une prise en charge de .NET Core. Dans le cadre de ce billet de blog, nous verrons comment mettre en place des tests unitaires dans un projet ASP.NEt MVC Core avec <strong>MSTest V2</strong>.</p>
<p>Nous allons dans un premier temps créer une application ASP.NET Core en utilisant le modèle Web Application.</p>
<p><span id="more-112"></span></p>
<p><a href="http://blog.developpez.com/lilroma/files/2016/08/image.png"><img src="http://blog.developpez.com/lilroma/files/2016/08/image.png" alt="image" class="alignnone size-medium wp-image-114" /></a></p>
<p>Ceci fait, vous allez ajouter un nouveau projet de type bibliothèque de classe à votre projet.   Pour l’instant, il n’existe pas de modèle de projet pour la nouvelle version du framework de test de Microsoft. Cette prise en charge sera effective dans la version stable de l’outil, avec la sortie de Visual Studio 15.</p>
<p><a href="http://blog.developpez.com/lilroma/files/2016/08/image1.png"><img src="http://blog.developpez.com/lilroma/files/2016/08/image1.png" alt="image1" class="alignnone size-medium wp-image-115" /></a></p>
<p>Ajoutez les dépendances suivantes à votre projet en utilisant la console Nuget :</p>
<ul>
<li>MSTest.TestFramework</li>
<li>MSTest.TestAdapter</li>
<li>dotnet-test-mstest</li>
</ul>
<p>Le package <strong>MSTest.TestFramework</strong> permet d’installer le framework MSTest V2. Pour l’installer, cliquez sur Tools dans la barre de menu de Visual Studio, puis Nuget Package Manager, ensuite sur Package Manager Console. Rassurez-vous que dans la zone Default Project, vous avez sélectionné votre projet de test :</p>
<p><a href="http://blog.developpez.com/lilroma/files/2016/08/image2.png"><img src="http://blog.developpez.com/lilroma/files/2016/08/image2.png" alt="image2" class="alignnone size-medium wp-image-116" /></a></p>
<p>Dans la console NuGet, tapez la commande suivante :</p>
<blockquote><p>Install-Package MSTest.TestFramework -Pre</p></blockquote>
<p><strong>MSTest.TestAdapter</strong> est utilisé pour trouver et exécuter le framework de test sur lequel votre projet de test est basé. Pour l’installer, vous devez exécuter la commande suivante dans la console NuGet :</p>
<blockquote><p>Install-Package MSTest.TestAdapter -Pre:</p></blockquote>
<p>Enfin, vous allez exécuter la commande suivante pour installer le dernier package NuGet :</p>
<blockquote><p>Install-Package dotnet-test-mstest -Pre</p></blockquote>
<p>Vous allez probablement obtenir un message d’erreur d’incompatibilité lors de la restauration des packages par NuGet. Ouvrez le fichier Project.json et remplacez :</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#800000'>"</span><span style='color:#0000e6'>frameworks</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>netstandard1.6</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
     <span style='color:#800000'>"</span><span style='color:#0000e6'>imports</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>dnxcore50</span><span style='color:#800000'>"</span>
   <span style='color:#800080'>}</span>
<span style='color:#800080'>}</span>
</pre>
<p>Par </p>
<pre style='color:#000000;background:#ffffff'><span style='color:#800000'>"</span><span style='color:#0000e6'>frameworks</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>netcoreapp1.0</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
     <span style='color:#800000'>"</span><span style='color:#0000e6'>imports</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#808030'>[</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>dnxcore50</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>portable-net45+win8</span><span style='color:#800000'>"</span>
     <span style='color:#808030'>]</span><span style='color:#808030'>,</span>
 
     <span style='color:#800000'>"</span><span style='color:#0000e6'>dependencies</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>Microsoft.NETCore.App</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
         <span style='color:#800000'>"</span><span style='color:#0000e6'>version</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.0</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
         <span style='color:#800000'>"</span><span style='color:#0000e6'>type</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>platform</span><span style='color:#800000'>"</span>
       <span style='color:#800080'>}</span>
     <span style='color:#800080'>}</span>
   <span style='color:#800080'>}</span>
 <span style='color:#800080'>}</span>
</pre>
<p>Vous remarquerez sans doute que nous avons marqué notre bibliothèque de classes comme une application (netcoreapp1.0). Cela est dû au fait que notre projet de test utilise le .NET CLI. Sa méthode Main sera fournie par le runner de mstest. </p>
<p>Vous devez par la suite ajouter au fichier Project.json la ligne suivante, pour spécifier que votre projet de test unitaire repose sur mstest :</p>
<blockquote><p>&laquo;&nbsp;testRunner&nbsp;&raquo;: &laquo;&nbsp;mstest&nbsp;&raquo;,</p></blockquote>
<p>Ajoutez une référence au projet ASP.NET Core. Votre fichier Project.json devrait ressembler à ceci :</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#800080'>{</span>
 <span style='color:#800000'>"</span><span style='color:#0000e6'>version</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.0-*</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>

 <span style='color:#800000'>"</span><span style='color:#0000e6'>testRunner</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>mstest</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>

 <span style='color:#800000'>"</span><span style='color:#0000e6'>dependencies</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>dotnet-test-mstest</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.1.1-preview</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>MSTest.TestAdapter</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.3-preview</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>MSTest.TestFramework</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.1-preview</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>NETStandard.Library</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.6.0</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>SampleApp</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.0-*</span><span style='color:#800000'>"</span>
 <span style='color:#800080'>}</span><span style='color:#808030'>,</span>

 <span style='color:#800000'>"</span><span style='color:#0000e6'>frameworks</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
   <span style='color:#800000'>"</span><span style='color:#0000e6'>netcoreapp1.0</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
     <span style='color:#800000'>"</span><span style='color:#0000e6'>imports</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#808030'>[</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>dnxcore50</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>portable-net45+win8</span><span style='color:#800000'>"</span>
     <span style='color:#808030'>]</span><span style='color:#808030'>,</span>

     <span style='color:#800000'>"</span><span style='color:#0000e6'>dependencies</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
       <span style='color:#800000'>"</span><span style='color:#0000e6'>Microsoft.NETCore.App</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800080'>{</span>
         <span style='color:#800000'>"</span><span style='color:#0000e6'>version</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>1.0.0</span><span style='color:#800000'>"</span><span style='color:#808030'>,</span>
         <span style='color:#800000'>"</span><span style='color:#0000e6'>type</span><span style='color:#800000'>"</span><span style='color:#808030'>:</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>platform</span><span style='color:#800000'>"</span>
       <span style='color:#800080'>}</span>
     <span style='color:#800080'>}</span>
   <span style='color:#800080'>}</span>
 <span style='color:#800080'>}</span>

<span style='color:#800080'>}</span>
</pre>
<p>Ajoutez un nouveau fichier HomeControllerTest.cs à votre projet de test. Ajoutez un appel à l’espace de nom <strong>Microsoft.VisualStudio.TestTools.UnitTesting</strong> :</p>
<blockquote><p>using Microsoft.VisualStudio.TestTools.UnitTesting; </p></blockquote>
<p>Jetons maintenant un coup d’œil au fichier HomeController.cs</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#800000;font-weight:bold'>using</span> System<span style='color:#800080'>;</span>
<span style='color:#800000;font-weight:bold'>using</span> System<span style='color:#808030'>.</span>Collections<span style='color:#808030'>.</span>Generic<span style='color:#800080'>;</span>
<span style='color:#800000;font-weight:bold'>using</span> System<span style='color:#808030'>.</span>Linq<span style='color:#800080'>;</span>
<span style='color:#800000;font-weight:bold'>using</span> System<span style='color:#808030'>.</span>Threading<span style='color:#808030'>.</span>Tasks<span style='color:#800080'>;</span>
<span style='color:#800000;font-weight:bold'>using</span> Microsoft<span style='color:#808030'>.</span>AspNetCore<span style='color:#808030'>.</span>Mvc<span style='color:#800080'>;</span>

<span style='color:#800000;font-weight:bold'>namespace</span> SampleApp<span style='color:#808030'>.</span>Controllers
<span style='color:#800080'>{</span>
   <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>class</span> HomeController <span style='color:#808030'>:</span> Controller
   <span style='color:#800080'>{</span>
       <span style='color:#800000;font-weight:bold'>public</span> IActionResult Index<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
       <span style='color:#800080'>{</span>
           <span style='color:#800000;font-weight:bold'>return</span> View<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
       <span style='color:#800080'>}</span>

       <span style='color:#800000;font-weight:bold'>public</span> IActionResult About<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
       <span style='color:#800080'>{</span>
           ViewData<span style='color:#808030'>[</span><span style='color:#800000'>"</span><span style='color:#0000e6'>Message</span><span style='color:#800000'>"</span><span style='color:#808030'>]</span> <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>Your application description page.</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

           <span style='color:#800000;font-weight:bold'>return</span> View<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
       <span style='color:#800080'>}</span>

       <span style='color:#800000;font-weight:bold'>public</span> IActionResult Contact<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
       <span style='color:#800080'>{</span>
           ViewData<span style='color:#808030'>[</span><span style='color:#800000'>"</span><span style='color:#0000e6'>Message</span><span style='color:#800000'>"</span><span style='color:#808030'>]</span> <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>Your contact page.</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

           <span style='color:#800000;font-weight:bold'>return</span> View<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
       <span style='color:#800080'>}</span>

       <span style='color:#800000;font-weight:bold'>public</span> IActionResult Error<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
       <span style='color:#800080'>{</span>
           <span style='color:#800000;font-weight:bold'>return</span> View<span style='color:#808030'>(</span><span style='color:#800000'>"</span><span style='color:#0000e6'>~/Views/Shared/Error.cshtml</span><span style='color:#800000'>"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
       <span style='color:#800080'>}</span>
   <span style='color:#800080'>}</span>
<span style='color:#800080'>}</span>
</pre>
<p>Nous allons écrire du code pour tester le ViewResult et une autre pour le ViewData.</p>
<p>Le code que nous allons écrire va permettre de vérifier que la méthode d’action Error() retourne le bon ViewResult. Le code de test est le suivant :</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#808030'>[</span>TestMethod<span style='color:#808030'>]</span>
        <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>void</span> Error_ReturnErrorView<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
        <span style='color:#800080'>{</span>
            <span style='color:#696969'>// Arrange</span>
            <span style='color:#800000;font-weight:bold'>var</span> controller <span style='color:#808030'>=</span> <span style='color:#800000;font-weight:bold'>new</span> HomeController<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
            <span style='color:#800000;font-weight:bold'>var</span> errorView <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>~/Views/Shared/Error.cshtml</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

            <span style='color:#696969'>// Act</span>
            <span style='color:#800000;font-weight:bold'>var</span> viewResult <span style='color:#808030'>=</span> controller<span style='color:#808030'>.</span>Error<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800000;font-weight:bold'>as</span> ViewResult<span style='color:#800080'>;</span>

            <span style='color:#696969'>// Assert</span>
            Assert<span style='color:#808030'>.</span>AreEqual<span style='color:#808030'>(</span>errorView<span style='color:#808030'>,</span> viewResult<span style='color:#808030'>.</span>ViewName<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
        <span style='color:#800080'>}</span>
</pre>
<p>Pour le ViewData, nous allons tester que notre méthode d’action renvoie le bon ViewData. La méthode de test pour effectuer cela est la suivante :</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#808030'>[</span>TestMethod<span style='color:#808030'>]</span>
       <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>void</span> About_ReturnViewData<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
       <span style='color:#800080'>{</span>
           <span style='color:#696969'>// Arrange</span>
           <span style='color:#800000;font-weight:bold'>var</span> controller <span style='color:#808030'>=</span> <span style='color:#800000;font-weight:bold'>new</span> HomeController<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
           <span style='color:#800000;font-weight:bold'>var</span> viewData <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>Your application description page.</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

           <span style='color:#696969'>// Act</span>
           <span style='color:#800000;font-weight:bold'>var</span> viewResult <span style='color:#808030'>=</span> controller<span style='color:#808030'>.</span>About<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800000;font-weight:bold'>as</span> ViewResult<span style='color:#800080'>;</span>

           <span style='color:#696969'>// Assert</span>
           Assert<span style='color:#808030'>.</span>AreEqual<span style='color:#808030'>(</span>viewData<span style='color:#808030'>,</span> viewResult<span style='color:#808030'>.</span>ViewData<span style='color:#808030'>[</span><span style='color:#800000'>"</span><span style='color:#0000e6'>Message</span><span style='color:#800000'>"</span><span style='color:#808030'>]</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
       <span style='color:#800080'>}</span>
</pre>
<p>Le code complet est le suivant :</p>
<pre style='color:#000000;background:#ffffff'><span style='color:#808030'>[</span>TestClass<span style='color:#808030'>]</span>
    <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>class</span> HomeControllerTest
    <span style='color:#800080'>{</span>


        <span style='color:#808030'>[</span>TestMethod<span style='color:#808030'>]</span>
        <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>void</span> Error_ReturnErrorView<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
        <span style='color:#800080'>{</span>
            <span style='color:#696969'>// Arrange</span>
            <span style='color:#800000;font-weight:bold'>var</span> controller <span style='color:#808030'>=</span> <span style='color:#800000;font-weight:bold'>new</span> HomeController<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
            <span style='color:#800000;font-weight:bold'>var</span> errorView <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>~/Views/Shared/Error.cshtml</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

            <span style='color:#696969'>// Act</span>
            <span style='color:#800000;font-weight:bold'>var</span> viewResult <span style='color:#808030'>=</span> controller<span style='color:#808030'>.</span>Error<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800000;font-weight:bold'>as</span> ViewResult<span style='color:#800080'>;</span>

            <span style='color:#696969'>// Assert</span>
            Assert<span style='color:#808030'>.</span>AreEqual<span style='color:#808030'>(</span>errorView<span style='color:#808030'>,</span> viewResult<span style='color:#808030'>.</span>ViewName<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
        <span style='color:#800080'>}</span>


        <span style='color:#808030'>[</span>TestMethod<span style='color:#808030'>]</span>
        <span style='color:#800000;font-weight:bold'>public</span> <span style='color:#800000;font-weight:bold'>void</span> About_ReturnViewData<span style='color:#808030'>(</span><span style='color:#808030'>)</span>
        <span style='color:#800080'>{</span>
            <span style='color:#696969'>// Arrange</span>
            <span style='color:#800000;font-weight:bold'>var</span> controller <span style='color:#808030'>=</span> <span style='color:#800000;font-weight:bold'>new</span> HomeController<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
            <span style='color:#800000;font-weight:bold'>var</span> viewData <span style='color:#808030'>=</span> <span style='color:#800000'>"</span><span style='color:#0000e6'>Your application description page.</span><span style='color:#800000'>"</span><span style='color:#800080'>;</span>

            <span style='color:#696969'>// Act</span>
            <span style='color:#800000;font-weight:bold'>var</span> viewResult <span style='color:#808030'>=</span> controller<span style='color:#808030'>.</span>About<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800000;font-weight:bold'>as</span> ViewResult<span style='color:#800080'>;</span>

            <span style='color:#696969'>// Assert</span>
            Assert<span style='color:#808030'>.</span>AreEqual<span style='color:#808030'>(</span>viewData<span style='color:#808030'>,</span> viewResult<span style='color:#808030'>.</span>ViewData<span style='color:#808030'>[</span><span style='color:#800000'>"</span><span style='color:#0000e6'>Message</span><span style='color:#800000'>"</span><span style='color:#808030'>]</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
        <span style='color:#800080'>}</span>

    <span style='color:#800080'>}</span>
</pre>
<p>A l’exécution, vous allez obtenir le résultat suivant dans l’explorateur de test :</p>
<p><a href="http://blog.developpez.com/lilroma/files/2016/08/image3.png"><img src="http://blog.developpez.com/lilroma/files/2016/08/image3.png" alt="image3" width="264" height="130" class="alignnone size-full wp-image-119" /></a></p>
<p>C’est tout. Dans un prochain billet, nous verrons comment écrire des tests unitaires smockés avec mstest v2 et la preview de Moq, qui prend aussi en charge .NET Core.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>« ASP.NET et Web Tools 2012.2 » sort en RC, avec de nouvelles fonctionnalités pour WebForms, MVC, WebAPI et SignalR</title>
		<link>https://blog.developpez.com/lilroma/p11585/net/asp-net-et-web-tools-2012-2-sort-en-rc-avec-de-nouvelles-fonctionnalites-pour-webforms-mvc-webapi-et-signalr</link>
		<comments>https://blog.developpez.com/lilroma/p11585/net/asp-net-et-web-tools-2012-2-sort-en-rc-avec-de-nouvelles-fonctionnalites-pour-webforms-mvc-webapi-et-signalr#comments</comments>
		<pubDate>Tue, 18 Dec 2012 16:51:09 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC 4]]></category>
		<category><![CDATA[ASP.NET Web API]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[WebPages]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/lilroma/?p=104</guid>
		<description><![CDATA[« ASP.NET et Web Tools 2012.2 » sort en RC, avec de nouvelles fonctionnalités pour WebForms, MVC et WebAPI Le Web évolue rapidement, et Microsoft est conscient de cela. L’éditeur a ainsi adopté un cycle de mise à jour pour &#8230; <a href="https://blog.developpez.com/lilroma/p11585/net/asp-net-et-web-tools-2012-2-sort-en-rc-avec-de-nouvelles-fonctionnalites-pour-webforms-mvc-webapi-et-signalr">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>« ASP.NET et Web Tools 2012.2 » sort en RC, avec de nouvelles fonctionnalités pour WebForms, MVC et WebAPI </p>
<p>Le Web évolue rapidement, et Microsoft est conscient de cela. L’éditeur a ainsi adopté un cycle de mise à jour pour ASP.NET plus rapide que celui de Visual Studio.</p>
<p>La société compte donc publier une mise à jour pour sa plateforme de développement Web ASP.NET en début d’année prochaine.</p>
<p>Les développeurs qui veulent commencer à « jouer » avec les nouvelles fonctionnalités de cette mise à jour peuvent déjà télécharger sa version Release Candidate (RC) qui vient d’être publiée par les équipes  ASP.NET et Visual Web Developer de Microsoft.</p>
<p><img src="http://rdonfack.developpez.com/images/aspnevnext.png" alt="" /></p>
<p><span id="more-104"></span></p>
<p>« ASP.NET et Web Tools 2012.2 » RC étend le runtine ASP.NET existant et ajout de nouveaux outils Web à Visual Studio 2012 pour WebForms, MVC, WebAPI, etc. Il s’agit des fonctionnalités suivantes :</p>
<ol>
<li>De nouveaux modèles de projets ASP.NET MVC. la création d’applications Facebook est désormais plus facile avec le modèle Facebook, qui permet en quelques étapes de créer une application qui interagir avec le réseau social. Le nouveau modèle « Single Page Application » permet aux développeurs de créer des applications Web interactives côté client à l’aide de jQuery, Knockout et ASP.NET Web API ;</li>
<li>Le support de la communication en temps réel avec ASP.NET SignalR. SignalR est une bibliothèque client/serveur qui permet aux clients basés sur un navigateur et aux composants serveur basés sur ASP.NET d&rsquo;avoir une conversation à étapes multiples et bidirectionnelle;</li>
<li>Le support de l’IntelliSense pour Knockout  et l’ajout de la prise en charge de JSON en tant que classe ;
</li>
<li>L’introduction de nouvelles fonctionnalités pour ASP.NET Web API, y compris le support d’OData, l’ajout des fonctions de traçabilité, de monitoring et  de génération d’une page d’aide pour une API Web;</li>
<li>Des améliorations de l’inspecteur de page, qui offre désormais de meilleures performances pour JavaScript et CSS, dont la capacité de voir les mises à jour en temps réel d’un fichier CSS ;</li>
<li>L’unification de l’expérience de publication pour une application Web et un projet de type site Web, ainsi que l’ajout des options de publication sélective ;</li>
<li>L’intégration de la nouvelle fonctionnalité ASP.NET Friendly URL. Cette fonction rend facile la génération des URL sans l’extension .aspx. Elle permet également au développeur d’ajouter plus facilement le support du mobile dans son application Web ;</li>
<li>La mise à jour des modèles de projets Web dans Visual Studio 2012.</li>
</ol>
<p>Cette mise à jour est livrée comme des packages NuGet supplémentaires. Ce qui signifie qu’il ne peut avoir aucun problème de compatibilité avec les projets existants.</p>
<p><strong><a href="http://www.asp.net/vnext">Télécharger &laquo;&nbsp;ASP.NET et Web Tools 2012.2&Prime; RC</a></strong></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Consommer une API Web avec HttpClient</title>
		<link>https://blog.developpez.com/lilroma/p11330/net/consommer-une-api-web-avec-httpclient</link>
		<comments>https://blog.developpez.com/lilroma/p11330/net/consommer-une-api-web-avec-httpclient#comments</comments>
		<pubDate>Thu, 20 Sep 2012 20:55:30 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET Web API]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/lilroma/?p=92</guid>
		<description><![CDATA[Dans un précédent article, j&#8217;ai présenté ASP.NET Web API, la nouveauté phare de ASP.NET MVC 4, qui a pour objectif principal de permettre aux développeurs d’exposer leurs applications, données et services sur le web directement à travers HTTP. Le support &#8230; <a href="https://blog.developpez.com/lilroma/p11330/net/consommer-une-api-web-avec-httpclient">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Dans <a href="http://blog.developpez.com/lilroma/p10768/">un précédent article</a>, j&rsquo;ai présenté ASP.NET Web API, la nouveauté phare de ASP.NET MVC 4, qui a  pour objectif principal de permettre aux développeurs d’exposer leurs applications, données et services sur le web directement à travers HTTP. Le support d’ASP.NET Web API permet de créer facilement des API Web puissantes, qui peuvent être consultées à partir d’un large éventail de client (réseaux sociaux, navigateurs, terminaux mobiles, etc.).</p>
<p>Dans ce article, nous avons créer une première API et consommer celle-ci dans une page Web en utilisant jQuery. Dans ce billet de blog, je vais vous montrer comment vous pouvez interagir avec votre API dans une application native en utilisant HttpClient.</p>
<p><span id="more-92"></span></p>
<p>Dans une application Web, vous pouvez simplement interagir avec une API Web coté client en appelant les requêtes HTTP Get, Put, Post et Delete dans un Script JavaScript ou en utilisant jQuery. Mais, si vous voulez accéder à votre API à partir d’une application Desktop par exemple, comment procéder ?</p>
<p>C’est à ce niveau qu’intervient HTTPClient. HTTPClient est un client moderne HTTP pour les applications .NET.  Il peut être utilisé pour consommer avec souplesse et simplicité les fonctionnalités exposées via HTTP. Vous pouvez utiliser HTTPClient pour mettre en œuvre des interactions avec une API Web en envoyant et en recevant des réponses à partir des verbes standards Get, Put, Post et Delete de HTTP grâce aux méthodes GetAsync, PutAsync, PostAsync, DeleteAsync.</p>
<p>L’exemple ci-dessous illustre comment vous pouvez consommer les données au format XML d’une API Web en utilisant la méthode GetAsync.</p>
<div>
<pre>HttpClient client = <span style="color: #0000ff">new</span> HttpClient();<br />client.DefaultRequestHeaders.Accept.Add(<span style="color: #0000ff">new</span> MediaTypeWithQualityHeaderValue(<span style="color: #006080">&quot;application/xml&quot;</span>));<br />var response = client.GetAsync(<span style="color: #006080">&quot;http://localhost:59130/api/Customer&quot;</span>).Result;<br /></pre>
<p></div>
<p>Si vous souhaitez que les données soient retournées au format XML, vous pouvez procéder comme suit :</p>
<div style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border: solid 1px silver;cursor: text;margin: 20px 0px 10px 0px;overflow: auto;padding: 4px;width: 97.5%;direction: ltr;text-align: left">
<pre style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border-style: none;color: black;overflow: visible;padding: 0px;width: 100%;margin: 0em;direction: ltr;text-align: left">HttpClient client = <span style="color: #0000ff">new</span> HttpClient();<br />client.DefaultRequestHeaders.Accept.Add(<span style="color: #0000ff">new</span> MediaTypeWithQualityHeaderValue(<span style="color: #006080">"application/json"</span>));<br />var response = client.GetAsync(<span style="color: #006080">"http://localhost:59130/api/Customer"</span>).Result;</pre>
<p></div>
<p>La procédure <strong>client.DefaultRequestHeaders.Accept.Add()</strong> permet de définir le format qui sera utilisé pour sérialiser les données.</p>
<p>La procédure asynchrone GetAsync() de la classe HttpClient() prend en paramètre une URI ou une chaine de caractères qui représente l’URL de l’API Web. GetAsync effectue une requête HTTP GET en utilisant l’URL passée en paramètre, puis retourne directement une tache dont la propriété Result (Task.Result) contient la réponse  HTTP (HttpResponseMessage). </p>
<p>NB : Il est recommandé lors de l’utilisation d’une méthode asynchrone d’utiliser également le mot clé await pour éviter que l’application ne soit bloquée jusqu’à ce que l’opération soit complète. On peut s’en passer pour une application console, mais pour une solution Desktop, faudra penser à utiliser await pour éviter le blocage de l’interface utilisateur. Pour plus de détails sur async et await, je vous invite à lire cet excellent article sur le sujet : les nouveautés de C# 5.0. </p>
<p>A titre d’exemple, vous allez créer une application console qui consomme l’API que vous avez créée ci-dessus. Cliquez sur le menu « FICHIER », sélectionnez « Ajouter » puis « Nouveau projet ». Sélectionnez le projet « Application Console » et donnez-lui le nom « TestFirstWebAPI ».</p>
<p>Après création du projet, vous allez ajouter une référence à HTTPClient. HTTPClient n’étant pas disponible par défaut dans le Framework .NET ou avec ASP.NET MVC 4, vous devez passer par le gestionnaire de packages NuGet pour ajouter cette dépendance à votre application.</p>
<p>Faites un clic droit sur votre projet dans l’explorateur de solution et sélectionnez la commande « Gérer les packages NuGet… ». Lorsque l’interface de NuGet va s’afficher, recherchez le package HTTPClient.</p>
<p><img src="http://rdonfack.developpez.com/tutoriels/dotnet/decouverte-asp-net-web-api/images/img7.png" alt="" /> </p>
<p>L’installation du package va  entrainer l’installation des dépendances System.Net.Http et System.Json que vous allez utiliser dans votre application.</p>
<p>Ajoutez une classe dans votre projet ayant la même définition que la classe Customer dans le projet ASP.NET MVC. Pour rappel, cette classe doit avoir la définition suivante :</p>
<div style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border: solid 1px silver;cursor: text;margin: 20px 0px 10px 0px;overflow: auto;padding: 4px;width: 97.5%;direction: ltr;text-align: left">
<pre style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border-style: none;color: black;overflow: visible;padding: 0px;width: 100%;margin: 0em;direction: ltr;text-align: left"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Customer<br />    {<br />        <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> Id { get; set; }<br />        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> FirstName { get; set; }<br />        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> LastName { get; set; }<br />        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> EMail { get; set; }<br />    }<br /></pre>
<p></div>
<p>Ajoutez par la suite une référence à System.Net.Http.Formatting  et System.Net.Http.Headers.</p>
<div style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border: solid 1px silver;cursor: text;margin: 20px 0px 10px 0px;overflow: auto;padding: 4px;width: 97.5%;direction: ltr;text-align: left">
<pre style="background-color: #f4f4f4;font-family: 'Courier New', Courier, Monospace;font-size: 8pt;line-height: 12pt;border-style: none;color: black;overflow: visible;padding: 0px;width: 100%;margin: 0em;direction: ltr;text-align: left"><span style="color: #0000ff">using</span> System.Net.Http.Formatting;<br /><span style="color: #0000ff">using</span> System.Net.Http.Headers;</pre>
<p></div>
<p>Vous allez maintenant ajouter les lignes de code suivantes à la fonction Main de votre application.</p>
<div>
<pre>HttpClient client = <span style="color: #0000ff">new</span> HttpClient();<br /><br /><br />client.DefaultRequestHeaders.Accept.Add(<br />     <span style="color: #0000ff">new</span> MediaTypeWithQualityHeaderValue(<span style="color: #006080">&quot;application/json&quot;</span>));<br /><br /> var response = client.GetAsync(<span style="color: #006080">&quot;http://localhost:59130/api/customer&quot;</span>).Result;  <br /><br /> <span style="color: #0000ff">if</span> (response.IsSuccessStatusCode)<br /> {<br />     <br />     var Customers = response.Content.ReadAsAsync&lt;IEnumerable&lt;Customer&gt;&gt;().Result;<br />     <span style="color: #0000ff">foreach</span> (var c <span style="color: #0000ff">in</span> Customers)<br />     {<br />         Console.WriteLine(<span style="color: #006080">&quot;{0}\t{1}\t{2}&quot;</span>, c.FirstName, c.LastName, c.EMail);<br />        <br />     }<br /> }<br /> <span style="color: #0000ff">else</span><br /> {<br />     Console.WriteLine(<span style="color: #006080">&quot;{0} ({1})&quot;</span>, (<span style="color: #0000ff">int</span>)response.StatusCode, response.ReasonPhrase);<br /> }<br />     Console.ReadLine();<br /></pre>
<p></div>
<p>La procédure ReadAsAsync() lit et déserialise automatiquement le corps de la réponse HTTP qui contient la liste des clients.  </p>
<p>En appuyant sur F5 pour lancer le débogage de votre application, vous allez obtenir le résultat suivant :</p>
<p><img src="http://rdonfack.developpez.com/tutoriels/dotnet/decouverte-asp-net-web-api/images/img8.png" alt="" /> </p>
<p>Rassurez vous que vous utilisez un numéro de port spécifique pour votre application (59130 pour mon cas). Vous pouvez vérifier cela dans les propriétés du projet, onglet Web :</p>
<p><img src="http://rdonfack.developpez.com/tutoriels/dotnet/decouverte-asp-net-web-api/images/img9.png" alt="" /></p>
<p>Vous avez le choix entre utiliser un numéro de port spécifique ou utiliser le serveur Web IIS local si vous en avez. Dans ces cas, le numéro de port ne varie que si vous décidez de le modifier.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC : optimiser le temps de chargement des pages en utilisant le regroupement et la minification</title>
		<link>https://blog.developpez.com/lilroma/p11258/net/asp_net_mvc_optimiser_le_temps_de_charge_1</link>
		<comments>https://blog.developpez.com/lilroma/p11258/net/asp_net_mvc_optimiser_le_temps_de_charge_1#comments</comments>
		<pubDate>Tue, 28 Aug 2012 14:38:19 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC 4]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour, Un petit message pour annoncer la publication de mon nouvel article sur le regroupement et la minification du JavaScript et CSS, des techniques d&#8217;optimisation qu&#8217;apporte ASP.NET MVC 4, pouvant grandement influencer le temps de chargement des pages Web. Le &#8230; <a href="https://blog.developpez.com/lilroma/p11258/net/asp_net_mvc_optimiser_le_temps_de_charge_1">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Bonjour,</p>
<p>Un petit message pour annoncer la publication de mon nouvel article sur le regroupement et la minification du JavaScript et CSS, des techniques d&rsquo;optimisation qu&rsquo;apporte ASP.NET MVC 4, pouvant grandement influencer le temps de chargement des pages Web.</p>
<blockquote><p>
Le temps de chargement d&rsquo;une page est un facteur important dans l&rsquo;évaluation des performances d&rsquo;un site Web. Il a un impact non négligeable sur l&rsquo;expérience utilisateur et même sur le référencement naturel. Plus les pages de votre site se chargent rapidement, plus l&rsquo;expérience de navigation est fluide et plus les utilisateurs sont contents.</p>
<p>Dans nos applications, nous avons recours à plusieurs bibliothèques dont jQuery, knockout, etc. et des feuilles de styles qui ont des conséquences non négligeables sur le temps de chargement des pages.</p>
<p>Dans cet article, nous verrons comment améliorer les performances d&rsquo;une application Web ASP.NET MVC en utilisant le regroupement et la minification à la volée du CSS et JavaScript.</p>
</blockquote>
<p><img src="http://www.developpez.net/forums/images/smilies/fleche.gif" alt="" title="" /> L&rsquo;article complet peut-être consulté sur <a href="http://rdonfack.developpez.com/tutoriels/dotnet/asp-net-mvc-optimiser-temps-chargement-page-utilisant-regroupement-et-minification/">cette page</a>.</p>
<p><img src="http://www.developpez.net/forums/images/smilies/fleche.gif" alt="" title="" /> Pour les commentaires, <a href="http://www.developpez.net/forums/d1255425/dotnet/developpement-web-net/asp-net-mvc/asp-net-mvc-optimiser-temps-chargement-pages-utilisant-regroupement-minification/">ça se passe ici</a>.</p>
<p><img src="http://www.developpez.net/forums/images/smilies/fleche.gif" alt="" title="" /> <a href="http://rdonfack.developpez.com/tutoriels/dotnet/asp-net-mvc-optimiser-temps-chargement-page-utilisant-regroupement-et-minification/bundling.zip">Télécharger le ZIP de l&rsquo;article.</a></p>
<p><img src="http://www.developpez.net/forums/images/smilies/fleche.gif" alt="" title="" /> <a href="http://rdonfack.developpez.com/tutoriels/dotnet/asp-net-mvc-optimiser-temps-chargement-page-utilisant-regroupement-et-minification/bundling.pdf">Télécharger l&rsquo;article au format PDF.</a></p>
<p><img src="http://www.developpez.net/forums/images/smilies/fleche.gif" alt="" title="" /> <a href="http://rdonfack.developpez.com/tutoriels/dotnet/asp-net-mvc-optimiser-temps-chargement-page-utilisant-regroupement-et-minification/bundling-ebooks.zip">Télécharger l&rsquo;article au format eBooks.</a></p>
<p>Bonne lecture <img src="https://blog.developpez.com/lilroma/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>WebMatrix 2 : améliorer le temps de chargement des pages Web en utilisant le regroupement et la minification du CSS et JavaScript</title>
		<link>https://blog.developpez.com/lilroma/p11221/net/webmatrix_2_ameliorer_le_temps_de_charge</link>
		<comments>https://blog.developpez.com/lilroma/p11221/net/webmatrix_2_ameliorer_le_temps_de_charge#comments</comments>
		<pubDate>Wed, 15 Aug 2012 01:57:48 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[WebMatrix]]></category>
		<category><![CDATA[WebPages]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Lorsque je travaille sur une application Web, quelque soit la taille, le langage et les outils que j’utilise, le temps de chargement de mes pages représente un élément auquel j’accorde beaucoup d’importance. Plus le chargement des pages du site est &#8230; <a href="https://blog.developpez.com/lilroma/p11221/net/webmatrix_2_ameliorer_le_temps_de_charge">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lorsque je travaille sur une application Web, quelque soit la taille, le langage et les outils que j’utilise, le temps de chargement de mes pages représente un élément auquel j’accorde beaucoup d’importance. Plus le chargement des pages du site est rapide, plus l’expérience de navigation est fluide et plus les clients sont contents.</p>
<p>Pour optimiser le temps le chargement d’une page, on peut avoir recours à plusieurs techniques côté client et côté serveur dont la mise en cache, l’utilisation d’un CDN ou encore la compression et la minification du CSS et JavaScript.</p>
<p>Dans ce billet de blog, je vais montrer comment vous pouvez grandement améliorer le temps de chargement des pages de votre site Web en minifiant et en regroupant vos fichiers JavaScript et CSS grâce à la bibliothèque ASP. NET Optimization &#8211; Bundling.</p>
<p><img src="http://blog.developpez.com/media/minification.png" alt="" title="" /></p>
<p><span id="more-60"></span></p>
<p>Le regroupement et la minification sont des procédés de réduction de la taille des fichiers en les combinant, et en supprimant les espaces et autres caractères inutiles. Ces méthodes permettent de rendre l’exécution d’une page Web plus rapide avec le moins de demandes de chargement des fichiers.</p>
<p>Pour commencer, vous allez créer une nouvelle application ASP.NET WebPages avec WebMatrix en utilisant le modèle de projet Starter Site. </p>
<p>Comme l’illustre l’image ci-dessous, vous constatez que votre application contient par défaut un nombre déjà assez important de fichiers JavaScript et CSS.</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle1_01.PNG" width="528" height="352" alt="" /></p>
<p>Si vous exécutez votre application et que vous analysez les performances de votre page d’index avec un outil comme Yslow, vous obtenez le résultat suivant :</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle2.PNG" width="680" height="349" alt="" /></p>
<p><strong>Ajout de la bibliothèque ASP.NET Optimization &#8211; Bundling</strong></p>
<p>WebMatrix 2 apporte comme nouveauté phare l’intégration du gestionnaire de packages open source .NET NuGet. Dans la boite à outil de l’EDI, une nouvelle icone NuGet est disponible, permettant d’accéder à l’interface des gestions des packages de votre application. Cliquez sur ce bouton.</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle3.jpg" width="267" height="205" alt="" /></p>
<p>L’interface de gestion des packages de NuGet s’affiche. Pour plus de détail sur son utilisation, lire mon article sur <a href="http://blog.developpez.com/lilroma/p10639/">l’intégration du gestionnaire d’extensions et de NuGet dans WebMatrix 2</a>.</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle4.PNG" width="699" height="504" alt="" /></p>
<p>Dans la zone de recherche, tapez le nom de la bibliothèque «  Microsoft.Web.Optimization », sélectionnez le package ASP.NET Optimization – Bundling, et cliquez sur Installer. </p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle5.PNG" width="697" height="268" alt="" /></p>
<p>La fenêtre contenant les termes de la licence va s’afficher. Cliquez sur j’accepte pour lancer l’installation du package dans votre application. A la fin de l’installation, si vous ouvrez le dossier Bin de votre application, vous verrez la présence d’un nouveau fichier Microsoft.Web.Optimization.dll.</p>
<p><strong>Activation du Bundling</strong></p>
<p>Grâce à NuGet, nous avons intégré sans difficulté la bibliothèque dont nous avons besoins dans notre application. Voyons maintenant comment nous pouvons activer le regroupement et la minification du CSS et JavaScript.</p>
<p>Pour cela, ouvrez le fichier _AppStart.cshtml et inserez la ligne de code suivant :</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">BundleTable.Bundles.EnableDefaultBundles();</pre>
<p></div>
<p>N’oubliez pas d’ajouter une référence à Microsoft.Web.Optimization.</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">@<span style="color: #0000ff;">using</span> Microsoft.Web.Optimization</pre>
<p></div>
<p>Tous les fichiers JavaScript contenus dans le répertoire Scripts (les sous dossiers ne sont pas pris en compte) de votre application seront regroupés, compressés et traités comme un seul fichier. Ces fichiers seront regroupés par défaut dans un dossier Scripts. Ils seront désormais référencés en utilisant la ligne de code suivante :</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">&lt;script src=<span style="color: #006080;">"~/Scripts/js"</span> type=<span style="color: #006080;">"text/javascript"</span>&gt;&lt;/script&gt;</pre>
<p></div>
<p>De même, les fichiers CSS contenus dans le répertoire Content seront également compactés par défaut dans un dossier Content. Ils seront référencés en utilisant la ligne de code suivante :</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">&lt;link href=<span style="color: #006080;">"/Content/css"</span> rel=<span style="color: #006080;">"stylesheet"</span> type=<span style="color: #006080;">"text/css"</span> /&gt;</pre>
<p></div>
<p>Après avoir appliqué ces modifications, exécutez à nouveau votre application. Vous allez obtenir  le résultat suivant :</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle6.PNG" width="575" height="356" alt="" /></p>
<p>En comparant les deux images, vous vous rendez compte que le nombre de requêtes HTTP sur votre page est passé de 30 à 10.  Les cinq fichiers JavaScript ont été regroupés en 1 fichier et les 16 feuilles de styles ont été combinés en 1 fichier.</p>
<p>De même, la taille des fichiers JavaScript est passée de 558,9 Ko à 375,1 Ko. C’est déjà pas mal. Mais, on aurait pu faire mieux, car plusieurs fichiers dans le dossier Scripts qui ont été regroupés n’ont pas été utilisés. C’est à ce niveau qu’intervient le Bundle personnalisé.</p>
<p><strong>Bundle personnalisé</strong></p>
<p>Avec cette option, vous avez la liberté dans le choix des fichiers qui seront dans un regroupement, ainsi que l’URL qu’aura le regroupement. À ce stade, le choix des dossiers de regroupement doit être fonction de la récurrence des fichiers JavaScript et CSS dans les pages de votre application.<br />
Vous pouvez définir vos regroupements personnalisés en procédant comme suit dans le fichier_çAppStart.cshtml.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 400px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">BundleTable.Bundles.EnableDefaultBundles();<br /> <br />    var jsBundle = <span style="color: #0000ff">new</span> Bundle(<span style="color: #006080">&quot;~/Scripts&quot;</span>, <span style="color: #0000ff">typeof</span>(JsMinify));<br />    <br />    jsBundle.AddFile(<span style="color: #006080">&quot;~/Scripts/jquery-1.6.2.min.js&quot;</span>);<br />    jsBundle.AddFile(<span style="color: #006080">&quot;~/Scripts/jquery-ui-1.8.11.js&quot;</span>);<br />    jsBundle.AddFile(<span style="color: #006080">&quot;~/Scripts/modernizr-2.0.6-development-only.js&quot;</span>);<br />   <br /> <br />    BundleTable.Bundles.Add(jsBundle);<br /> <br />    Bundle cssBundle = <span style="color: #0000ff">new</span> Bundle(<span style="color: #006080">&quot;~/Styles&quot;</span>, <span style="color: #0000ff">typeof</span>(CssMinify));<br />    cssBundle.AddFile(<span style="color: #006080">&quot;~/content/site.css&quot;</span>);<br />    cssBundle.AddFile(<span style="color: #006080">&quot;~/content/themes/base/jquery.ui.all.css&quot;</span>);<br /> <br />    BundleTable.Bundles.Add(cssBundle); </pre>
<p></div>
<p>Vous allez désormais référencer ces regroupements dans votre page comme suit :</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">&lt;link href=<span style="color: #006080;">"~/Styles"</span> rel=<span style="color: #006080;">"stylesheet"</span> type=<span style="color: #006080;">"text/css"</span> /&gt;<br />&lt;script src=<span style="color: #006080;">"~/Scripts"</span> type=<span style="color: #006080;">"text/javascript"</span>&gt;&lt;/script&gt;  </pre>
<p></div>
<p>En exécutant la page précédente de votre application, vous obtenez le résultat suivant :</p>
<p><img src="http://blog.developpez.com/media/Webmatrixbundle7.png" width="565" height="313" alt="" /> </p>
<p>Et voilà, la taille de vos fichiers JavaScript passe de 558,9K à 5,7K, soit un taux de compression de près de 98 %.<br />
Vous pouvez également ajouter à votre regroupement tous les fichiers JavaScript d’un répertoire précis en procédant comme suit :</p>
<p>Et voilà, vous pouvez désormais améliorer assez simplement le temps de chargement des pages de votre application JavaScript grâce à la bibliothèque ASP. NET Optimization – Bundling.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Optimisation du temps de chargement d’une page ASP.NET MVC Part 2 : La mise en cache</title>
		<link>https://blog.developpez.com/lilroma/p11207/net/optimisation_du_temps_de_chargement_d_un</link>
		<comments>https://blog.developpez.com/lilroma/p11207/net/optimisation_du_temps_de_chargement_d_un#comments</comments>
		<pubDate>Wed, 08 Aug 2012 10:01:09 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC 3]]></category>
		<category><![CDATA[ASP.NET MVC 4]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour améliorer les performances de leur application, les développeurs ont couramment recours à l’optimisation côté client et côté serveur. L’optimisation d’une application Web regroupe l’ensemble des techniques qui peuvent aider à accélérer le temps de téléchargement d’une page Web. Parmi &#8230; <a href="https://blog.developpez.com/lilroma/p11207/net/optimisation_du_temps_de_chargement_d_un">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Pour améliorer les performances de leur application, les développeurs ont couramment recours à l’optimisation côté client et côté serveur. L’optimisation d’une application Web regroupe l’ensemble des techniques qui peuvent aider à accélérer le temps de téléchargement d’une page Web. Parmi ces techniques, on retrouve la minification et la compression du CSS et JavaScript, la mise en cache, l’utilisation des CDN, etc.</p>
<p>Ce billet est le second d’une série sur les techniques d’optimisation du temps de chargement d’une application ASP.NET MVC. Le premier article sur la compression et la minification du CSS et JavaScript peut être consulté sur <a href="http://blog.developpez.com/lilroma/p10462/net/asp-net/microsoft-web-optimisation-ou-comment-op/">cette page</a>.</p>
<p><span id="more-44"></span></p>
<p>Les requêtes des utilisateurs sur une page d’un site Web qu’il soit statistique ou dynamique engendre couramment le chargement de plusieurs éléments et de nombreuses opérations (chargement des images, CSS, JavaScript, données depuis une en base de données, etc.). Imaginez un intervalle de temps pendant lequel près de 100 requêtes sont effectuées sur votre site, et que durant cette période, le même contenu est retourné par votre application. Tout le long ce moment, votre application reprend 100 fois les mêmes opérations pour retourner un contenu identique.</p>
<p>La mis en cache est un procédé permettant d’améliorer considérablement le temps de chargement d’une page Web et économiser la bande passante, en évitant d’exécuter plusieurs fois certaines opérations (chargement des données, lecture d’une information dans la base de données, etc.) en stockant le contenu de cette page quelque part.</p>
<p><strong>Activer la mise en cache</strong></p>
<p>Le Framework ASP.NE MVC depuis la version 1 dispose d’un mécanisme pour la mise en a cache d’une application, qui repose essentiellement sur la même technique utilisée par ASP.NET. Il a été amélioré à partir de la version 3 pour coller avec les spécificités de la plateforme.</p>
<p>L’activation de la mise en cache se fait via l’attribut <strong>[OutputCache]</strong> qui peut être ajoutée soit individuellement à une action contrôleur, ou alors à une classe entière d&rsquo;un contrôleur</p>
<p>Le code ci-dessous permet de mettre en cache pendant 30 secondes la sortie de l’action Index.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[OutputCache(Duration = 30)] <span style="color: #008000">//mise en cache pour 30 secondes</span><br /><span style="color: #0000ff">public</span> ActionResult Index()<br />{<br />    ViewBag.Message = <span style="color: #006080">&quot;Cette page a été mise e cache à &quot;</span> + DateTime.Now;<br /><br />    <span style="color: #0000ff">return</span> View();<br />}<br /><br /></pre>
<p></div>
<p>Pour mettre en  cache une classe entière d’un contrôleur, il suffit de décorer la classe avec l’attribut OutputCache comme l’illustre le code ci-dessous :</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 400px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[OutputCache(Duration = 30)] <span style="color: #008000">//mise en cache pour 30 secondes</span><br />    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> HomeController : Controller<br />    {<br />       <br />        <span style="color: #0000ff">public</span> ActionResult Index()<br />        {<br />            ViewBag.Message = <span style="color: #006080">&quot;Cette page a été mise e cache à &quot;</span> + DateTime.Now;<br /><br />            <span style="color: #0000ff">return</span> View();<br />        }<br /><br />        <span style="color: #0000ff">public</span> ActionResult About()<br />        {<br />            ViewBag.Message = <span style="color: #006080">&quot;Your app description page.&quot;</span>;<br /><br />            <span style="color: #0000ff">return</span> View();<br />        }<br />}<br /></pre>
<p></div>
<p>Si vous exécutez ce code, vous vous rendrez compte que la date et l’heure affichées ne vont pas varier chaque fois que vous allez actualiser la page, jusqu’à ce que les 30 secondes soient écoulées.</p>
<p>NB: Il faut noter que le temps de sauvegarde des données de la page n’est pas garanti. En cas de manque de ressources mémoires, le cache va commencer à vider automatiquement son contenu.</p>
<p><strong>Personnaliser la mise en cache</strong></p>
<p>En dehors de la propriété Duration qui permet de définir le temps de mise en cache, d’autres propriétés dont il est important de connaitre sont disponibles pour vous permettre de personnaliser la mise en cache des données de votre page selon votre convenance et les spécificités de la page.</p>
<p><strong>Location</strong></p>
<p>La propriété location permet de définir l’emplacement pour enregistrer l’objet mis en cache. Il est possible d’enregistre l’objet mis en  cache sur le serveur, le client, les deux ou toutes les autres options de l’enum <strong>OutputCacheLocation</strong>. Les différentes valeurs qu’elle peut prendre sont :</p>
<p>&#8211; Any<br />
&#8211; Client<br />
&#8211; Downstream<br />
&#8211; Server<br />
&#8211; None<br />
&#8211; ServerAndClient </p>
<p>Par défaut, la valeur Any est utilisée lorsque cette propriété n’est pas spécifiée. L’orientation vers la mise en cache côté client, côté serveur ou les deux doit se faire suivant vos besoins. Si vous souhaitez afficher par exemple des informations personnalisées à l’utilisation comme son heure de connexion, son login, ses statistiques, etc. vous devez utiliser dans ce cas la mise en cache côté client.</p>
<p>Le code ci-dessous permet de mettre en cache la méthode d’action Index uniquement chez le client.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[OutputCache(Duration = 10, Location = OutputCacheLocation.Client)]<br /> <span style="color: #0000ff">public</span> ActionResult Index()<br /> {<br />     ViewBag.Message = <span style="color: #006080">&quot;Cette page a été mise en cache à &quot;</span> + DateTime.Now;<br /><br />     <span style="color: #0000ff">return</span> View();<br /> }<br /></pre>
<p></div>
<p><strong>VaryByParam</strong></p>
<p>Supposons un instant que vous voulez afficher les détails sur un produit à partir de son identifiant. Cela suppose qu’à chaque fois que l’identifiant du produit va changer, les détails affichés doivent également changer. Comment modifier la mise en cache pour que le contenu change automatiquement lorsque l’ID change. C’est à ce stade qu’intervient la propriété VaryByParam.  Cette propriété permet de créer différentes versions d&rsquo;un même contenu, dès que l&rsquo;un des paramètres du formulaire ou de l&rsquo;URL change. </p>
<p>Le code ci-dessous illustre comment vous pouvez l’utiliser.</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">[OutputCache(Duration = 3600, VaryByParam=<span style="color: #006080;">"id"</span>)]<br />        <span style="color: #0000ff;">public</span> ViewResult Details(<span style="color: #0000ff;">short</span> id)<br />        {<br />            Articles article = db.Articles.Find(id);<br />            <span style="color: #0000ff;">return</span> View(article);<br />        }</pre>
<p></div>
<p>En procédant ainsi, plusieurs versions du contenu de la méthode d’action sont mises en cache jusqu’à expiration de la période de mise en cache.</p>
<p><strong>Créer un profil de cache dans le Web.Config</strong></p>
<p>Le fichier de configuration de votre application peut être utilisé pour créer un profil un cache. L’utilisation de cette technique présente plusieurs avantages :</p>
<p>&#8211; vous pouvez créer un profil de cache et appliquer celui-ci à plusieurs actions ou contrôleurs.</p>
<p>&#8211; vous pouvez modifier le comportement de votre profil de cache dans le Web.config sans avoir besoin de recompiler votre application.</p>
<p>Par exemple, la section de configuration Web « caching » définit un profil de cache nommé MyCacheProfil. Cette section « caching » doit apparaître dans la section « system.web » du fichier Web.Config.</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">&lt;system.web&gt;<br />    &lt;caching&gt;<br />      &lt;outputCacheSettings&gt;<br />        &lt;outputCacheProfiles&gt;<br />          &lt;add name=<span style="color: #006080;">"MyCacheProfile"</span>  duration=<span style="color: #006080;">"60"</span> /&gt;<br />        &lt;/outputCacheProfiles&gt;<br />      &lt;/outputCacheSettings&gt;<br />    &lt;/caching&gt;<br />  &lt;/system.web&gt;</pre>
<p></div>
<p>Le contrôleur suivant illustre comment appliquer le profil MyCacheProfile sur une action contrôleur à l&rsquo;aide de l&rsquo;attribut [OutputCache].</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 200px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">[OutputCache(CacheProfile=<span style="color: #006080;">"MyCacheProfile"</span>)]<br />        <span style="color: #0000ff;">public</span> ActionResult Index()<br />        {<br />            ViewBag.Message = <span style="color: #006080;">"Cette page a été mise en cache à "</span> + DateTime.Now;<br /><br />            <span style="color: #0000ff;">return</span> View();<br />        }</pre>
<p></div>
<p>Le cache de sortie fournir un moyen simple pour améliorer radicalement les performances de vos applications ASP.Net MVC. Au travers de cet article, vous avez découvert comment vous pouvez utiliser cette technique. Restez connecté à mon blog pour la suite des astuces sur l’optimisation du temps de chargement d’une page Web.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Entity Framework : que faire face à l’erreur «new transaction is not allowed because there are other threads running »</title>
		<link>https://blog.developpez.com/lilroma/p11182/net/entity_framework_que_faire_face_a_l_erre</link>
		<comments>https://blog.developpez.com/lilroma/p11182/net/entity_framework_que_faire_face_a_l_erre#comments</comments>
		<pubDate>Fri, 27 Jul 2012 16:58:48 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC 3]]></category>
		<category><![CDATA[Entity Framework]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je travaillais il y a de cela quelques jours sur une application ASP.NET MVC 3, avec l’ORM Entity Framework. J’ai été confronté lors de l’écriture de mon code à l’erreur suivante : «new transaction is not allowed because there are &#8230; <a href="https://blog.developpez.com/lilroma/p11182/net/entity_framework_que_faire_face_a_l_erre">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je travaillais il y a de cela quelques jours sur une application ASP.NET MVC 3, avec l’ORM Entity Framework. J’ai été confronté lors de l’écriture de mon code à l’erreur suivante : «new transaction is not allowed because there are other threads running ». </p>
<p>Comme il n’est pas exclu que je tombe encore sur le même type de problème à l’avenir, je vais partager sur mon blog  &#8211; qui est avant tout mon rappel mémoire favori &#8211; les causes de cette erreur et comment contourner cela.</p>
<p><span id="more-83"></span></p>
<p><strong>Ce que j’essayais de faire dans mon application.</strong></p>
<p>Pour une facture, je voulais récupérer la liste des produits, et pour chaque produit, avoir  la fiche produit correspondante, y effectuer des modifications, ensuite appliquer la mise à jour à la base de données.</p>
<p>Le code source de cette partie est le suivant :</p>
<p>&#160;</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 400px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">var lp = from l <span style="color: #0000ff">in</span> db.Liste_produit.Include(l =&gt; l.Article)<br />         <span style="color: #0000ff">where</span> l.Id_facture == facture.Id_facture<br />         select l;<br /><span style="color: #0000ff">foreach</span>(Liste_produit liste_produit <span style="color: #0000ff">in</span> lp)<br />     {<br />       article = liste_produit.Article;<br />       <span style="color: #008000">//bla bla bla</span><br />       <span style="color: #008000">//bla bla bla</span><br />       db.Entry(article).State = EntityState.Modified;<br />       db.SaveChanges();<br />                        <br />     }<br /></pre>
<p></div>
<p>À l’exécution de ce code, au moment de l’enregistrement des modifications dans la base de données (db.SaveChanges()), l’exception ci-dessous est levée.</p>
<p><img src="http://blog.developpez.com/media/exception.png" width="580" height="317" alt="" /></p>
<p><strong>Les causes :</strong></p>
<p>Après avoir observé le problème de près et effectué quelques recherches, je me suis rendu compte que le souci était au niveau du foreach.</p>
<p>Il semblerait que pour la lecture de chaque élément dans « lp », la bouche ait recours à une transaction pour le Context en cours. Hor, lorsque j’appelle la procédure SaveChanges(), une nouvelle transaction veut être créée pour le même Context. Ce qui n’est pas autorisé par Entity Famework.</p>
<p><strong>Solutions</strong></p>
<p>De prime abord, j’ai opté pour la sauvegarde de mes données dans une IList. Ainsi, lors de la lecture de celles-ci, je n’aurais plus besoin d’avoir recours à une transaction.<br />
Le code que j’ai utilisé est le suivant :</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 400px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">var lp = from l <span style="color: #0000ff;">in</span> db.Liste_produit.Include(l =&gt; l.Article)<br />         <span style="color: #0000ff;">where</span> l.Id_facture == fa.Id_facture<br />         select l;<br />IList&lt;Liste_produit&gt; ListeP = lp.ToList();<br /><span style="color: #0000ff;">foreach</span>(Liste_produit liste_produit <span style="color: #0000ff;">in</span> ListeP)<br />   {<br />      article = liste_produit.Article;<br />      <span style="color: #008000;">//bla bla bla</span><br />      <span style="color: #008000;">//bla bla bla</span><br />      db.Entry(article).State = EntityState.Modified;<br />      db.SaveChanges();<br />                        <br />  }<br /></pre>
<p></div>
<p>Cette solution marche. Mais, côté performance, elle n’est pas du tout satisfaisante. Si la quantité de données est importante, imaginez un peu la consommation de la mémoire en chargeant toutes ces données dans une liste.</p>
<p>En tout cas, elle ne m’arrange pas.  J’ai donc opté pour une solution beaucoup plus simple et performante. J’ai simplement appelé la procédure SaveChanges() en dehors de la boucle et le problème a été résolu avec de meilleures performances.</p>
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border: solid 1px silver; cursor: text; margin: 20px 0px 10px 0px; max-height: 400px; overflow: auto; padding: 4px; width: 97.5%; direction: ltr; text-align: left;">
<pre id="codeSnippet" style="background-color: #f4f4f4; font-family: 'Courier New', Courier, Monospace; font-size: 8pt; line-height: 12pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;">var lp = from l <span style="color: #0000ff;">in</span> db.Liste_produit.Include(l =&gt; l.Article)<br />         <span style="color: #0000ff;">where</span> l.Id_facture == facture.Id_facture<br />         select l;<br /><span style="color: #0000ff;">foreach</span>(Liste_produit liste_produit <span style="color: #0000ff;">in</span> lp)<br />   {<br />      article = liste_produit.Article;<br />      <span style="color: #008000;">//bla bla bla</span><br />      <span style="color: #008000;">//bla bla bla</span><br />      db.Entry(article).State = EntityState.Modified;<br />   }<br />db.SaveChanges();<br /></pre>
<p></div>
<p>En procédant ainsi, j’apporte des modifications à l’entité dans le foreach, et c’est à la suite de cette instruction (lorsque la transaction a été bouclée) que j’appelle la procédure SaveChanges().</p>
<p>Voila le problème est résolu, et la prochaine fois que je serais face à ce problème (ce qui est fort probable), et que je ne me souviendrais plus de comment j’avais procédé (ce qui est également fort probable), je saurais ou chercher e premier ;).</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>[Article]Entity Framework : à la découverte de Code First Migrations</title>
		<link>https://blog.developpez.com/lilroma/p11158/net/article_entity_framework_a_la_decouverte</link>
		<comments>https://blog.developpez.com/lilroma/p11158/net/article_entity_framework_a_la_decouverte#comments</comments>
		<pubDate>Wed, 18 Jul 2012 09:30:59 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC 4]]></category>
		<category><![CDATA[Entity Framework]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un petit post pour annoncé la publication de nouvel article sur Code First Migrations, la nouveauté certainement la plus intéressante d&#8217;Entity Framework 4.3. Pendant le développement ou le cycle de vie d&#8217;une application, le développeur est très souvent confronté à &#8230; <a href="https://blog.developpez.com/lilroma/p11158/net/article_entity_framework_a_la_decouverte">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un petit post pour annoncé la publication de nouvel article sur Code First Migrations, la nouveauté certainement la plus intéressante d&rsquo;Entity Framework 4.3.</p>
<blockquote><p>Pendant le développement ou le cycle de vie d&rsquo;une application, le développeur est très souvent confronté à des situations pouvant entrainer des modifications de son modèle objet ainsi que de sa base de données. Avec Entity Framework, cette tâche peut s&rsquo;avérer assez complexe, voire frustrante pour certains.</p>
<p>Si vous voulez par exemple apporter une modification (ajout d&rsquo;une colonne) à une table de votre base de données, si vous vous limitez à définir uniquement la nouvelle colonne dans votre modèle, lors de l&rsquo;exécution de l&rsquo;application vous allez obtenir un message d&rsquo;erreur puisque le modèle ne correspond plus aux objets de la BD.</p>
<p>Il était cependant possible d&rsquo;ajouter quelques lignes de code dans le fichier Global.asax, permettant lors de la modification du modèle, de détruire et recréer automatiquement la base de données lors de la prochaine exécution de l&rsquo;application, avec comme conséquence directe la perte des données. Ce qui est inacceptable pour une base de données déjà en production.</p>
<p>Heureusement, Entity Framework 4.3 élimine ces contraintes avec la nouvelle fonctionnalité Code First Migrations, qui permet d&rsquo;appliquer avec souplesse les modifications du modèle sur la base de données, en réduisant les risques de pertes de données.</p></blockquote>
<p>L&rsquo;article complet est <a href="http://rdonfack.developpez.com/tutoriels/dotnet/entity-framework-decouverte-code-first-migrations/">disponible ici</a>.</p>
<p>Pour les commentaires, <a href="http://www.developpez.net/forums/d1243827/dotnet/acces-aux-donnees/entity-framework/entity-framework-decouverte-code-first-migrations/">ça se passe ici</a></p>
<p><strong>Bonne lecture</strong> <img src="https://blog.developpez.com/lilroma/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET MVC et Entity Framework : résoudre l’erreur  System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types</title>
		<link>https://blog.developpez.com/lilroma/p11148/net/asp_net_mvc_et_entity_framework_resoudre</link>
		<comments>https://blog.developpez.com/lilroma/p11148/net/asp_net_mvc_et_entity_framework_resoudre#comments</comments>
		<pubDate>Fri, 13 Jul 2012 10:22:03 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ASP.NET MVC 3]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Entity Framework]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Lors du déploiement de mon application ASP.NET MVC 3 chez un client, j’ai eu l’erreur « System.Reflection.ReflectionTypeLoadException » pendant l’exécution de celle-ci. Pourtant, l’application fonctionnait correctement sur ma machine de développement. En dehors d’un foutu message “Unable to load one &#8230; <a href="https://blog.developpez.com/lilroma/p11148/net/asp_net_mvc_et_entity_framework_resoudre">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lors du déploiement de mon application ASP.NET MVC 3 chez un client, j’ai eu l’erreur « System.Reflection.ReflectionTypeLoadException » pendant l’exécution de celle-ci. Pourtant, l’application fonctionnait correctement sur ma machine de développement.</p>
<p>En dehors d’un foutu message “Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information”, rien ne permet d’identifier clairement la source de cette erreur.</p>
<p><span id="more-43"></span></p>
<p>Après plusieurs recherches, il semblerait que l’erreur soit générée par Entity Framework. En effet, lorsque vous utilisez Entity Framework, celui-ci est configuré par défaut pour charger tous les types des assemblys référencées, afin d’identifier les différents types des entités pour votre modèle objet.  Si l’un des types ne peut être chargé, alors Entity Framework va générer cette erreur.</p>
<p>Il existe plusieurs solutions pour fixer ce problème :</p>
<p>&#8211; vous pouvez marquer la copie locale de toutes les assemblys référencées dans votre application à True ;</p>
<p>&#8211; dans une autre mesure, il suffit de supprimer toutes les DLL dans le dossier bin et procéder à une nouvelle génération de votre application.</p>
<p>&#8211; il est également possible que les bibliothèques System.Data.Entity et System.Web.Entity soient corrompues.  Pour mon cas par exemple, lors du déploiement de mon application, après investigation, je me suis rendu compte que les fichiers System.Data.Entity.dll et System.Web.Entity.dll avaient respectivement pour tailles 1640 Ko et 63 ko, pourtant dans le framework .NET, ces fichiers avaient pour tailles 4360 Ko et 135 Ko. En les remplaçant simplement avant le déploiement de l’application, cela a résolu ce bug.</p>
<p>Mais, le véritable problème ici, c’est d’identifier réellement l’assemblys qui pose problème. Pour cela, vous  pouvez simplement utiliser le code suivant :</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 600px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">try</span><br />{<br />    <span style="color: #008000">//Le code qui pose problème.</span><br />}<br /><span style="color: #0000ff">catch</span> (ReflectionTypeLoadException ex)<br />{<br />    StringBuilder sb = <span style="color: #0000ff">new</span> StringBuilder();<br />    <span style="color: #0000ff">foreach</span> (Exception exSub <span style="color: #0000ff">in</span> ex.LoaderExceptions)<br />    {<br />        sb.AppendLine(exSub.Message);<br />        <span style="color: #0000ff">if</span> (exSub <span style="color: #0000ff">is</span> FileNotFoundException)<br />        {<br />            FileNotFoundException exFileNotFound = exSub <span style="color: #0000ff">as</span> FileNotFoundException;<br />            <span style="color: #0000ff">if</span>(!<span style="color: #0000ff">string</span>.IsNullOrEmpty(exFileNotFound.FusionLog))<br />            {<br />                sb.AppendLine(<span style="color: #006080">&quot;Fusion Log:&quot;</span>);<br />                sb.AppendLine(exFileNotFound.FusionLog);<br />            }<br />        }<br />        sb.AppendLine();<br />    }<br />    <span style="color: #0000ff">string</span> errorMessage = sb.ToString();<br />   }<br /></pre>
<p></div>
<p>N’oubliez pas d’ajouter une référence à System.IO et System.Reflection;</p>
<p>Et voilà. Dorénavant, lorsque vous allez exécuter votre application et qu’il y’aura un problème avec le chargement d’un composant, vous aurez un message clair et les détails sur l’assembly qui pose problème.</p>
<p>À noter que ce bug n’existe plus lorsque l’on utilise Entity Framework avec le framework .NET 4.5, il ne scanne plus toutes les assemblys de l’application lors de son exécution.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WebMatrix 2 RC disponible</title>
		<link>https://blog.developpez.com/lilroma/p11100/net/webmatrix_2_rc_disponible</link>
		<comments>https://blog.developpez.com/lilroma/p11100/net/webmatrix_2_rc_disponible#comments</comments>
		<pubDate>Mon, 18 Jun 2012 01:12:04 +0000</pubDate>
		<dc:creator><![CDATA[Hinault Romaric]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[WebMatrix]]></category>
		<category><![CDATA[WebPages]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Dans la foulée des sorties de Visual Studio 2012 RC, Windows 8 Preview et le nouveau Windows Azure, Microsoft a également publié la Release Candidate de WebMatrix 2. Pour rappel, WebMatrix est un environnement de développement Web léger « tout-en-un &#8230; <a href="https://blog.developpez.com/lilroma/p11100/net/webmatrix_2_rc_disponible">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Dans la foulée des sorties de Visual Studio 2012 RC, Windows 8 Preview et le nouveau Windows Azure, Microsoft a également publié la Release Candidate de WebMatrix 2.</p>
<p>Pour rappel, WebMatrix est un environnement de développement Web léger « tout-en-un », robuste et surtout gratuit, développé par Microsoft. </p>
<p>Cette mouture qui marque une étape importante dans le cycle de développement de l’EDI s’aligne avec la vision de Microsoft : fédérer l’ensemble de la pile Web et des outils dont les développeurs ont besoin pour créer des applications Web au sein d’un outil.</p>
<p><img src="http://blog.developpez.com/media/webmatrixnode.png" width="556" height="292" alt="" /></p>
<p><span id="more-59"></span></p>
<p>WebMatrix 2 RC s’arrime au développement mobile en proposant des outils permettant de mettre sur pied facilement des applications Web Mobiles. Les modèles pour ASP.NET, Node.js et PHP ont été mis à jour pour être plus mieux adaptés pour un affichage sur les terminaux mobiles.  Le rendu des vus spécifiques en fonction des dispositifs (Tablette, iPhone, Windows Phone, etc..) est désormais possible.</p>
<p>L’EDI dispose par défaut des émulateurs allégés pour Windows Phone, iPad et iPhone, permettant d’avoir un aperçu rapide du fonctionnement de son site Web sur ces dispositifs. Des travaux sont en cours pour intégrer encore plus d’émulateurs.</p>
<p>Le support de JQuery Mobile est également au rendez-vous (auto-complexion, etc.). Plusieurs modèles de projets mobiles reposent sur la bibliothèque JavaScript.</p>
<p>La complexion de code pour HTML5, CSS3, JQuery est au menu. L’EDI repose sur la version 2 de WebPages qui dispose d’un nombre assez intéressant d’améliorations par rapport à la version 1.  Le support de Node.js est également au centre de la RC de WebMatrix 2, qui propose de nouveaux modèles de projets, l’IntelliSense pour Node.js et la coloration de code pour Jade/EJS. </p>
<p>WebMatrix 2 RC offre un support encore plus étroit de Windows Azure, la plateforme Cloud de Microsoft.  	  </p>
<p>WebMatrix 2 RC dispose d’un nombre assez impressionnant de nouvelles fonctionnalités par rapport à la bêta. Je viens à peine de commencer à jouer avec ces nouveautés, et je peux dire que je suis déjà assez impressionné et captivé par cet EDI que j’ai adopté depuis la sortie de la première version.<br />
Je reviendrais sur certains de mes billets de blog sur les nouveautés qui auront le plus attiré mon attention au fur et à mesure que je découvrir cette RC de WebMatrix 2.</p>
<p>&#8211; <strong><a href="http://aka.ms/webmatrix2blog">Télécharger WebMatrix 2 RC</a></strong></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
