WPF DynamicEntity for code-free Notification and DataValidation

Tue, 10 Apr 2012 12:51:00 GMT Visualizza

Ciao a tutti

 

Usare XAML con modelli ed entità complesse o meno è spesso tediante

Servono tante implementazioni, prima fra tutte INotifyPropertyChanged, spesso tediante da mettere a tappeto

Poi IDataErrorInfo per la validazione offre altro lavoro al programmatore che spesso ha bisogno di semplici classi POCO giusto per contenere da qualche parte le proiezioni dei propri dati

 

Un componente semplice per facilitare tutto questo è http://code.msdn.microsoft.com/WPF-DynamicEntity-for-code-acb9c2fe

grazie a questo componente, ad esempio, una POCO Person diventerà così:

 

[NotificableProperty("Name", typeof(string), true, 20)]
[NotificableProperty("Surname", typeof(string), true, 20)]
[NotificableProperty("Age", typeof(int))]
public class PersonModel : NotificableEntity
{
    //a readonly property
    public string FullName()
    {
        return string.Format("{0} {1}", dthis.Name, dthis.Surname);
    }

    //a writable property getter
    public string CommmaSeparatedFullName()
    {
        return string.Format("{0}, {1}", dthis.Name, dthis.Surname);
    }

    //a writable property setter
    public void CommmaSeparatedFullName(string arg)
    {
        try
        {
            var s = arg.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());
            dthis.Name = s.First();
            dthis.Surname = s.Last();
        }
        catch (Exception)
        {
        }
    }

    //a custom validation
    protected override bool CustomValidation(string propertyName, out string errorMessage, object value)
    {
        if (propertyName == "Age" && Convert.ToInt32(value) > 100)
        {
            errorMessage = "Age exceded maximum value";
            return false;
        }
        else
            return base.CustomValidation(propertyName, out errorMessage, value);
    }
}

 

si accettano feedback Sorriso

a presto

WCF (O)Data Services + IoC Validation and Business Logic + Transactions + Role/User Based Authorization and Row Filtering

Sun, 11 Mar 2012 17:26:00 GMT Visualizza

Ciao a tutti

 

tempo fa avevo parlato dei Data Services di WCF http://dotnetlombardia.org/b/tonyexpo/archive/2011/07/13/wcf-data-services-questo-immaturo.aspx una volta detti ADO.NET Data Services

 

La soluzione è pratica negli scenari di DaaS (data –as-a-service) dove è necessario un tier (layer fisico) di servizi per accedere per accedere ai propri dati, nell’ottica principalmente di applicazioni datadriven, o domain-driven non SOA

mi spiego: un sistema n-tier di grandi dimensioni  si rifà al SOA (service oriented architecture) per fornire un insieme di servizi omogenei e autonomi che nell’insieme realizzano il proprio sistema informativo

questo è altamente scalabile e modularizzato

e la business-logic risiede esclusivamente nei servizi, ognuno dei quali, ha in genere il proprio motore di persistenza SQL o NOSQL che sia

 

differentemente device e smartphone portano lo sviluppo software ad andare sempre più obbligatoriamente verso design-pattern enterprise di disegno della UI come MVC (iOS) e MVVM (windows phone) che ben si prestano a gestire anche completamente la business-logic, quando questa è di complessità non troppo vasta (in genere con l’ausilio di design-pattern propri da usare nel tier del device come active-record, etc)

in questi casi creare un tier di servizi che facciano semplicemente copia-incolla dei dati dal motore di persistenza all’XML è quasi inutile

così sono nati i servizi OData (attualmente molto usati anche in ottica OGDI) che servono a fornire un tier di disaccoppiamento al motore di persistenza (che per WCFDS è basato su EF4.x)

in pratica, è come usare entity framework a distanza con pro come le query che vengono convertite automaticamente in SQL sul proprio motore di DB

 

