Dal blog di Giorgio Sardo arriva la notizia che sono stati pubblicati i controlli ASP.NET per IE8. Questi controlli dovrebbero supportare lo sviluppatore ad implementare nei propri siti le feature specifiche di IE8 quali acceleratoes, webslice, etc.

Questi sono i controlli inclusi:

  • ASP.NET Web Slice control
  • ASP.NET Accelerator control
  • ASP.NET Visual Search control
  • ASP.NET Browser Helper control
  • Link: ASP.Net Controls for IE8 released!

     


    +


    Dopo essere entrato nella rosa dei Silverlight Insiders lo scorso Ottobre, quest'oggi mi è stato confermato il cambio di Expertise del mio MVP. Da oggi quindi esco dalla categoria ASP.NET, che pure lascio a malincuore visto che mi ha dato molte soddisfazioni, per entrare nella nuova categoria di Silverlight.

    Viste le mie attività più recenti credo che molti si aspettassero un tale passaggio. Personalmente sono molto soddisfatto di entrarvi, in qualità di primo e per ora unico Italiano, e colgo l'occasione per ringraziare il team di Silverlight - ma anche chiunque in abbia avuto un ruolo in questa scelta - oltre che per la valutazione positiva anche per l'incredibile lavoro che stanno facendo.

    Chi avesse bisogno di aiuto su Silverlight non ha che da chiamarmi oppure come fanno molti presentarsi sui forum di Silverlight dove recentemente ho iniziato a rispondere. (http://silverlight.net/members/codeblock.aspx)

    Naturalmente, il fatto che abbia cambiato categoria non mi impedirà di continuare ad essere attivo anche su altre tecnologie, ASP.NET, Entity Framework, C#, Linq, etc. Pertanto, tempo permettendo su queste pagine continuerete a vedere i miei post e snippet.

    Ancora grazie e Silverlight a tutti!


    Quest'oggi debuggando un po' alcune pagine web che fanno pesante uso del routing, io e ci siamo resi conto di un problemino che ne affligge l'uso. Pare che se gli url terminano con .aspx (e questo era proprio il nostro caso), non ci sia modo di vedere inizializzato il contesto della pagina. Il sintomo primario di questo comportamento è dato dalla mancata esecuzione degli handler nel global.asax, ma nel nostro caso si è rivelato perchè ci siamo trovati difronte alla mancanza completa di Session e ViewState.

    In rete si trovano alcuni post su questo problema, primo fra tutti quello su StackOverflow:

    http://stackoverflow.com/questions/218057/httpcontext-current-session-is-null-when-routing-requests

    Pare che l'unico workaround conosciuto a questo problema sia relativo l'uso di una estensione conosciuta a IIS e conseguentemente mappata sull'handler di asp.net, oppure l'uso del wildcard mapping (ovvero tutto passa per asp.net).

    Nel nostro caso l'applicazione stava girango su Vista con IIS7 e non abbiamo indicazioni in merito al problema su IIS6 o su un server di produzione, ma per fortuna non siamo arrivati fino a li... :)

    Va detto che ci siamo resi conto del problema con qualche difficoltà per il semplice motivo che nel contesto in cui stiamo lavorando abbiamo escluso per quanto possibile l'uso di session e viewstate (si tratta di una applicazione mobile), perciò credo che lavorando su pagine normali questo problema sarebbe emerso molto più facilmente.

    Technorati Tag: ,,

    Sono disponibili su BE-IT i webcast su ASP.NET Dynamic Data Controls che ho registrato lo scorso mese. Si tratta di 4 webcast di approfondimento sull'uso e la customizzazione dei controlli Dynamic Data introdotti con la SP1 del .NET Framework 3.5.

    Come sempre se avete domande o consigli basta che mi contattiate al messenger o via email.

    Link:

    Technorati Tag: ,,

    E’ necessario che faccia questo post per una rettifica a proposito della sessione sugli ADO.NET Data Services che ho tenuto durante la serata dei Community After Hour. Si tratta tutto sommato di due piccolezze ma per completezza devo dare qui la versione corretta:

    1. Qualcuno mi ha fatto notare una inesattezza. Durante la sessione ho detto che per generare il proxy necessario per interrogare il servizio da Silverlight 2.0 è obbligatorio usare il tool da riga di comando datasvcutil.exe. In realtà se provate a referenziare il servizio con una Service Reference vedrete che Visual Studio 2008 è in grado di accorgersi che di DataService si tratta e di conseguenza generare il proxy corretto. Purtroppo seguendo svariati post in merito questa caratteristica non viene mai menzionata e io stupidamente non ci ho nemmeno provato.
    2. Alla fine della sessione mi è stato chiesto se è possibile fare uso del protocollo WS-Security con un ADO.NET Data Service. Di primo acchito trattandosi di un servizio esposto con WCF si può avere l’impressione che la cosa sia possibile. Ma soffermandosi un po’ a pensare mi sarebbe venuto in mente immediatamente che gli standard WS-* sono basati su SOAP e di conseguenza non è certo pensabile che funzionino con JSON e AtomPub. Quindi la risposta giusta è “no, non è possibile”. L’unica cosa da fare per proteggere il servizio è usare SSL.

    Tutto qua. Non si tratta di questioni rilevanti, ma tutto sommato è meglio saperlo :)


    Ormai ci siamo. Domani sera saremo tutti al Community After Hour di Padova (allo Sheraton) per condividere qualche ora sugli argomenti caldi del momento. Le slide sono pronte, il codice anche, e tutto sommato dovrebbe essere pronto anche lo speaker dato che pur uscendo da un periodo di superlavoro sono riuscito a ritagliarmi il giusto tempo per preparare la sessione.

    Si parlerà di un argomento caldo: l'accesso ai dati da applicazioni RIA. L'argomento è molto sentito e non manca occasione perchè - oggi al messenger domani ad un evento - non mi senta rivolgere qualche domanda su questo "problema". Così la mia sessione sarà di carattere squisitamente pratico. Analizzeremo il problema dell'accesso ai dati così come è oggi e introdurremo una soluzione diversa che va nella direzione di risparmiare tempo sulle cose ripetitive che tipicamente sono la tomba della produttività.

    Soprattuto vedremo come l'investire tempo nell'apprendimento di nuove tecnologie quali sono l'Entity Framework e gli ADO.NET Data Services possa pagare velocemente in termini di risparmio sul lavoro senza per questo dimenticare le buone norme di programmazione e architetturali.

    Sarà una bella chiacchierata, che spero vi sia utile e che vi dia un impulso ulteriore - se ce n'è bisogno - nello sviluppo con Silverlight 2.0 e ASP.NET AJAX. E se la cosa vi piace vedremo di ripetere questa esperienza in qualche prossimo evento cercando di trovare sempre più il risvolto pratico e lasciare ad altri la mera enunciazione di nuove feature.

    Qui i dettagli: http://www.microsoft.com/italy/eventi/days/community/xedotnet.mspx


    Dopo il successo dello scorso 6 Marzo in questo mese ripeteremo la bella esperienza del Community After Hour. Il prossimo 23 Ottobre infatti troverete me e alcuni colleghi di XeDotNet al booth ATE dei Microsoft Days08 di Padova e alla sera potrete ascoltare le sessioni di , e di .

    Qui trovate l'agenda della serata: http://www.microsoft.com/italy/eventi/days/community/xedotnet.mspx

    L'argomento che affronterò durante la mia sessione sarà di sapore squisitamente pratico. Mi aspetto di avere poche slide, e una bella quantità di codice da vedere. L'accesso ai dati da applicazioni RIA è uno degli argomenti che mi viene richiesto spesso e volentieri, perciò ho deciso di mostrare un interessante connubio dato dall'Entity Framework e ADO.NET Data Services. Tramite essi saremo in grado di connetterci ad un database sia da Silverlight 2.0 che da AJAX. Si tratta di uno strumento efficace in questo contesto che consente di mantenere la suddivisione imposta da questo tipo di applicazioni che tipicamente non hanno accesso diretto alla base dati, ma nel contempo di evitare di scrivere decine di metodi di un webservice.

    Vi aspetto numerosi. Passeremo assieme un'oretta decisamente proficua che potrebbe farvi cambiare l'approccio nella realizzazione di molte applicazioni.

    Iscrizioni: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032391659&Culture=it-IT


    Se è vero che i nuovi Dynamic Data hanno il potere di far risparmiare parecchio tempo, è anche vero l'approccio che utilizzano spesso e volentieri è, per così dire, un po' "ottimistico". Con questo intendo che la molte volte le condizioni "ideali" che essi presuppongono non si verificano perciò bisogna lavorare un po' per piegarli alla propria volontà.

    E' il caso ad esempio di tabelle che contengono righe che devono essere filtrate in base al contesto in cui ci si trova. Pensiamo a una tabella che contenga i record di diversi utenti oppure di diverse aziende. E' obbiettivamente improbabile che chiunque possa vedere i record di un altro utente, ivi compresi magari quelli dell'amministratore delegato. E così anche nel caso di record di diverse aziende, in un sistema in ASP (Application Service Provider) questo modo di lavorare è inammissibile.

    Il fatto è che queste condizioni non sono proprio previste. Non c'è un modo ufficiale per ottenere un funzionamento adeguato a casi del genere. Bisogna invece scendere un po' più in pofondità nei template ed agire in almeno quattro punti

    1. Il template di pagina List.aspx ed eventualmente ListDetails.aspx
    2. Il template di pagina Insert.aspx
    3. Il template di field ForeignKey_Edit.ascx
    4. Lo user control FilterUserControl.ascx

    Poniamo ad esempio di voler introdurre un filtro per un ipotetico campo OrganizationID che identifica l'ente cui è associato il record. Dato per acquisito che esista una variabile in Sessione che indica la CurrentOrganization (incapsulata in un opportuno SessionManager), ovvero l'ente cui è associato l'utente loggato, ecco come dovremmo procedere.

    Template di Pagina List.aspx

    Il punto migliore dove intervenire in questo caso è l'evento OnSelecting della LinqDataSource. Questo evento viene sollevato un attimo prima di eseguire la query che restituirà i risultati da mostrare nella lista. Ecco il codice da inserire:

       1: protected void GridDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
       2: {
       3:     if (e.WhereParameters.ContainsKey("OrganizationID"))
       4:         e.WhereParameters["OrganizationID"] = 
       5:             SessionManager.CurrentOrganization;
       6:     else
       7:         e.WhereParameters.Add(
       8:             "OrganizationID", 
       9:             SessionManager.CurrentOrganization);
      10: }

    Questo codice non fa altro che cercare un parametro OrganizationID e valorizzarlo con la sessione. Qualora nei parametri di selezione questo attributo sia già presente andiamo a sostituire il valore con la session. Questo fa si che il criterio venga applicato arbitrariamente a tutte le query.

    Il template di pagina Insert.aspx

    Per questo template la soluzione è ancora più semplice. In effetti è sufficiente inserire nel markup un Parameter che aggiunga il valore nella Insert:

       1: <asp:LinqDataSource ID="DetailsDataSource" runat="server" EnableInsert="true">
       2:     <InsertParameters>
       3:         <asp:SessionParameter Name="OrganizationID" SessionField="CurrentOrganization" Type="Int32" />
       4:     </InsertParameters>
       5: </asp:LinqDataSource>

    Il template di field ForeignKey

    Questa è probabilmente la parte più complessa. Tra i field template ne esite uno che è deputato a mostrare gli elementi che fanno parte di una Foreign Key. Si tratta di una DropDownList che viene bindata ai valori della tabella relazionata. Purtroppo anche in una soluzione di questo tipo esiste sempre una situazione mista. Alcune chiavi devono subire il filtro per OrganizationID mentre altre no. Occorre quindi creare un field nuovo che io ho chiamato FilteredForeignKey. In particolare quello da sistemare è il FilteredForeignKey_Edit. Per creare il field bisogna duplicare e rinominare quello già esistente.

       1: /// <summary>
       2: /// Provides dictionary access to all data in the current row.
       3: /// </summary>
       4: /// <param name="dictionary">The dictionary that contains all the new values.</param>
       5: protected override void ExtractValues(IOrderedDictionary dictionary)
       6: {
       7:     // If it's an empty string, change it to null
       8:     string val = DropDownList1.SelectedValue;
       9:     if (val == String.Empty)
      10:         val = null;
      11:  
      12:     ExtractForeignKey(dictionary, val);
      13:  
      14:     if (dictionary.Contains("OrganizationID"))
      15:         dictionary["OrganizationID"] = SessionManager.CurrentOrganization;
      16: }
      17:  
      18: /// <summary>
      19: /// Populates the list control filtered.
      20: /// </summary>
      21: /// <param name="listControl">The list control.</param>
      22: protected void PopulateListControlFiltered(ListControl listControl)
      23: {
      24:     MetaTable table = this.ForeignKeyColumn.ParentTable;
      25:     IQueryable query = table.GetQuery();
      26:     query = query.Where("OrganizationID == @0", SessionManager.CurrentOrganization);
      27:  
      28:     if (table.SortColumn != null)
      29:         query = query.OrderBy(table.SortColumn.Name);
      30:  
      31:     foreach (object obj2 in query)
      32:     {
      33:         string displayString = table.GetDisplayString(obj2);
      34:         string primaryKeyString = table.GetPrimaryKeyString(obj2);
      35:         listControl.Items.Add(new ListItem(displayString, primaryKeyString.TrimEnd(new char[0])));
      36:     }
      37: }

    Dobbiamo agire in due punti: Il primo dove i controlli sono filtrati. Occorre qui sostituire il metodo di default (PopulateListControl) e crearne uno proprio che ho chiamato PopulateListControlFiltered. In secondo luogo bisogna assicurarsi che quando il valore viene estratto l'id dell'ente sia correttamente imputato. Lo user control dovrà poi essere associato ad una proprietà per mezzo dell'attributo UIHint.

    Lo user control FilterUserControl.ascx

    L'ultimo passo serve ad assicurarsi che nemmeno le DropDownList che filtrano le liste siano un punto in cui trovare record che non si dovrebbero vedere. Qui l'intervento è sul controllo FilterUserControl.ascx. Il metodo da applicare è esattamente lo stesso del precedente esempio salvo che dato che non dobbiamo editare allora il corrispondente ExtractValues non è necessario.

    Arrivato a questo punto devo far notare che i miei esempi si appoggiano alla libreria System.Linq.Dynamic che trovate all'interno degli esempi di Linq2SQL. Una volta apportate le modifiche che ho appena illustrato sarete in grado di aprire qualche nuova porta all'uso di questi comodi controlli. Chiaro che detto questo va precisato che per poterlo fare bisogna in qualche modo piegare il data model a questa esigenza. Infatti se non avete il campo OrganizationID su ogni tabella allora siete punto e a capo...


    ha annunciato che a breve diverrà un prodotto supportato da Microsoft e incluso nelle prossime release di librerie e prodotti (MVC Framework as esempio). Non solo, sarà disponibile anche una estensione dell'intellisense di Visual Studio 2008 SP1 che consentirà di avere l'intellisense per i metodi di query della apprezzata liberia.

    I'm excited today to announce that Microsoft will be shipping jQuery with Visual Studio going forward.  We will distribute the jQuery JavaScript library as-is, and will not be forking or changing the source from the main jQuery branch.  The files will continue to use and ship under the existing jQuery MIT license.

    e ancora

    We will also extend Microsoft product support to jQuery beginning later this year, which will enable developers and enterprises to call and open jQuery support cases 24x7 with Microsoft PSS.

    Direi una ottima notizia che va anche nella direzioni che molti auspicavano di integrare le librerie di terze parti piuttosto che riscriverle.