Visual Studio 2013 http://blogs.ugidotnet.org/PietroLibroBlog/category/Visual Studio 2013.aspx Visual Studio 2013 it-IT Pietro Libro pietro.libro@libero.it Subtext Version 2.6.0.0 EF 6.1 : What&rsquo;s new (3) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx <p>Supporto a “.ToString()” e “String.Concat()”, un esempio:</p> <pre class="csharpcode">var queryConcat = from c <span class="kwrd">in</span> db.Vehicles <span class="kwrd">where</span> <span class="kwrd">string</span>.Concat(c.EngineSize, c.HP).Equals(<span class="str">"1600110"</span>) select c; var queryToString = from c <span class="kwrd">in</span> db.Vehicles <span class="kwrd">where</span> c.HP.ToString().Equals(<span class="str">"110"</span>) select c;</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Abbiamo due Query LINQ che filtrano i dati in base a condizioni su stringhe, la prima “tira fuori” tutti i veicoli dove la concatenazione dei valori delle proprietà “EngineSize” e “HP” è uguale a “1600110”, mentre la seconda esegue un filtro su di un valore intero convertio in stringa. Se proviamo ad eseguire il codice in un ambiente con EF 6.0 otteniamo un’eccezione a runtime in tutti e due i casi:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_thumb.png" width="244" height="223" /></a></p> <p>Con EF 6.1 le query sono eseguite correttamente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_thumb_1.png" width="244" height="165" /></a></p> <p>Cosa succede dietro le quinte:</p> <pre class="csharpcode"><span class="kwrd">SELECT</span> [GroupBy1].[A1] <span class="kwrd">AS</span> [C1] <span class="kwrd">FROM</span> ( <span class="kwrd">SELECT</span> <span class="kwrd">COUNT</span>(1) <span class="kwrd">AS</span> [A1] <span class="kwrd">FROM</span> [DomusDotNet].[Vehicles] <span class="kwrd">AS</span> [Extent1] <span class="kwrd">WHERE</span> N<span class="str">'1600110'</span> = (<span class="kwrd">CASE</span> <span class="kwrd">WHEN</span> ([Extent1].[EngineSize] <span class="kwrd">IS</span> <span class="kwrd">NULL</span>) <span class="kwrd">THEN</span> N<span class="str">''</span> <span class="kwrd">ELSE</span> [Extent1].[EngineSize] <span class="kwrd">END</span> + <span class="kwrd">CAST</span>( [Extent1].[HP] <span class="kwrd">AS</span> nvarchar(<span class="kwrd">max</span>))) ) <span class="kwrd">AS</span> [GroupBy1] <span class="kwrd">SELECT</span> [GroupBy1].[A1] <span class="kwrd">AS</span> [C1] <span class="kwrd">FROM</span> ( <span class="kwrd">SELECT</span> <span class="kwrd">COUNT</span>(1) <span class="kwrd">AS</span> [A1] <span class="kwrd">FROM</span> [DomusDotNet].[Vehicles] <span class="kwrd">AS</span> [Extent1] <span class="kwrd">WHERE</span> N<span class="str">'110'</span> = <span class="kwrd">CAST</span>( [Extent1].[HP] <span class="kwrd">AS</span> nvarchar(<span class="kwrd">max</span>)) ) <span class="kwrd">AS</span> [GroupBy1]</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Da analizzare il funzionamento di “String.Concat(…)” con SQL Server 2012 per verificare la conversione in SQL con la funzione “nativa SQL” “<a href="http://technet.microsoft.com/en-us/library/hh231515.aspx" target="_blank">Concat</a>”.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101829.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx Thu, 27 Mar 2014 10:04:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101829.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101829.aspx EF 6.1 : What&rsquo;s new (2) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx <p>Altra <em>feature </em>introdotta, l’attributo “IndexAttribute” che ci permette di definire un indice su una o piu’ colonne. Ad esempio, per creare un indice (di nome “IX_FreeDailyKm”) sulla proprietà “FreeDailyKm” del nostro modello, scriviamo:</p> <pre class="csharpcode">[Index(<span class="str">"IX_FreeDailyKm_Clustered"</span>, IsUnique = <span class="kwrd">false</span>, IsClustered = <span class="kwrd">false</span>)] <span class="kwrd">public</span> <span class="kwrd">int</span> FreeDailyKm { get; set; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Mentre per creare un indice che insiste su due proprietà, è sufficiente utilizzare lo stesso nome come da esempio:</p> <pre class="csharpcode">[Index(<span class="str">"IX_Engine"</span>, 2)] <span class="kwrd">public</span> <span class="kwrd">string</span> EngineSize { get; set; } [Index(<span class="str">"IX_Engine"</span>, 1)] <span class="kwrd">public</span> <span class="kwrd">int</span> HP { get; set; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Utilizzando <em>EF migrations</em> per aggiornare il database, avremmo:</p> <pre class="csharpcode">CreateIndex(<span class="str">"DomusDotNet.Vehicles"</span>, <span class="str">"FreeDailyKm"</span>, name: <span class="str">"IX_FreeDailyKm_Clustered"</span>); CreateIndex(<span class="str">"DomusDotNet.Vehicles"</span>, <span class="kwrd">new</span>[] { <span class="str">"HP"</span>, <span class="str">"EngineSize"</span> }, name: <span class="str">"IX_Engine"</span>);</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Quindi, a livello di database:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-2_EA92/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-2_EA92/image_thumb.png" width="244" height="55" /></a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101825.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx Thu, 20 Mar 2014 17:49:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101825.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101825.aspx EF 6.1 : What&rsquo;s new (1) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx <p>Da qualche giorno è stata rilasciata in RTM la <a href="http://blogs.msdn.com/b/adonet/archive/2014/03/17/ef6-1-0-rtm-available.aspx" target="_blank">versione 6.1.0</a> di Entity Framework. Una delle novità piu’ interessanti è sicuramente la possibilità di utilizzare l’approcio  <em>Code First </em>partendo da un database esistente (potrebbe sembrare strano, ma se pensiamo ad un nuovo sviluppo potrebbe non esserlo). I “ferri” da utilizzare sono ovviamente  EF 6.0.1 e la nuova versione di EF Tools, “scaricabile” per VS 2012 e VS 2013 seguendo <a href="http://www.microsoft.com/en-us/download/details.aspx?id=40762" target="_blank">questo</a> link.</p> <p>Per un semplice test, apriamo VS 2013 (o 2012), magari creando un semplice progetto “Console” al quale aggiungiamo tramite NuGet i riferimenti a EF 6.0.1. Poi tasto destro sul progetto e “Add New Item”, e scegliamo “ADO.NET Entity Data model”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_1.png" width="244" height="170" /></a></p> <p>Il testo di “Name” infuenzerà il nome della classe “DbContext” generata. Dalla scheramata successiva (“Entity Data Model Wizard”) scegliamo “Code First model from Database”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_2.png" width="244" height="170" /></a></p> <p>Nella schermata successiva del Wizard verrà chiesta la connessione dati da utilizzare (eventualmente ne creiamo una nuova), nel mio caso, per i test ho utilizzato un DB di un evento “DomusDotNet”. L’ultimo passo è la scelta degli oggetti da “importare”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_8.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_3.png" width="244" height="219" /></a></p> <p>Dopo aver premuto “Finish” e qualche secondo di pazienza, VS aggiungerà all’alberatura del progetto, tutte le classi necessarie, una “buildata” per verificare che sia tutto a posto , e qualche riga di codice per verificare l’estrapolazione dati :</p> <pre class="csharpcode"><span class="kwrd">using</span> (CarRental db = <span class="kwrd">new</span> CarRental()) { System.Console.WriteLine(<span class="str">"There are {0} cars."</span>, db.Cars.Count()); System.Console.ReadKey(); }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101823.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx Thu, 20 Mar 2014 12:42:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101823.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101823.aspx Dynamic Data Provider per EF6 released http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx <p>Sono stati rilasciati in RTM, <em>ASP.NET Dynamic Data</em> e <em>EntityDataSource</em> per EntityFrameowrk 6. Per provare la nuova versione di <em>Dynamic Data</em> è sufficiente creare un nuovo progetto di tipo “ASP.NET Dynamic Data Entities Web Application”, ed installare tramite NuGet il package <em>Microsoft.AspNet.DynamicData.EFProvider</em>:</p> <p align="center"><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb.png" width="244" height="33" /></a></p> <p>Eventualmente forziamo la scrittura dei <em>Template</em> (“A” per sovrascrivere tutto):</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb_1.png" width="244" height="39" /></a></p> <p>Aggiungiamo in modalità <em>Code First</em> una semplice classe <em>Book </em>e relativo <em>DbContext</em>:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Book { <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Title { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Authors { get; set; } <span class="kwrd">public</span> <span class="kwrd">int</span> Pages { get; set; } } <span class="kwrd">public</span> <span class="kwrd">class</span> Db : DbContext { <span class="kwrd">public</span> DbSet&lt;Book&gt; Books { get; set; } <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnModelCreating(DbModelBuilder modelBuilder) { <span class="kwrd">base</span>.OnModelCreating(modelBuilder); } }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Nel <em>Global.asax</em> registriamo il nostro <em>DbContext</em>:</p> <pre class="csharpcode">DefaultModel.RegisterContext( <span class="kwrd">new</span> Microsoft.AspNet.DynamicData.ModelProviders.EFDataModelProvider(() =&gt; <span class="kwrd">new</span> Db()), <span class="kwrd">new</span> ContextConfiguration { ScaffoldAllTables = <span class="kwrd">true</span> });</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>F5, per vedere in azione il nostro <em>Data Site</em>:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb_2.png" width="244" height="156" /></a></p> <p>Discorso simile per l’utilizzo <em>dell’EntityDataSource</em> control.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101806.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx Mon, 03 Mar 2014 10:06:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101806.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101806.aspx Windows Azure WebJobs (parte 4) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/17/windows-azure-webjobs-parte-4.aspx <p>Per automatizzare tramite script il processo di creazione di un WebJob utilizzando <a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj156055.aspx" target="_blank">Windows Azure Power Shell</a> (Windows PowerShell ISE), i principali comandi da utilizzare sono:</p> <ul> <li><em>Add-AzureAccount</em>, che ci permette di autenticarci utilizzando <a href="http://www.windowsazure.com/en-us/services/active-directory/" target="_blank">Active Azure Directory</a> </li> <li><em>Get-AzureWebsite</em>, per avere una panoramica dei WebSites legati alla <em>subscription</em> con la quale siamo collegati </li> <li><em>Get-AzureWebsiteJob</em>, il quale ritorna le informazioni sul WebJob specificato dal paramentro <em>Name</em>  </li> </ul> <p align="center"><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-4_C607/image_4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-4_C607/image_thumb_1.png" width="244" height="70" /></a></p> <ul> <li> <em>New-AzureWebsiteJob</em>, il quale permette la creazione di un nuovo WebJob ed accetta in ingresso i seguenti parametri: <ul> <li><em>Name</em>, il nome del WebSite di riferimento </li> <li><em>JobName</em>, il nome del WebJob </li> <li><em>JobType</em>, la modalità di esecuzione del WebJob come descritto nel <a href="http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/05/windows-azure-webjobs-parte-1.aspx" target="_blank">primo post</a> relativo a questa serie </li> <li><em>JobFile</em>, il percorso dell’archivio compresso contenente tutti i file necessari all’esecuzione del Job </li> </ul> </li> <li><em>Remove-AzureWebsiteJob</em>, il quale rimuove il WebJob specificato ed necessita dei parametri: <em>Name</em>, <em>JobName</em> e <em>JobType</em> </li> </ul> <p>Per eseguire “Start&amp;Stop” del WebJob, possiamo utilizzare i comandi:</p> <ul> <li><em>Start-AzureWebsiteJob</em>, con parametri <em>Name</em>, <em>JobName</em> e <em>JobType</em> </li> <li><em>Stop-AzureWebsiteJob</em>, con parametri <em>Name</em> e <em>JobName</em> </li> </ul> <p>Se i comandi sopracitati non dovessero essere presenti nel tool (I WebJob sono in <em>Preview</em>) è sufficiente aggiornare la documentazione della guida:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-4_C607/image_6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-4_C607/image_thumb_2.png" width="244" height="64" /></a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101780.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/17/windows-azure-webjobs-parte-4.aspx Mon, 17 Feb 2014 10:02:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/17/windows-azure-webjobs-parte-4.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101780.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101780.aspx Windows Azure WebJobs (parte 2) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/06/windows-azure-webjobs-parte-2.aspx <p>Nella <a href="http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/05/windows-azure-webjobs-parte-1.aspx" target="_blank">prima parte</a> abbiamo visto come creare un’applicazione console ed utilizzarla per elaborare (ridimensionare) in modalità <em>Continuously</em> dei <em>Blob</em> contenenti immagini, caricati in un particolare <em>container</em> del nostro <em>storage</em>. L’applicazione non è stata fisicamente copiata su un Web Site di Azure, ma è stata eseguita “in locale” sfruttando gli <em>endpoint</em> allo <em>storage</em>. Per caricare il nostro processo su <em>Web Site</em> i passi da compiere sono pochi e semplici:</p> <ul> <li>Accedere al portale di Windows Azure (<a title="https://manage.windowsazure.com" href="https://manage.windowsazure.com">https://manage.windowsazure.com</a>)</li> <li>Se non presente, creare un nuovo Web Site:</li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_1.png" width="244" height="108" /></a></p> <ul> <li>Aprire il <em>Web Site</em> e visualizzare la sezione “Configure”:</li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_10.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_4.png" width="244" height="23" /></a></p> <ul> <li>Nella sottosezione “connection strings”, aggiungiamo la stringa di connessione “AzureJobsRuntime”:</li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_12.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_5.png" width="244" height="45" /></a></p> <ul> <li>Visualizziamo la sezione “WebJobs”:</li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_8.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_3.png" width="244" height="52" /></a></p> <ul> <li> <p>Prima di effettuare l’upload dell’eseguibile è necessario creare una cartella compressa contenente sia “.exe” che “.dll” necessari al corretto funzionamento dell’applicazione. E’ sufficiente creare un archivio “zip” partendo (ad esempio) dalla cartella Debug\Release del nostro progetto. A questo punto è sufficiente cliccare sul bottone “ADD”, assegnare un nome al nostro “WebJob”, specificare il percorso della cartella compressa ed infine la modalità di esecuzione:</p> </li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_14.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_6.png" width="233" height="244" /></a></p> <ul> <li> <p>Una volta caricato il file compresso, dovremmo avere una situazione simile alla seguente:</p> </li> </ul> <p align="center"><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_16.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_7.png" width="244" height="43" /></a></p> <ul> <li> <p>Il <em>Job</em> caricato è in stato “STOP”, per entrare in “RUNNING” è ncessario cliccare l’icona con la dicitura “START” in fondo alla pagina:</p> </li> </ul> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_18.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_8.png" width="244" height="31" /></a></p> <ul> <li> <p>Per testare che tutto funzioni correttamente è sufficiente utilizzare il tool <a href="http://azurestorageexplorer.codeplex.com/" target="_blank">Azure Storage Explorer</a> come visto nella prima parte.</p> </li> </ul> <p>Se avessimo optato per un’esecuzione <em>On Demand</em> del <em>Job</em> ci saremmo trovati in una situazione di questo tipo:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_20.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/Windows-Azure-WebJobs-parte-2_7AF8/image_thumb_9.png" width="244" height="194" /></a></p> <p>Dove per eseguire il processo si rende necessario cliccare l’icona con la dicitura “RUN ONCE”. Se si vuole invece provare la versione <em>Scheduled</em> è necessario attivare il servizio “Windows Azure Scheduler” tra quelli presenti in questa pagina: <a title="https://account.windowsazure.com/PreviewFeatures" href="https://account.windowsazure.com/PreviewFeatures" target="_blank">https://account.windowsazure.com/PreviewFeatures</a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101766.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/06/windows-azure-webjobs-parte-2.aspx Thu, 06 Feb 2014 12:22:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/06/windows-azure-webjobs-parte-2.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101766.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101766.aspx Windows Azure WebJobs (parte 1) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/05/windows-azure-webjobs-parte-1.aspx <p>Windows Azure mi appassiona veramente tanto e le nuove funzionalità  rilasciate (seppur in <em>alpha</em>) aumentano ancora di piu’  la voglia e volontà di adottare questa piattaforma. E’ il caso dei <em>WebJobs</em>, un nuovo SDK in versione <em>alpha</em> che permette di eseguire programmi e script ospitati nei <em>Web Site</em> di Windows Azure, “semplicemente” tramite upload di un file (ad esempio “.exe” o “.cmd” ) dato che tutto il “difficile” è onere del “WebJobs SDK”.</p> <p>Questa nuova <em>feature </em>permette di eseguire dei veri e propri <em>batch,</em> processi che normalmente impiegherebbero molto tempo per essere eseguiti, come ad esempio la riorganizzazione di file, invio di email, processamento di immagini o code (<em>Queue</em>). Un <em>batch </em>puo’ essere eseguito in tre modalità differenti:</p> <ul> <li>On-Demand (<em>a richiesta</em>) </li> <li>Continuously, il processo in background è sempre attivo “in attesa di fare qualcosa”, il <em>Trigger</em> per attivare il processo puo’ essere ad esempio la ricezione di un messaggio in una specifica coda oppure la creazione di un nuovo <em>Blob</em> </li> <li>Scheduled, vogliamo che il nostro processo esegua del lavoro ad una certa ora di uno o piu’ giorni della settimana (in modalità singola o ricorrente) </li> </ul> <p>Un piccolo scenario d’esempio: un task (sempre attivo) che <em>triggerato</em> al caricamento di un <em>Blob</em> (un file immagine) in uno specifico <em>container </em>(“inputcontainer”), lo elabora (ridimensiona l’immagine e ne cambia formato in “png”) e salva il <em>Blob</em> risultato in un altro <em>container</em> (“outputcontainer”).</p> <p>Per iniziare è sufficiente creare una nuova applicazione console C# ed aggiungere i <em>package</em> necessari traminte NuGet:</p> <p>PM&gt; Install-Package Microsoft.WindowsAzure.Jobs.Host –pre</p> <p>In <em>Program.cs</em> scriviamo il codice seguente:</p> <pre class="csharpcode"><span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args) { JobHost host = <span class="kwrd">new</span> JobHost(); host.RunAndBlock(); } <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> ProcessJob([BlobInput(<span class="str">@"inputcontainer/{name}"</span>)] Stream inputStream, [BlobOutput(<span class="str">@"outputcontainer/{name}"</span>)] Stream outputStream) { <span class="kwrd">using</span> (Bitmap inputImage = <span class="kwrd">new</span> Bitmap(inputStream)) { Image outputImage = <span class="kwrd">new</span> Bitmap(200, 200); <span class="kwrd">using</span> (Graphics g = Graphics.FromImage(outputImage)) { g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingMode = CompositingMode.SourceCopy; g.PixelOffsetMode = PixelOffsetMode.HighQuality; <span class="kwrd">using</span> (ImageAttributes imageAttributes = <span class="kwrd">new</span> ImageAttributes()) { Rectangle destRect = <span class="kwrd">new</span> Rectangle(0, 0, 200, 200); g.DrawImage(inputImage, destRect, 0, 0, inputImage.Width, inputImage.Height, GraphicsUnit.Pixel, imageAttributes); } } System.Drawing.Imaging.ImageFormat pngFormat = <span class="kwrd">new</span> System.Drawing.Imaging.ImageFormat(ImageFormat.Png.Guid); outputImage.Save(outputStream, pngFormat); } }</pre> <p> </p> <p>E’ abbastanza intuitivo che il “lavoro sporco” del <em>Task</em> è eseguito dal codice presente in <em>ProcessJob</em>, il quale verrà attivato (<em>BlobInput</em>) ogni volta che un nuovo <em>Blob</em> verrà caricato in “inputcontainer”. L’output è definito dall’attributo <em>BlobOutput</em>, nello specifico la creazione di un nuovo Blob (immagine 200x200) nel container “outputcontainer”. Il codice di ridimensionamento è <em>out of scope</em>. Il nome del <em>Blob</em> in ingresso sarà uguale a quello di uscita in base al pattern specificato dal token “{name}”.</p> <p>Chi si occupa di gestire i <em>Bindings</em>, di rimanere in “ascolto” e dei <em>Trigger</em> è la classe <em>JobHost</em> che puo’ essere inizializzata come specificato nel <em>Main</em>. In questo caso si suppone che l’A<em>pp.config </em>contenga le definizione delle due <em>ConnectionStrings</em> necessarie rispettivamente per lavorare con lo <em>Storage</em> di Azure (“AzureJobsData”) e con le attività di logging (“AzureJobsRuntime”):</p> <pre class="csharpcode"> <span class="kwrd">&lt;</span><span class="html">connectionStrings</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">="AzureJobsRuntime"</span> <span class="attr">connectionString</span><span class="kwrd">="DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY"</span><span class="kwrd">/&gt;</span> <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">="AzureJobsData"</span> <span class="attr">connectionString</span><span class="kwrd">="DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=ACCOUNT_KEY"</span><span class="kwrd">/&gt;</span> <span class="kwrd">&lt;/</span><span class="html">connectionStrings</span><span class="kwrd">&gt;</span></pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Altrimenti è necessario specificare il nome delle due stringhe di connessione tramite costruttore della classe <em>JobHost</em>. Le due connessioni possono coincidere ed ovviamente per eseguire l’esempio è necessario modificarle secondo il proprio account, sostituendo i valori di ACCOUNT_NAME e ACCOUNT_KEY.</p> <p>Il metodo “RunAndBlock()” esegue il <em>Task</em> nello stesso <em>Thread</em> attivo, mentre per utilizzare un <em>Background Thread</em> è necessario invocare il metodo “RunOnBackgroundThread()” (che ritorna immediatamente il controllo al chiamante). </p> <p>Per testare il tutto possiamo premere F5 e dopo qualche secondo, se tutte le configurazioni sono corrette, dovremmo ottenere una <em>console</em> simile alla seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb.png" width="244" height="126" /></a></p> <p>Questo implica che il nostro Job è in attesa di “fare qualcosa”. Per lavorare con lo storage di Windows Azure possiamo scaricare il Tool <a href="http://azurestorageexplorer.codeplex.com/" target="_blank">“Azure Storage Explorer”</a>. Una volta installato e configurato è possibile esplorare e modificare il nostro storage, nel mo caso, inizailmente abbiamo una situazione simile alla seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb_2.png" width="244" height="176" /></a></p> <p>Dopo aver selezionato la voce “inputcontainer” nella lista “Container”, scegliamo la voce “New” nella lista dei comandi “Blob”, specifichiamo il nome del nuovo <em>Blob</em> e premiamo “Create Blob”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_8.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb_3.png" width="244" height="176" /></a></p> <p>Dalla lista dei <em>Blob</em> presenti selezioniamo quello appena creato e scegliamo la voce “View” per visualizzarne i dettagli:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_12.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb_5.png" width="244" height="162" /></a></p> <p>Click su “Upload Image File” per caricare una nuova immagine ed attendere il completamento delle operazioni di upload. Rieseguendo la nostra applicazione, dopo qualche secondo, dovremmo ottenere una <em>console</em> di questo tipo:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_14.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb_6.png" width="244" height="126" /></a></p> <p>A questo punto ”outputcontainer” dovrebbe contenere un <em>Blob</em> con lo stesso nome di quello di input e contenente un immagine di dimensione 200x200px:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_16.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WebJobs_CCDC/image_thumb_7.png" width="244" height="135" /></a></p> <p>Nella seconda parte del post vedremo come caricare l’eseguibile direttamente in un nostro Web Site ospitato su Windows Azure.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101765.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/05/windows-azure-webjobs-parte-1.aspx Wed, 05 Feb 2014 18:32:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/02/05/windows-azure-webjobs-parte-1.aspx#feedback 2 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101765.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101765.aspx EF6 RTM Available http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx <p>Con il rilascio di VS 2013, puntuale anche il rilascio in RTM di Entity Framework 6, tutti i dettagli direttamente sul blog di <a href="http://blogs.msdn.com/b/adonet/archive/2013/10/17/ef6-rtm-available.aspx#!" target="_blank">ADO.NET</a>.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101699.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx Thu, 17 Oct 2013 16:25:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101699.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101699.aspx Disponibile EF 6 RC http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx <p>Rilasciata la RC di Entity Framework 6, tutti i dettagli e le novità rispetto alla Beta 1, <a href="http://blogs.msdn.com/b/adonet/archive/2013/08/21/ef6-release-candidate-available.aspx" target="_blank">qui</a>. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101644.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx Thu, 22 Aug 2013 09:25:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101644.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101644.aspx VS 2013 (Preview) : ASP.NET External Authentication http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/07/vs-2013-preview-external-authentication.aspx <p>Tra le novità di Visual Studio 2013 ed ASP.NET 4.5.1 , troviamo nuove opzioni per integrare applicazioni SPA (<em>Single Page Application</em>) e Web API (ma non solo) con servizi di autenticazione esterni basati su Social come Twitter, Facebook, Google e Microsoft Accounts o basati su OAuth/OPenID (tutto a vantaggio di noi sviluppatori). Vediamo con un esempio.</p> <p>Apriamo VS 2013 (Preview) e selezioniamo come template “ASP.NET Web Application”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb.png" width="244" height="131" /></a></p> <p>Scegliamo il progetto di tipo SPA  che di base utilizza HTML5, CSS3 e ASP.NET Web API (una semplice applicazione “Todo List”):</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb_1.png" width="244" height="153" /></a></p> <p>A questo punto il gioco è quasi finito, nella <em>Solution Explorer</em> apriamo il file <em>App_Start\Startup.Auth.cs</em> e decommentiamo la riga relativa “UseGoogleAuthentication”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb_2.png" width="241" height="244" /></a></p> <p>Eseguiamo l’applicazione con F5, e dalla schermata principale possiamo scegliere se autenticarci in modalità classica oppure utilizzando un servizio di autenticazione esterno (nello specifico “Google”):</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_8.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb_3.png" width="244" height="136" /></a></p> <p>Decommentando le opportune righe di codice è possibile offrire agli utenti piu’ servizi di autenticazione, ad esempio, per aggiungere anche “Microsoft Authentication” (è necessario possedere un account come developer qui : <a title="http://go.microsoft.com/fwlink/?LinkID=144070" href="http://go.microsoft.com/fwlink/?LinkID=144070">http://go.microsoft.com/fwlink/?LinkID=144070</a>)  modifichiamo il file di codice precedente aggiungendo “ClientId” and “Client Secret” come richiesto:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_14.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb_6.png" width="244" height="213" /></a></p> <p>Eseguiamo con F5, ed ecco il risultato:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_10.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/VS_7782/image_thumb_4.png" width="244" height="140" /></a></p> <p>Semplice, no ?</p> <p>Tutti gli approfondimenti del caso, sul sito di ASP.NET: <a title="http://www.asp.net/web-api/overview/security/external-authentication-services" href="http://www.asp.net/web-api/overview/security/external-authentication-services">http://www.asp.net/web-api/overview/security/external-authentication-services</a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101636.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/07/vs-2013-preview-external-authentication.aspx Wed, 07 Aug 2013 10:13:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/07/vs-2013-preview-external-authentication.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101636.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101636.aspx