per avere un sistema robusto, però, è necessario avere anche transazioni, logiche di intercettazione delle operazioni con validazioni e logiche di business (del tipo modifiche aggiuntive, conversioni, etc),  e role-based authorization a tappeto, o riga-per-riga, magari tutte funzionanti in ottica IoC (facilmente convertibile in plugin)

tutte cose che se fatte in un WCF normale, sarebbero fonte di tante righe di codice, invece qui sono abbastanza semplici, ed ho predisposto un completo esempio di codice con tutte le funzionalità descritte:

 

  • SQL Express DataBase (App_Data)
  • EntityFramework 4.0 DB-First EDM (supports up to 4.3 code-first design)
  • IoC (inversion of control) / dependency injection execution pattern core engine
  • IoC /dependency injection based module for validation, row-filtering and business logic
  • Role/user based authorization with PrincipalPermission (Imperative/Declarative) checks for update/read
  • Row-filtering role/user based authorization enabled (with examples)
  • WCF Data Service (REST/OData HTTP/s)
  • DTC/LTM Transactions execution injection
  • Exception Bubling to DataService clients
  • T4 Templates for Data Service Extensions

 

DOWNLOAD DAL SITO MSDN

 

a presto

ASP.NET Chart Storages & Custom Storage cone IChartStorageHandler per scenari webfarm/webgarden e Windows Azure

Sat, 03 Mar 2012 11:07:00 GMT Visualizza

l’ASP.NET Chart control è un controllo per generare grafici in applicazioni web molto potente

Questo il suo funzionamento:

1) la sorgente dati viene processata per generare il grafico

2) il grafico viene renderizzato in immagine png/jpg/bmp/emf (si può scegliere cambiando la proprietà ImageType sugli oggetti asp:Chart

3) l’immagine viene messa in un luogo temporaneo: in sessione utente, in un path di temp locale, in memoria

4) un nome random viene dato ad ogni immagine

5) il browser cercherà di leggerle ed un custom HttpHandler andrà a rileggere l’immagine dallo storage TEMP per ritornare il grafico corretto

 

il controllo Chart si imposta negli appsettings. es:

<appSettings>

<add key="ChartImageHandler" value="storage=file;timeout=20;dir=c:\TempImageFiles\;" />

</appSettings>

 

la proprietà storage è la più importante. questa la sua spiegazione su MSDN:

  • file: Store the rendered chart images as temporary files. You must also specify the storage location in the url or dir parameter. In a server cluster or a multiple-process site, you must specify the dir parameter.

  • memory: Store the rendered chart images in the memory space of the running process. Do not use this option in a server cluster or a multiple-process site.

  • session: Store the rendered chart images in a session variable.

 

l’uso della memoria è da preferire in casi di single-server

in casi di webfarm o di windows azure le cose si complicano: se abbiamo la sessione impostata su di un DB SQL allora possiamo usare la sessione, altrimenti rimane solo un path di temp su una SAN o NAS visibile da tutti i server di front-end

 

nel caso specifico di Windows Azure però, abbiamo anche alcune possibilità aggiuntive non supportate automaticamente dal Chart: un blob storage, ed una cache di AppFabric usabile come provider del SessionState, o direttamente connessa alla configurazione del Chart

in questi casi, implementare IChartStorageHandler ci da la flessibilità richiesta. vediamone 2 esempi:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.DataVisualization.Charting;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Web.SessionState;
using System.Threading;
using System.Diagnostics;
using Microsoft.IdentityModel.Claims;
using Microsoft.ApplicationServer.Caching;

 

public class ChartBlobStorageImageHandler : IChartStorageHandler
{
    CloudStorageAccount account;
    CloudBlobClient client;
    CloudBlobContainer container;

    public ChartBlobStorageImageHandler()
    {
        //wire up azure
        account = new CloudStorageAccount(new StorageCredentialsAccountAndKey("[BLOBNAME]", "[BLOBKEY]"), false);
        client = account.CreateCloudBlobClient();
        container = new CloudBlobContainer("chartcontainer", client);
        container.CreateIfNotExist();
    }

