ASP.NET MVC – Caricare un file JAVASCRIPT EMBEDDED.

25 luglio 2012

Appunto qui per ricordarmene in futuro (visto che dimentico tutto ultimamente). Ho realizzato una libreria di classi in cui, oltre ad oggetti C#, sono presenti diversi file JAVASCRIPT il cui contenuto è necessario perché le classi possano funzionare correttamente all’interno di un’APP MVC.

Come è possibile caricare questi file all’interno di un progetto di questo tipo? Con pochi è semplici passaggi il lavoro è fatto.

  1. Selezionare il file JAVASCRIPT che è necessario importare all’interno del progetto libreria.
  2. Dal menu contestuale (click destro del mouse), selezionare la voce Proprietà.
  3. Nella finestra delle Proprietà modificare Build Action: Embedded Resource.
  4. Nel file AssemblyInfo.cs della del progetto libreria aggiungere una nuova riga di codice:
    [assembly: System.Web.UI.WebResource("YourNamespace.Resource.js, "application/x-javascript")]

Questi passaggi bastano per poter incorporare la libreria all’interno di un’applicazione ASP.NET Web Forms utilizzando ClientScript.GetWebResourceUrl(Type, resourceName), con MVC è necessario eseguire ulteriori passaggi per poter rendere tutto funzionante. Realizziamo per questo scopo un oggetto con cui deve essere possibile ottenere l’URL dei file embedded molto semplicemente.

public static class ResLocator
{
	private const string UrlLocatorMethodName = "GetWebResourceUrlInternal";

	public static string Resolve(Type assemblyObjectType, string resourceName) 
	{
		MethodInfo resourceLocatorMethod = assemblyObjectType.GetMethod(UrlLocatorMethodName, 
			BindingFlags.NonPublic | BindingFlags.Static);
		string url = string.Format("/{0}", resourceLocatorMethod.Invoke(
			null,
			new object[] { Assembly.GetAssembly(assemblyObjectType), resourcePath, false })
		);

		return url;
	}
}

Il metodo Resolve accetta in input un Type che deve necessariamente riferirsi ad un tipo di oggetto contenuto nel progetto libreria e resourceName, cioè il nome della risorsa da includere. Successivamente, referenziando il namespace in cui è contenuto l’helper all’interno della nostra MasterPage, è possibile includere lo script di riferimento in questo modo:

<script 
	type="text/javascript" 
	src="@ResLocator.Resolve(typeof(SampleAssemblyObject), "YourNamespace.Resource.js)" />

Completati questi passaggi ed avviata la nostra applicazione MVC, il risultato dell’inclusione è simile a questo:

/WebResource.axd?d=HWyLh7g77XDqhYfNG0fioE3hSIzYB4uYmoUs3cJSuFRbnk9cZT1AWVuijZ81&t=634788092174760080

Spero possa essere utile anche ad altri per eventuali EMBEDDED RESOURCES!

Web Application Development – Web Communication

28 aprile 2012

Dopo moltissimo tempo torno a scrivere! Questa volta ho un preciso obiettivo. Molti dei post che pubblicherò d’ora in poi potranno sembrare scontati e semplici per qualcuno mentre per me rappresentano dei veri e propri appunti, a breve dovrò sostenere molti esami che mi permetteranno di ricevere diverse certificazioni in ambiente Microsoft, per questo motivo ho deciso di riportare qui un riassunto di ripassi/nuove conoscenze/curiosità/dubbi!

Oggi si parte con una panoramica delle attività svolte tra Client e Server per quanto concerne il funzionamento di una web application. Capire cosa accade durante la navigazione all’interno di un sito web è importante per poter meglio comprendere le mimiche che si nascondono dietro l’interazione con un server IIS. Un Web Browser (Client) ed un Web Server (Server) comunicano tra di loro utilizzando l’HTTP (Hypertext Transfer Protocol) che è un protocollo di rete assegnato alla porta 80, se il server è provvisto di un certificato, la comunicazione può avvenire su porta 443, in questo caso parliamo di HTTPS.

Tipicamente la comunicazione Client/Server prevede diverse operazioni:

  1. L’utente si collega al sito www.sample.com
  2. Il Browser attiva una connessione HTTP con www.sample.com ed inoltra un comando GET, questo comando tenta di accedere al path / (root del sito web) per cui, generalmente, è specificata una pagina di default da caricare. Tecnicamente il comando inoltrato assomiglia a questo:
    GET /
    host http://www.sample.com
  3. Il web server restituisce una risposta preceduta da un HTTP STATUS CODE che ne indica il tipo di contenuto (200 se è stata trovata una pagina web da visualizzare, 404 se la pagina non esiste, 302 se è stato effettuato un inoltro presso un’altra pagina etc. per ulteriori info sugli status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).

Volendo entrare nel merito delle attività, possiamo suddividere il lavoro svolto tra Client e Server, il client esegue una serie di operazioni volte alla preparazione ed inoltro/ricezione della richiesta al web server:

  1. Inoltra la richiesta al web server: se, come nell’esempio precedente, dobbiamo accedere a www.sample.com, il browser risolve l’indirizzo ed inoltra la chiamata per la richiesta della pagina.
  2. Autenticazione: se è attiva una connessione HTTPS, la richiesta deve contenere le informazioni necessarie per poter poi essere autenticata dal server.
  3. Elaborazione della risposta: quando il web server restituisce l’output della richiesta il web browser si occupa dell’elaborazione della risposta (es. se il web server ha restituito la pagina, il browser provvede a tradurla in elementi grafici, se invece sono restituiti particolari HTTP STATUS CODE, il web server si comporta nel modo più appropriato per poterli gestire).
  4. Esecuzione di codice Client Side (Scripts): se all’interno della pagina è presente del codice javascript, il browser si fa carico della sua esecuzione.

Questo processo è ripetuto ogni qual volta l’utente clicca su un bottone o seleziona un link. Il Server Web, come è facile immaginare, fa molto più del client. Una serie di processi sono innescati quando una richiesta HTTP arriva, tali processi, in parte operazioni di validazione, in parte comportamenti di contesto, concorrono alla preparazione dell’output finale da inoltrare al client. Quando una richiesta arriva sono eseguite diverse attività:

  1. Validazione: il server verifica che la richiesta sia correttamente strutturata, tale operazione si rende necessaria per evitare l’introduzione di richieste malformate che possono compromettere il corretto funzionamento del web server.
  2. Autenticazione: se la richiesta è in HTTPS (es. https://www.sample.com), è necessario autenticare la chiamata (il tutto avviene utilizzando il Secure Sockets Layer SSL).
  3. Autenticazione dell’utente: se è previsto un particolare meccanismo di autenticazione per l’utente, è necessario applicarlo, nel caso non siano presenti le credenziali necessarie per poter accedere, è visualizzata una maschera di login.
  4. Impostazione delle autorizzazioni dell’utente: successivamente è necessario impostare le autorizzazioni dell’utente, una serie di informazioni che indicano quali sono i permessi disponibili per il profilo connesso.
  5. Determinare come gestire la richiesta: a questo punto il server web deve capire in che modo interpretare ed eseguire la richiesta, se per esempio l’utente ha richiesto una pagina statica provvederà a restituirne il contenuto, se ha chiesto una pagina ASPX provvederà a servirla nel modo corretto.
  6. Gestione degli errori: se si verificano eventuali errori nel determinare il corretto percorso della richiesta, il server web cerca di fornire un dettaglio chiaro dell’errore che si è verificato (es. un Internal Server Error solitamente restituisce uno status code 500).
  7. Cache Output: il web server, provvede ad applicare anche meccanismi di cache con cui è possibile migliorare i tempi di risposta.
  8. Logging: per finire, tutte le operazioni eseguite per la chiamata, generalmente vengono loggate per questioni di sicurezza/monitoring.

La comunicazione descritta tra client e server è gestita mediante l’utilizzo di una richiesta. In ASP.NET è disponibile un oggetto, appunto Request, in cui sono raccolte tutte le informazioni che girano intorno a questa informazione. L’oggetto richiesta contiene informazioni sui Cookies, la cache, la scadenza delle pagine e molto altro. Tecnicamente parlando, il web server restituisce una risposta del genere:

HTTP/1.1 200 OK
Server: Microsoft-IIS/7.0
Content-Type: text/html
Content-Length: 154
<html><head><title>Hello World Sample</title></head><body><p>Hello World Sample Page!</p></body></html>
  • la prima linea indica il protocollo di comunicazione e le informazioni di stato (HTTP STATUS CODE).
  • la seconda linea contiene le informazioni sul tipo di web server che ha generato la risposta (Microsoft-IIS/7.0).
  • la terza linea (Content-Type) indica il tipo di contenuto erogato dal web server. Questo indicatore è anche conosciuto come MIME TYPE (Multipurpose Internet Mail Extensions). In questo esempio il MIME indica che il tipo di file è HTML.
  • la linea successiva contiene informazioni sulla grandezza effettiva del dato restituito.
  • ciò che è presente dopo è il dato vero e proprio che verrà trattato dal web browser in base alle specifiche del Content-Type.

Per ora può bastare, nel prossimo articolo: FORMS, POSTBACK e gestione degli HTTP METHODS.

ASP.NET MVC & Microsoft Chart Controls

7 novembre 2011

Ultimamente mi sono concentrato molto sull’utilizzo di ASP.NET MVC per lo sviluppo di un progetto abbastanza grosso, tra le varie cose è sorta l’esigenza di poter utilizzare uno strumento per la generazione di grafici di vario tipo.

All’inizio la mia scelta è ricaduta su “Libero API for Fusion Charts”, un prodotto fatto davvero molto bene e che offre la possibilità di implementare diverse tipologie di grafico (tante!). Nonostante le sue caratteristiche ho dovuto mettere da parte questa libreria in quanto legata all’utilizzo del componente Flash (sempre questioni di legacy).

Alla fine ho optato per la soluzione che poi si è rivelata anche la migliore (e ancora mi chiedo perché non ci ho pensato prima?). La scelta è ricaduta su “Microsoft Chart Controls”.

Partiamo dal presupposto che questo prodotto non si presta bene, se non dopo qualche piccolo accorgimento, per essere utilizzato con ASP.NET MVC. Infatti nasce per funzionare principalmente all’interno di applicazioni Web Forms, la cui struttura è nettamente diversa da quella di un progetto MVC. Essendo il chart un controllo Server, necessita di una pagina web di tipo System.Web.UI.Page in cui poter essere posizionato, sappiamo bene che in una pagina MVC non è possibile inserire controlli di questo tipo.

Oggi vorrei spiegarvi come configurare il vostro progetto MVC perché i Microsoft Charts possano funzionare correttamente e senza alcun tipo di problema.

Prima di tutto è necessario estendere le funzionalità dell’oggetto Page perché possa occuparsi anche del disegno dei grafici ms. Lo facciamo realizzando un helper come nell’esempio che segue:

namespace MvcApplication.Helpers
{
	public static class HelperCharts
	{
		public static void RenderChart(this Page page, System.Web.UI.DataVisualization.Charting.Chart chart)
		{
			var writer = new HtmlTextWriter(page.Response.Output);
			chart.RenderControl(writer);
		}
	}
}

Chiaramente le istruzioni che abbiamo scritto sono poche e semplici, ritengo in ogni caso che lavorare in questo modo garantisce una migliore leggibilità e pulizia del codice  e, soprattutto per quanto riguarda MVC, rispetto delle regole imposte dal pattern.

Completato il metodo dobbiamo assicurarci che tale funzionalità sia poi disponibile in tutte le Views e che la gestione dei Charts possa essere correttamente eseguita dal .Net Framework, per tale motivo è necessario il file web.config:

<configuration>
	<appSettings>
		<add key="ChartImageHandler" value="storage=file;timeout=20" />
	</appSettings>
	<system.web>
		<httpHandlers>
		<add path="ChartImg.axd" verb="GET,HEAD,POST" 
			type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
				System.Web.DataVisualization, Version=4.0.0.0, 
				Culture=neutral, PublicKeyToken=31bf3856ad364e35"
	        	validate="false" />
		</httpHandlers>
		<pages>
			<namespaces>
				<add namespace="MvcApplication.Helpers" />
			</namespaces>
		</pages>
	</system.web>
</configuration>

Come da documentazione è necessario aggiungere la chiave ChartImageHandler per definire le modalità di generazione del grafico (considerando che questo alla fine non è altro che un’immagine). Nell’elenco degli HttpHandlers è necessario configurare la risorsa utilizzata per la generazione dei grafici e, per concludere, volendo rendere visibile la funzione precedentemente scritta (RenderChart) in tutte le viste senza dover effettuare una import in ogni pagina del namespace, aggiungiamo all’elenco dei default namespaces anche quello in cui risiede il metodo da noi implementato.

In seguito possiamo realizzare un DTO fatto in questo modo:

namespace MvcApplication.Models.DTO
{
	public sealed class SampleDTO
	{
		public Chart Chart { get; private set; }

		public SampleDTO(Chart chart)
		{
			Chart = chart;
		}
	}
}

Possiamo ora creare un controller di esempio che dispone di un’Action che restituisce il DTO precedentemente realizzato:

namespace MvcApplication.Controllers
{
	using MvcApplication.Models.DTO;
	public class SampleController : Controller
	{
		[HttpGet] public ActionResult GetSampleChart()
		{
			Chart chart = new Chart();
			// Configure Chart...
			SampleDTO sampleDTO = new SampleDTO(chart);
			return View(sampleDTO);		
		}
	}
}

E per concludere si passa alla View che si presenta come nell’esempio:

<%@ Page 
	Title="Sample" 
	Language="C#" 
	MasterPageFile="~/Views/Shared/Shell.Master" 
	Inherits="System.Web.Mvc.ViewPage<MvcApplication.Models.DTO.SampleDTO>" %>
<h2>Chart Sample</h2>
<div>
<% 	Page.RenderChart(Model.Chart); >
</div>

Con poche righe, abbiamo realizzato quanto necessario per poter sfruttare in modo corretto e pulito i Microsoft Charts nel nostro progetto MVC.

Enjoy!

IIS – “Could not load file or assembly ‘Oracle.DataAccess’ or one of its dependencies. An attempt was made to load a program with an incorrect format.”

27 giugno 2011

In quest’ultimo periodo mi sono occupato dello sviluppo di un progetto basato su ASP.NET MVC ed Oracle. Per l’accesso ai dati abbiamo utilizzato Oracle.DataAccess, una libreria presente all’interno di un pacchetto di strumenti raggruppati sotto il nome di “Oracle Client”.

Nel dover rilasciare l’applicativo si è verificato un particolare problema all’interno del Web Server IIS ospitante. Provando a chiamare l’applicazione da Browser veniva visualizzato il seguente messaggio di errore:

Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Provando a cercare online una possibile soluzione al problema mi sono imbattuto in una serie di Post infiniti in cui vengono proposti particolari workground da applicare direttamente sul file web.config per risolvere un problema di riferimenti che si creano durante l’utilizzo della libreria. C’è da notare che questo problema non si verifica se si lavora con il server web Cassini integrato in Visual Studio.

Poi però ho trovato una soluzione meno invasiva a livello applicativo ma configurabile direttamente sul web server. In pratica per risolvere il problema è necessario apportare una piccola modifica al Pool Applicativo utilizzato per l’esecuzione dell’applicazione quando questa gira su un server a 64bit. Aprendo Internet Information Services Manager è possibile, all’interno della voce “Application Pools” configurare in maniera più dettagliata uno di questi pool selezionando la voce “Advanced Settings…” subito dopo averne selezionato uno.

Per l’applicazione MVC realizzata è stato scelto come pool predefinito “ASP.NET v4.0”, nelle opzioni avanzate ho spuntato la voce “Enable 32-Bit Applications” in modo tale da permettere l’esecuzione di codice a 32 ed a 64 bit insieme.

Rigenerando il pool e riavviando l’applicazione, il problema non si presenta più!

Windows Phone 7 – Installare NoDo

29 marzo 2011

Prima di continuare nella lettura di questa breve guida sono necessarie due considerazioni:

  1. è necessario avere molta pazienza perchè questo processo funzioni;
  2. il processo è stato testato da me personalmente dopo non pochi tentativi totalmente falliti;

In ogni caso se avete problemi o non vi è chiaro qualche passaggio potete lasciare un commento e provvederò a rispondere non appena possibile. Ora partiamo con la guida!

  • Scarichiamo USAIP.pbk dal seguente link e successivamente facciamo doppio-click sul file appena scaricato.
  • Nella finestra che ci viene proposta selezioniamo la connessione “EUROIP PPTP Hungary” ed inseriamo le seguenti credenziali di accesso:
    Username: demo
    Password: demo
    Attenzione: questa connessione viene automaticamente chiusa dopo 7 minuti quindi cerchiamo di fare in fretta e con attenzione le operazioni successive (in ogni caso è sempre possibile effettuare una riconnessione).
    Altra nota: se la connessione di rete non viene aperta, è necessario modificare il registro di sistema scaricando una patch (un file reg) dal seguente link, successivamente è necessario riavviare il computer perchè tutto funzioni correttamente (quindi ripetiamo il primo passaggio).
  • Ora sul nostro terminale Windows Phone disattiviamo la Connessione WIFI e ci assicuriamo che “Modalità Aereo” sia disattivata e “Rete Dati” sia attiva
  • Avviamo Zune e nello stesso tempo lasciamo la configurazione “rete dati” (sul dispositivo) aperta in modo tale da poterci operare velocemente (fare un fast siwtch On|Off).
  • Manualmente cerchiamo aggiornamenti da Zune (Settings ->Phone->Update)
  • Dopo qualche secondo (il tempo è molto variabile, leggendo i vari commenti su XDA Developers alcune persone hanno aspettato 10-15 secondi, altre dai 33 ai 35 ed altre ancora addirittura oltre i 55 secondi), io con il mio HTC HD7 ho aspettato 15 secondi(dopo aver effettuato ben 3 diversi tentativi con 3 tempi diversi e 3 ripetizioni per ogni range temporale) prima di disattivare la rete dati (rispettivamente le voci “Rete dati” e “Connessione 3G“).
  • Aspettiamo un’altro pò ed un popup sul nostro cellulare dovrebbe notificarci che un nuovo aggiornamento è disponibile!
  • Questi primi passaggi avranno sicuramente impegnato molto tempo (più o meno 7 minuti, io in totale sono andato oltre i 30 minuti prima di completare l’operazione, tempo in cui è stata effettuata più volte la riconnessione tramite pbk) quindi riattiviamo la connessione alla rete “EUROIP L2TP Hungary” ed ora, con molta calma, Zune procederà al download del primo aggiornamento ufficiale per Windows Phone 7!
  • Se non dovesse funzionare ripetiamo questo passaggio facendo attenzione al numero totale di secondi che aspettiamo ogni volta prima di disattivare la rete dati.

Lascio ad un altro giorno la mia recensione sull’HTC HD7 o più in generale su Windows Phone ma voglio concludere questo brevissimo post esponendo la mia opinione: quando ho comprato Windows Phone una delle caratteristiche che più mi attraeva (o che forse ho idealizzato io nella mia mente) era la poca frammentazione che questo sistema avrebbe creato (rispetto ad Android per esempio) o più in generale la facilità con cui un utente avrebbe potuto ricevere aggiornamenti sul proprio terminale senza dover aspettare o fare chissà cosa. Il fatto che io abbia scritto questo post è per me una delusione. Il primo update ufficiale è stato rilasciato quasi una settimana fà ed ancora oggi la maggior parte dei possessori di un Windows Phone riscontrano problemi nel reperire facilmente gli aggiornamenti (quindi non sto parlando solo di Italia).

In ogni caso spero che questa guida sia utile a voi tanto quanto lo è stata per me! Enjoy and stay tuned!

Fonte ufficiale: http://forum.xda-developers.com/showthread.php?t=1012189