    private string GetUri(string key)
    {
        var p = HttpContext.Current.User as ClaimsPrincipal;
        var i = p.Identity as ClaimsIdentity;
        var id = i.Claims.FirstOrDefault(x => x.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
        return string.Format("{0}/{2}_{1}", container.Uri, key, id.Value);
    }

    public void Delete(string key)
    {
        CloudBlob image = container.GetBlobReference(GetUri(key));
        image.Delete();
    }

    public bool Exists(string key)
    {
        CloudBlob blob = container.GetBlobReference(GetUri(key));
        try
        {
            var s = blob.OpenRead();
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

    public byte[] Load(string key)
    {
        CloudBlob blob = container.GetBlobReference(GetUri(key));
        return blob.DownloadByteArray();
    }

    public void Save(string key, byte[] data)
    {
        CloudBlob image = container.GetBlobReference(GetUri(key));
        image.UploadByteArray(data);
    }
}

 

vediamo l’esempio con l’AppFabricCache, la configurazione da incollare nel proprio .config viene scaricata direttamente dal portale di Windows Azure

 

public class ChartAppFabricCacheImageHandler : IChartStorageHandler
{
    private DataCache Cache = new DataCacheFactory(new DataCacheFactoryConfiguration("SslEndpoint")).GetCache("default");

    private string Key(string key)
    {
        var p = HttpContext.Current.User as ClaimsPrincipal;
        var i = p.Identity as ClaimsIdentity;
        var id = i.Claims.FirstOrDefault(x => x.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
        return string.Join("|", id.Value, key);
    }

    public void Delete(string key)
    {
        Cache.Remove(Key(key));
    }

    public bool Exists(string key)
    {
        return Cache.Get(Key(key)) != null;
    }

    public byte[] Load(string key)
    {
        return Cache.Get(Key(key)) as byte[];
    }

    public void Save(string key, byte[] data)
    {
        Cache.Add(Key(key), data, TimeSpan.FromMinutes(1));
    }
}

 

questi due esempi, rendono particolarmente flessibile l’uso del controllo Chart su scenari WebFarm e Windows Azure

per usare poi il proprio comportamento custom, basta modificare l’appsetting:

 

<add key="ChartImageHandler" value="handler=MYNAMESPACE.ChartAppFabricCacheImageHandler, MYNAMESPACE;timeout=60;" />

 

a presto

Could not establish trust relationship for the SSL/TLS secure channel

Sat, 18 Feb 2012 19:26:00 GMT Visualizza

Ciao

 

in produzione non è assolutamente consigliato disabilitare in qualche modo la validazione di un certificato X509, ma durante lo sviluppo, spesso non si possono avere certificati sempre validi localmente, ancora di più quando usando emulatori come quello per Windows Azure hai un IP variabile che comporterebbe l’uso di un certificato diverso ad ogni nuovo IP

 

semplicemente è possibile disabilitare la validazione eseguendo questo codice:

 

using System.Net;

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(
    (a, b, c, d) =>
    {
        return true;
    });

 

 

questo codice modificherà la validazione del vostro certificato, validandolo sempre!

ATTENZIONE: togliere sempre questo codice in applicazioni in produzione o comunque la cui sicurezza non è trascurabile

 

a presto

Cloud Monitor & Home Framework @ Community Days 2012

Fri, 17 Feb 2012 18:02:00 GMT Visualizza

Ciao

 

oggi durante il laboratorio su Windows Azure ed il Cloud Computing sono stati felicemente testati WCF Home Framework e Free Cloud Monitor

per chi non lo sapesse: Home Framework è un facilitatore sullo sviluppo di WCF per il Cloud Computing

mentre Free Cloud Monitor è una console di diagnostica di Windows Azure con trace e grafici sulle performances

 

questi i link:

WCFHF: https://homeframework.tnxconsulting.com

CloudMonitor: http://freecloudmonitor.cloudapp.net

 

a presto

Windows Azure & Email! Mai così semplice inviare mail dal cloud

Wed, 25 Jan 2012 15:50:00 GMT Visualizza

ciao a tutti

 

SendGrid è un componente eccezionalmente valido se si realizzano applicativi online (ancor meglio Cloud) che necesitano di inviare Email in quantità

 

per registrarsi (altrimenti è impossibile inviare mails) andate: http://sendgrid.com

 

mentre per scaricare il codice necessario per farlo, andate come sempre su NugGet (http://nuget.codeplex.com/) cercando Sendgrid

image

 

 

un po di codicello:

 

SendGridMail.SendGrid message = SendGridMail.SendGrid.GenerateInstance();
message.AddTo("destinatario@domain.it");
message.From = new System.Net.Mail.MailAddress("mittente@domain.it", "Mario Rossi");
message.Subject = "Test :)";
message.Text = "Ciaooooooooooooooo";

//l'SDK mi genera il client SMTP dal mio account sendgrid
var transport = SendGridMail.Transport.SMTP.GenerateInstance(new System.Net.NetworkCredential("username", "password"), port : SendGridMail.Transport.SMTP.SslPort);


//invia la mail
transport.Deliver(message);

 

e tutto funzionerà Sorriso

Dotnetlombardia @ Intel AppUp Day!

Wed, 25 Jan 2012 12:15:00 GMT Visualizza

Ciao a tutti

 

vi ringrazio per la grande presenza all’Intel AppUp Day, in Intel Italia ad Assago – Milano

 

E’ sempre bello quando un evento community viene seguito da tante persone

Intel poi è un nuovo partner sia della nostra community che del mondo Microsoft grazie anche all’ottimo marketplace che è l’AppUp e questa che era il nostro primo evento insieme non poteva andare meglio di così

 

Oggi Roberto è a Bologna insieme ai nostri amici di DotDot per una seconda tappa dell’AppUp Day! In bocca al lupo!! Sorriso

 

la mia sessione di ieri era sullo sviluppo Windows (Forms e WPF)

Qui trovate i vari esempi (principalmente WPF) per binding, validazione, convertitori, elaborazione asincrona, etc…

 

ci vediamo ai CommunityDays di fine mese Sorriso

a presto

Silverlight SlSvcUtil & StackOverflowException

Mon, 23 Jan 2012 17:27:00 GMT Visualizza

ciao a tutti

 

sfortunatamente slsvcutil (WCF Client-Proxt Generation Utility) per silverlight ha un problema quando la si esegue con una lingua di sistema diversa da EN (come noi italiani che usiamo Windows in inglese con tastiera italiana)

per risolvere, basta creare un file slsvcutil.exe.config da mettere nello stesso path del .exe

in genere: C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Tools

 

nel file copiare:

<configuration>
  <satelliteassemblies>
    <assembly name="SlSvcUtil, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </satelliteassemblies>
</configuration>

ed il gioco è fatto Sorriso

 

a presto

DEV WPF Senior CERCASI–Parma - 40 giorni

Fri, 20 Jan 2012 14:04:00 GMT Visualizza

Ciao

 

mi è stato chiesto di cercare un DEV su WPF con esperienza per un’attività piccola di 40 giorni su Parma

chiunque interessato è pregato di contattarmi ASAP

info@antonioesposito.it

 

grazie Sorriso

Quanto ripaga una certificazione?!?!? Tanto, stando ad un’analisi americana

Wed, 14 Dec 2011 07:47:00 GMT Visualizza

Ciao a tutti

 

ebbene si! le certificazioni ripagano!

Anche se in Italia non tanto come in USA, dove sembra che un DEV certificato si aggiri su cifre da 110.000$ (circa 85.000€) all’anno… comunque non non siamo del tutto da meno a mio modesto parare, l’unica cosa che ci rimane (a noi certificati) è prendere spunto dai confratelli americani, e spingere anche qui da noi affinché l’importanza di una certificazione cresca sempre più!!

 

http://www.networkworld.com/slideshows/2011/112111-survey-it-certifications-lead-to-jobs.html

Nuova UI di Billing per Windows Azure, adesso è davvero semplice tenere sotto controllo i costi

Tue, 13 Dec 2011 18:35:00 GMT Visualizza

Ciao a tutti

le novità su Azure ultimamente sono tantissime, e si susseguono ogni giorno, tra le varie, anche la maschera consuntiva delle spese è stata finalmente aggiornata!

Ricordate quella pagina con una semplice riga azzurra in alto con il vostro abbonamento ed il vostro attuale saldo!!?!?? Scordatevela!!! Sorriso

 

Ecco la nuova:

image

 

per tutti raggiungibile semplicemente con: https://account.windowsazure.com/subscriptions

La semplicità fatta servizio, WCF & Username+Password

Sun, 11 Dec 2011 19:46:00 GMT Visualizza

Ciao a tutti

DEMO

capita ancora di trovare soluzioni di sicurezza custom, dove per custom intendo molto spesso poco sicure, a vantaggio della semplicità

comprendo che chi non ama come me WCF odia il .config Sorriso ma in realtà mettere su un sistema sicuro di messaggistica con username e password gestiti a modo nostro, è tutt’altro che difficile

PASSO 1: creiamo il nostro servizio

a) Creo un nuovo progetto “Empty Web Application” e dentro aggiungo un WCF Service con nome di default Service1

b) sostituisco il DoWork autogenerato con un GetString molto semplice:

IService1:

[OperationContract]
string GetString();

Service1:

public string GetString()
{
    return "Ciao :)";
}

 

a questo punto abbiamo il nostro WCF, dobbiamo aggiungere la sicurezza

PASSO 2: creazione del certificato per instaurare un canale sicuro

a) apro il prompt dei comandi di visual studio, nella sottocartella “Visual Studio Tools” nel menù Start

b) lancio “makecert -r -pe -n "CN=Service1Certificate" -sky exchange -sr LocalMachine –ss My”, dove Service1Certificate è il nome del certificato che gli vogliamo dare

c) per vedere il nostro certificato, posso andare in IIS da pannello di controllo, strumenti di amministrazione, nel centro, sotto il gruppo IIS, troverò il link ServerCertificates, lo apro

image

d) da qui posso fare Export con il click destro per esportare il nostro certificato da poi importare sul server di destinazione sempre da questo pannello di IIS

a questo punto abbiamo il certificato

PASSO 3: Aggiungo il validatore nel progetto.

a) aggiungo il riferimento a System.IdentityModel

b) aggiungo una classe che estende UserNamePasswordValidtor (System.IdentityModel.Selectors) ed implemento la classe astratta aggiungendo il nostro codice al metodo Validate. es stupido:

public override void Validate(string userName, string password)
{
    if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
        throw new SecurityTokenException("Username or password not valid!");  //using System.IdentityModel.Tokens
}

a questo punto abbiamo il validatore

 

PASSO 4: Configuro WCF per usare certificato e validatore

Aprendo il web.config, posso configurare entrambe le cose. esempio:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <!-- QUI SI SPECIFICA IL CERTIFICATO PER INSTAURARE IL CANALE SICURO-->
            <serviceCertificate findValue="Service1Certificate"
                                storeName="My"
                                storeLocation="LocalMachine"
                                x509FindType="FindBySubjectName"/>
            <!-- QUI SI SPECIFICA CHE VOGLIAMO USARE USERNAME E PASSWORD CON UN NOSTRO VALIDATORE-->
            <userNameAuthentication  userNamePasswordValidationMode="Custom"
                                     customUserNamePasswordValidatorType="UserNamePasswordSimpleService.MyConstomUsernamePasswordValidator, UserNamePasswordSimpleService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <!-- AGGIUNGO IL NODO SERVICE CON IL NOME DEL NOSTRO SERVIZIO PER CONFIGURARLO-->
      <service name="UserNamePasswordSimpleService.Service1">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="BindingConfiguration1" contract="UserNamePasswordSimpleService.IService1" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <!-- CONFIGURO IL BINDING CON L'IMPOSTAZIONE DI SICUREZZA VOLUTA - USERNAME+PASSWORD-->
        <binding name="BindingConfiguration1">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

Il gioco è fatto Sorriso

peccato che sul client avremo problemi perchè il certificato è un certificato locale non valido a livello pubblico… quindi, o al posto di generarlo a mano con il “makecert” lo compriamo (anche gratis ad esempio con SmartSSL), oppure dobbiamo disabilitare il check di sicurezza sul client così da poter usare anche io nostro certificato

PASSO 5: Il Client

Basta fare un nuovo progetto Windows o Console, poi click destro sui riferimenti, e click su “Add Service Reference”, li basta selezionare l’url del nostro servizio che vediamo quando andiamo in Debug sul progetto con il servizio, oppure facendo click destro sul servizio (il file .svc) e poi ViewInBrowser.

una volta connesso il client al servizio, la configurazione la farà tutta WCF per noi, a noi servirà solo impostare username e password quando ci connettiamo così:

var c = new ServiceReference1.Service1Client();
c.ClientCredentials.UserName.UserName = "user";
c.ClientCredentials.UserName.Password = "pass";

PASSO 6 [SOLO X CERTIFICATI DI TEST]: disabilito il check di sicurezza sul client per il certificato lato server. Questo l’App.config del client:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
            maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
            allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" negotiateServiceCredential="true"
                algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

<!-- CONFIGURAZIONE PER DISABILITARE IL CHECK -->

    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientBehavior">
          <clientCredentials>
            <serviceCertificate>
              <authentication revocationMode="NoCheck" certificateValidationMode="None"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>


    <client>
      <!-- CONNETTO LA CONFIGURAZIONE DEL CHECK IMPOSTANDO LA PROPRIETA' behaviorConfiguration-->
      <endpoint address="http://localhost:48844/Service1.svc" binding="wsHttpBinding" behaviorConfiguration="ClientBehavior"
          bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
          name="WSHttpBinding_IService1">
        <identity>
          <certificate encodedValue="AwAAAAEAAAAUAAAAU9NakvE/ZBiomn6+liSNuIRH6wYgAAAAAQAAABACAAAwggIMMIIBeaADAgECAhARchX3tGWejUpysWzNI4btMAkGBSsOAwIdBQAwHjEcMBoGA1UEAxMTU2VydmljZTFDZXJ0aWZpY2F0ZTAeFw0xMTEyMTExOTEyMTdaFw0zOTEyMzEyMzU5NTlaMB4xHDAaBgNVBAMTE1NlcnZpY2UxQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOr3C6g0UBx0YJ+ZoVlZgjun1xjNx1/o5j0dDu/i4arCuT3gcI9R6s6LB8vBDAV6LN6EcenmTM6TcuDDmXqfFZEkRfCDa5KSvfTD5CAiYy6yLbqlSHZte8imzqkuqto433lMUTHmep8EgPVOi5OCv/FFU0xfpP0GIlyqgULGkKM/AgMBAAGjUzBRME8GA1UdAQRIMEaAEJm63aKyQ9abRQoAHtmUEQuhIDAeMRwwGgYDVQQDExNTZXJ2aWNlMUNlcnRpZmljYXRlghARchX3tGWejUpysWzNI4btMAkGBSsOAwIdBQADgYEAPNVgkLYE3XnPlaY/IEfgrnrDx+N/K9uAwT882Ns/LbpPKzEcVh6o74H4efYHnPVeMYbJur435Ga6iElWO+n7Dw7icL1S/YfC3gKvgCzR1upbUUYVilfbuminqOb9ag1s9QFat0OQy/i4psi4aXH86nIAuxDQ8qHESRTNKEcfS60=" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

 

per disabilitare il check, fare copiaincolla della parte in alto contrassegnata (il tag behaviors) e poi aggiungere la parola behaviorConfiguration come segnalato in basso nel proprio app.config senza alterare le altre configurazioni

 

 

per ogni dubbio, contattatemi pure Sorriso

info@antonioesposito.it

 

DEMO

Windows Azure WebRole: quando NetworkService non è sufficiente

Sat, 10 Dec 2011 11:08:00 GMT Visualizza

Ciao a tutti

capita a volte di fare deploy di una applicazione web su Windows Azure, come nel mio caso di HomeFramework e ci si trova a chiedersi: come faccio ad impostare l’AppPool in automatico senza andare in DesktopRemoto su tutte le istanze del mio cloud, andando di fatto a vanificare ogni aspettativa cloud….

Fortunatamente la risposta è abbastanza semplice, ed è nell’assembly Microsoft.Web.Administration che giace sepolta e nascosta in C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll

 

Una volta aggiunto il semplice riferimento al nostro WebRole, è sufficiente andare in WebRole.cs/vb che automaticamente l’SDK di Windows Azure aggiunge ai nostri WebRole, e scrivere qualcosa come questo:

 

public override bool OnStart()
{
    // To enable the AzureLocalStorageTraceListner, uncomment relevent section in the web.config 
    DiagnosticMonitorConfiguration diagnosticConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
    diagnosticConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
    diagnosticConfig.Directories.DataSources.Add(AzureLocalStorageTraceListener.GetLogDirectory());

    try
    {
        using (ServerManager serverManager = new ServerManager())
        {
            //leggo il nome del mio AppPool
            string appPoolName = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"].Applications.First().ApplicationPoolName;
            Log.Verbose("Found AppPool {0}", appPoolName);
            //prendo l'AppPool per poterci fare modifiche
            var appPool = serverManager.ApplicationPools[appPoolName];
            //cambio le credenziali (ovviamente posso anche dargliene di specifiche, ma poi dovrei gestire un dominio cloud...
            appPool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem;
            //salvo
            serverManager.CommitChanges();
            Log.Information("Set AppPool {0} identity at {1}", appPoolName, appPool.ProcessModel.IdentityType);
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex, "Unable to configure AppPool!");
    }

    return base.OnStart();
}

 

questo codice farà si che ad ogni deploy di Windows Azure, automaticamente sarà eseguita questa configurazione, così, quando l’applicazione sarà tirata su da IIS, automaticamente ci troveremo con le credenziali aumentate a (in questo esempio) LocalSystem

ovviamente se ne sconsiglia l’uso se non obbligatorio come nel mio caso ove avevo da creare endpoint dinamici che senza diritti non avrei potuto tirare su in HTTP…..

 

per via della sicurezza di Windows Azure, questo stessso codice non avrebbe i diritti per salvare le modifiche su IIS a meno di andare nel ServiceDefinition.csdef e aggiungere questa riga nel nodo del nostro WebRole:

<WebRole name="XXX" vmsize="XXX" enableNativeCodeExecution="XXX"> //cercare il vostro nodo

<Runtime executionContext="elevated" /> //aggiungere questa riga

 

 

a presto

WCF Home Framework – Finally Cloud

Wed, 07 Dec 2011 11:28:00 GMT Visualizza

Ciao a tutti

 

chi ha seguito il mio blog da tempo, ricorderà questo nome “Home Framework”… così come anche chi è venuto alle mie scorse conferenze come ad esempio l’ultimo WPC in OverNet a Milano/Assago

WCFHF è un framework che ci aiuta a gestire e rilasciare servizi WCF, adesso completamente cloud su Windows Azure e SQL Azure

La sicurezza, la scalabilità, la configurazione, il rilascio, la gestione delle versioni, sono tutte problematiche che WCFHF gestisce per te.

E’ sicuro, perchè il manager è in HTTP/SSL, è sicuro perchè il tuo servizio è utilizzabile esclusivamente da te tramite username e password identiche a quelle del manager, è sicuro perchè il servizio risponde alle chiamate a sua volta in TLS/SSL + Message Security con autenticazione, appunto, username+password.

E’ scalabile perchè il tuo servizio è sul cloud. Gira sempre su più server dietro un bilanciatore che non devi gestire, semplicemente usare

Niente più configurazioni… non hai bisogno di creare un progetto da visual studio per il tuo WCF, niente più .config da gestire, etc…

Niente più rilasci con copia di files, modifiche delle configurazioni, web deploy, etc…. Semplicemente basterà andare sul manager web di WCFHF e fare l’upload del tuo servizio.

Le versioni le gestisce WCFHF, e non c’è limite al numero di versioni contemporanee del tuo servizio online

 

Esempio d’uso. Andiamo su WCFHF: https://homeframework.tnxconsulting.com/Manager/Default.aspx

image

Se non sei ancora registrato, registrati tanto non si paga niente Sorriso

Qui sono presenti i nostri servizi, catalogati per nome e versione. sulla sinistra abbiamo il flag che ci indica se il servizio è attivo (risponde alle chiamate) o no mandando in automatico eventuali chiamate sulla versione subito successivamente disponibile

infine sulla dx abbiamo il link al wsdl. questo ci permette di creare il nostro client come facciamo abitualmente da visual studio o da svcutil

Guida. Creiamo l’HelloService1

1) Apro Visual Studio 2010 con framework 4.0 e creo un progetto di tipo libreria (DLL) in c# o vb

2) Aggiungo i riferimenti a System.Runtime.Serialization e System.Servicemodel.*

3) Creo il contratto di servizio ed il servizio con un’interfaccia ed una classe

[ServiceContract()]
public interface IHelloService1
{
    [OperationContract]
    string GetString();
}

[ServiceBehavior]
public class HelloService1 : IHelloService1
{
    public string GetString()
    {
        return "Hello v 2.0";
    }
}

4) compilo in Release

5) Vado su WCFHF e clicco sulla DX il link upload, scelgo il mio file compilato in .dll e premo ancora Upload

6) Abilito il servizio cliccando sul link con il suo nome, e poi Enable sulla DX

Tornando alla homepage vedrò che il servizio è funzionante Sorriso volendo possiamo cliccare WSDL sulla sua DX per vederne la configurazione

 

Guida. Creiamo un client per utilizzare l’HelloService1.

1) Clicco sul link WSDL sulla DX del servizio che voglio usare, e mi copio l’URL (oppure clicco dx sul link e faccio copia URL)

2) Apro Visual Studio, creo un nuovo progetto o uso uno esistente, copio l’URL del WSDL in “Add Service Reference” come usualmente faccio per connettermi ad un servizio e do un nome leggibile al namespace in basso (opzionale)

image

3) vado nel mio codice e istanzio un nuovo client passandogli le credenziali del mio utente WCFHF

var c = new CloudHelloService.HelloService1Client();
c.ClientCredentials.UserName.UserName = "[USERNAME]";
c.ClientCredentials.UserName.Password = "[PASSWORD]";

4) Uso il mio servizio normalmente

Console.WriteLine(c.GetString());
Console.ReadLine();

A questo punto, non bisogna fare altro Sorriso, a tutta la configurazione, inclusa la sicurezza, ha pensato il WDSL

 

Usatelo e mandatemi ogni feedback possibile a info@antonioesposito.it

Vi consiglio per ogni richiesta su WCF di andare sul forum italiano: http://social.msdn.microsoft.com/Forums/it/wcfwfit/threads

 

Seguiranno ulteriori tutorial e nuove funzionalità come supporto REST, supporto a SilverLight, servizi longrunning, etc… spero il più presto possibile e se non ci si vede prima, ci si vedrà con WCFHF al prossimo HackItaly Sorriso

A presto

Puliamo i nostri files da spazi e quant’altro

Thu, 01 Dec 2011 21:54:00 GMT Visualizza

Ciao a tutti

 

prima di andare a dormire, voglio lasciarvi con un interessante e comodo codicino per ripulire vari files dagli spazi di troppo, ritorni a capo, etc…

pensiamo all’HTML, agli XML, e quant’altro che potremmo voler ripulire

es:

var stringaRipulita = Regex.Replace(<stringa-da-ripulire>,@"\s{2,1000}", "");

 

a presto