Nel corso di quest’articolo vedremo come realizzare un client .NET per accedere alle informazioni registrate sul sistema di CRM e sfruttare il client come base per la realizzazione di una semplice applicazione .NET C# che sia in grado di eseguire una serie di operazioni elementari come: login, creazione di un nuovo contatto e recupero dati.
Daniele Lunassi, CEO & Head of Design @Eye Studios – “Creare prodotti e servi...
Costruire un client .NET per SugarCRM
1. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Costruire
un
client
.NET
per
SugarCRM
Nel
corso
di
quest’articolo
vedremo
come
realizzare
un
client
.NET
per
accedere
alle
informazioni
registrate
sul
sistema
di
CRM
e
sfruttare
il
client
come
base
per
la
realizzazione
di
una
semplice
applicazione
.NET
C#
che
sia
in
grado
di
eseguire
una
serie
di
operazioni
elementari
come:
login,
creazione
di
un
nuovo
contatto
e
recupero
dati.
Il
sistema
SugarCRM (SugarCRM Inc.)
espone
verso
l’esterno
delle
interfacce
che
supportano
i
protocolli
SOAP1
e
REST2,
tramite
queste
interfacce
è
garantito
l’accesso
ai
dati
attraverso
una
serie
di
funzioni
o
operazioni
di
tipo
CRUD 3
(SugarCRM Inc.).
La
versione
di
SugarCRM
cui
faremo
riferimento
durante
l’intero
articolo
è
la
6.1
Community
Edition
(SugarCRM Inc.).
Il
protocollo
che
utilizzeremo
per
l’interazione
tra
la
nostra
applicazione
.NET
e
SugarCRM
è
il
protocollo
SOAP.
Esistono
modi
diversi
per
creare
un
client
SOAP
C#
in
grado
di
colloquiare
con
un
servizio
web
sfruttando
.NET
Framework
(Microsoft)
(Wikipedia).
I
passi
da
seguire
per
raggiungere
il
nostro
obiettivo
sono
i
seguenti:
• Generazione
del
client
SOAP
• Compilazione
del
client
SOAP
come
.NET
Library
Assembly
• Creazione
dell’applicazione
.NET
C#
Così
come
per
il
muratore
che
per
realizzare
una
casa
utilizza
gli
strumenti
del
mestiere,
anche
noi
utilizzeremo
i
nostri
per
completare
l’opera:
• .NET
Framework
SDK:
Runtime
e
strumenti
di
sviluppo.
La
versione
di
riferimento
utilizzata
per
la
stesura
dell’articolo
è
la
4.0
del
framework.
Il
supporto
ai
servizi
web
è
comunque
supportato
anche
da
versioni
precedenti
del
framework.
• SharpDevelop:
Ambiente
di
sviluppo
Open
Source
per
.NET.
La
versione
di
riferimento
utilizzata
per
la
stesura
dell’articolo
è
la
4.1 (IC#Code)
L’articolo
è
rivolto
a
un
pubblico
che
abbia
le
conoscenze
di
base
dello
sviluppo
software
su
piattaforma
.NET
e
in
particolare
utilizzando
il
linguaggio
C#,
oltre
ad
avere
un
certa
familiarità
con
la
tecnologia
dei
servizi
web.
Il
codice
sorgente
dell’intero
progetto
realizzato
nel
corso
dell’articolo
è
disponibile
sul
repository
GitHub
all’indirizzo:
https://github.com/amusarra/SugarCRM_CE_SOAP_V21_DotNetClientLibrary
1
SOAP
(inizialmente
acronimo
di
Simple
Object
Access
Protocol)
è
un
protocollo
leggero
per
lo
scambio
di
messaggi
tra
componenti
software,
tipicamente
nella
forma
di
componentistica
software.
La
parola
object
manifesta
che
l'uso
del
protocollo
dovrebbe
effettuarsi
secondo
il
paradigma
della
programmazione
orientata
agli
oggetti.
2
Representational
State
Transfer
(REST)
è
un
tipo
di
architettura
software
per
i
sistemi
d’ipertesto
distribuiti
come
il
World
Wide
Web.
REST
si
riferisce
a
un
insieme
di
principi
di
architetture
di
rete,
i
quali
delineano
come
le
risorse
sono
definite
e
indirizzate.
I
sistemi
che
seguono
i
principi
REST
sono
spesso
definiti
"RESTful".
3
Create,
Read,
Update
e
Delete
(CRUD)
sono
le
quattro
operazioni
base
per
la
persistenza
dei
dati.
14/11/11
1
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
2. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
1. Creazione
del
Client
SOAP
Per
colloquiare
con
il
servizio
web
di
SugarCRM
occorre
creare
una
Proxy
Class,
un
elemento
software
che
ci
consenta
di
accedere
in
modo
trasparente
al
servizio
web
senza
preoccuparci
del
modo
con
cui
questo
è
chiamato
e
utilizzato.
La
Proxy
Class
deriva
direttamente
dal
documento
WSDL
che
descrive
il
servizio
web.
SugarCRM,
dalla
versione
5.5,
ha
introdotto
il
supporto
al
versioning4
per
le
proprie
API
esposte
come
servizio
web
sia
SOAP
sia
REST;
la
versione
delle
API
di
riferimento
è
la
2.1 (SugarCRM Inc.).
Tramite
l’IDE
SharpDevelop,
sfruttando
la
funzione
di
Add
Web
Reference,
la
creazione
della
Proxy
Class
è
pressoché
banale.
La
creazione
della
Proxy
Class
è
un’operazione
che
può
anche
essere
eseguita
utilizzando
i
tool
dell’SDK
.NET,
nel
Riquadro
2
è
mostrata
la
procedura
di
creazione
e
compilazione.
A
seguire
un
breve
riepilogo
dei
task
che
occorre
eseguire
su
SharpDevelop
al
fine
di
creare
il
nostro
Assembly
che
sarà
poi
utilizzato
dall’applicazione
.NET
C#
per
il
colloquio
con
SugarCRM:
• Creazione
di
un
nuovo
Progetto/Soluzione
• Creazione
della
Proxy
Class
tramite
la
funzione
Add
Web
Reference
• Compilazione
del
Progetto
Il
processo
di
creazione
della
Proxy
Class
richiede
obbligatoriamente
il
documento
WSDL
del
servizio
web
di
SugarCRM,
il
WSDL
può
essere
remoto
(http/s)
o
locale
(file
system).
Nel
nostro
caso
sfrutteremo
un’istanza
SugarCRM
(Community
Edition
6.1.2)
installata
sulla
piattaforma
di
PHPFog (PHPFog)
e
raggiungibile
all’indirizzo
https://shirus-‐crm.phpfogapp.com.
Le
figure
mostrate
a
seguire
illustrano
alcune
delle
fasi
importanti
del
processo
di
creazione
del
progetto
su
SharpDevelop.
Figura
1
Creazione
del
nuovo
progetto
come
Class
Library.
4
Vedere
bibliografia
(IBM, 2004), (Microsoft, 2005) e (SOA World Magazine, 2004)
14/11/11
2
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
3. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Il
nuovo
progetto
deve
essere
creato
utilizzando
il
template
Class
Library
e
specificando
il
profilo
.NET
adeguato
(nel
nostro
caso
.NET
4
Client
Profile).
Il
progetto
sarà
creato
all’interno
di
una
soluzione
che
prenderà
il
nome
specificato
in
Solution
Name
(vedere
Figura
1).
Figura
2
Accesso
alla
funzione
di
Add
Web
Reference.
Una
volta
creato
il
progetto
è
possibile
proseguire
con
la
creazione
della
Proxy
Class
attraverso
la
funzione
Add
Web
Reference
raggiungibile
tramite
il
menù
contestuale
del
progetto.
Figura
3
Add
Web
Reference:
WSDL
del
servizio
web
SugarCRM.
Il
documento
WSDL
che
descrive
il
servizio
web
di
SugarCRM
nel
nostro
caso
è
https://shirus-‐crm.phpfogapp.com/service/v2_1/soap.php?wsdl.
Per
ragioni
di
semplicità
ho
preferito
rendere
più
semplici
il
Reference
Name
e
il
Namespace
rispetto
ai
valori
proposti
di
default
(vedere
Figura
3).
Una
volta
acquisito
il
WSDL
è
possibile
visionare
le
operazioni
esposte
dal
servizio
web
tramite
la
linguetta
“Available
Web
Services”
(vedere
Figura
4).
14/11/11
3
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
4. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Figura
4
Operazioni
esposte
dal
servizio
web.
Figura
5
Vista
del
progetto
dopo
l’operazione
Add
Web
Reference.
In
Figura
5
è
mostrato
il
risultato
ottenuto
dall’importazione
del
Web
Reference,
il
file
Reference.cs
contiene
la
nostra
Proxy
Class.
Per
completare
questa
prima
fase
non
resta
altro
che
compilare
il
progetto,
il
processo
di
compilazione
creerà
dentro
la
directory
bin,
la
dll
dell’assembly.
14/11/11
4
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
5. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
2. Creazione
dell’applicazione
.NET
C#
All’interno
della
soluzione
creata
per
il
progetto
della
Proxy
Class,
dovremmo
aggiungere
un
nuovo
progetto
C#
che
chiameremo
per
esempio
SugarCRM_SOAP_Console_Client
utilizzando
il
template
Windows
Console
(categoria
Windows
Applications).
Prima
di
proseguire
oltre,
aggiungiamo
al
nuovo
progetto
il
riferimento
alle
librerie
SugarCRM_CE_SOAP_V21_ClientLibrary
e
System.Web.Services.
Il
riferimento
alle
librerie
deve
essere
aggiunto
utilizzando
la
funzione
Add
Reference
dal
menù
contestuale
del
progetto
(vedi
Figura
6
e
Figura
7).
La
semplice
applicazione
d’esempio
che
realizzeremo
dovrà
soddisfare
il
seguente
flow:
a) Login
per
l’utente
specificato;
b) Lettura
di
alcune
informazioni
sul
sistema;
c) Lettura
di
alcune
informazioni
sull’utente
che
ha
eseguito
il
login;
d) Inserimento
di
un
nuovo
contatto;
e) Lettura
dei
dati
del
contatto
inserito
in
precedenza;
f) Logout
dell’utente
Prima
di
passare
alla
codifica
del
flow
precedente,
vediamo
di
descrivere
brevemente
e
quali
sono
le
operazioni
del
servizio
web
che
dobbiamo
utilizzare
al
fine
di
poter
realizzare
il
flow
indicato
e
i
modi
d’utilizzo
dell’applicazione
stessa.
In
Tabella
1
sono
mostrate
in
ordine
le
operazioni
che
utilizzeremo.
Per
maggiori
informazioni
di
dettaglio
sulle
API
di
SugarCRM
consiglio
la
consultazione
della
relativa
documentazione.
Figura
6
Add
Reference.
14/11/11
5
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
6. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Figura
7
Lista
riferimenti
del
progetto.
Order
Operazione
Descrizione
1
get_server_info
Restituisce
una
serie
d’informazioni
utili
a
identificare
i
dettagli
dell’installazione
di
SugarCRM
(esempio:
versione,
edizione,
etc…).
2
login
Esegue
il
processo
di
login
per
l’utente
specificato,
restituendo
l’identificativo
di
sessione
(SessionID).
Il
valore
della
SessionID
è
utilizzato
in
tutte
le
operazioni
che
richiedono
l’identificazione
dell’utente
corrente.
3
get_user_id
Restituisce
l’identificativo
dell’utente
specificando
la
sessione
corrente.
4
set_entry
Inserisce
un
item
per
il
modulo
specificato,
per
esempio
un
contatto,
leads,
accounts,
etc…
5
get_entry
Restituisce
un
oggetto
che
si
riferisce
al
modulo
specificato.
6
logout
Esegue
il
logout
dell’utente
corrente.
Tabella
1
Operazioni
del
servizio
web
utilizzate
dall’applicazione.
La
nostra
applicazione
di
tipo
Windows
Console
accetterà
come
input
la
coppia
username
e
password
più
l’indirizzo
(URL)
dell’istanza
SugarCRM
a
cui
desideriamo
connetterci.
Usage: SugarCRMClient.exe {username} {password} [SugarCRM URL]
Listato
1
Uso
del
client
SugarCRM
via
console.
L’utilizzo
del
client
non
richiederà
obbligatoriamente
di
specificare
l’URL
dell’istanza
di
SugarCRM,
se
non
specificato
sarà
utilizzato
l’URL
da
cui
è
stato
creato
il
client
SOAP
(Proxy
Class).
Il
Listato
1
mostra
come
utilizzare
il
client
a
linea
di
comando
mentre
il
Listato
2
mostra
un
esempio
d’utilizzo.
14/11/11
6
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
7. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
SugarCRMClient.exe amusarra amusarra https://shirus-crm.phpfogapps.com
Listato
2
Esempio
di
utilizzo
del
client
SugarCRM.
L’URL
non
deve
essere
quello
del
documento
WSDL
ma
bensì
il
root
address
di
SugarCRM,
sarà
poi
responsabilità
dell’applicazione
costruire
l’URL
completo
delle
API.
L’output
dell’applicazione
sarà
mostrato
in
console.
A
grandi
linee
abbiamo
definito
le
funzioni
richieste
e
come
l’applicazione
dovrà
essere
utilizzata,
a
questo
punto
possiamo
analizzare
brevemente
il
codice
della
nostra
applicazione.
I
blocchi
di
codice
a
seguire
sono
mostrati
rispettando
l’ordine
del
flow
indicato
in
precedenza.
// Create a new instance of SugarCRM SOAP Proxy Client
shirus.crm.phpfogapp.com.sugarsoap client = new shirus.crm.phpfogapp.com.sugarsoap();
if (SugarCRM_URL != null) {
client.Url = SugarCRM_URL.AbsoluteUri + "service/v2_1/soap.php";
}
/**
* Step 1) Try login to SugarCRM istance with username and password
*/
// Prepare a User Auth Object
shirus.crm.phpfogapp.com.user_auth userAuthInfo = new
shirus.crm.phpfogapp.com.user_auth();
userAuthInfo.user_name = sugarCRMUserName;
userAuthInfo.password = GetMD5Hash(sugarCRMPassword,false);
// Execute a login as admin
shirus.crm.phpfogapp.com.entry_value userSession = client.login(userAuthInfo,
"SugarCRM Console Client 1.0.0", null);
Listato
3
Operazione
di
login.
/**
* Step 2) Get SugarCRM Server Info
*/
Console.WriteLine("SugarCRM EndPoint URL: " + client.Url);
Console.WriteLine("SugarCRM Server Version: " + client.get_server_info().version);
Console.WriteLine("SugarCRM Server Edition: " + client.get_server_info().flavor);
Console.WriteLine("SugarCRM Server Time: " + client.get_server_info().gmt_time);
/**
* Step 3) Get logged user info
*/
String userId = client.get_user_id(userSession.id);
Console.WriteLine("Welcome Your SessionID: " + userSession.id);
Console.WriteLine("Get user data...");
Console.WriteLine("---------- BEGIN USER DATA ----------");
shirus.crm.phpfogapp.com.get_entry_result_version2 userInfo =
client.get_entry(userSession.id, userSession.module_name, userId, null, null);
14/11/11
7
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
8. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
foreach (shirus.crm.phpfogapp.com.name_value nameValue in
userInfo.entry_list[0].name_value_list) {
if (nameValue.value.Length > 0 && nameValue.name != "user_hash") {
Console.WriteLine(nameValue.name + ": " + nameValue.value);
}
}
Console.WriteLine("---------- END USER DATA ----------");
Listato
4
Informazioni
sul
server
SugarCRM
e
sull’utente
appena
loggato.
/**
* Step 4) Insert new contact
*/
Console.WriteLine("Try insert new Contact...");
Dictionary<string, string> contactsData = new Dictionary<string, string>();
contactsData.Add("first_name", "Antonio");
contactsData.Add("last_name","Musarra");
contactsData.Add("title", "IT Senior Consultant");
contactsData.Add("description", "Contacts created bye .NET SOAP Client");
contactsData.Add("email1","antonio.musarra@gmail.com");
shirus.crm.phpfogapp.com.name_value[] name_value_list = new
shirus.crm.phpfogapp.com.name_value[contactsData.Count];
int i = 0;
foreach (KeyValuePair<string, string> kvp in contactsData) {
name_value_list[i] = new shirus.crm.phpfogapp.com.name_value();
name_value_list[i].name = kvp.Key;
name_value_list[i].value = kvp.Value;
i++;
}
shirus.crm.phpfogapp.com.new_set_entry_result contactResult =
client.set_entry(userSession.id, "Contacts", name_value_list);
Console.WriteLine("New Contact as Id:" + contactResult.id);
Listato
5
Inserimento
di
un
nuovo
contatto.
/**
* Step 5) Get My Contacts
*/
Console.WriteLine("Get data for Contacts: " + contactResult.id);
Console.WriteLine("---------- BEGIN CONTACTS DATA ----------");
shirus.crm.phpfogapp.com.get_entry_result_version2 myContacts =
client.get_entry(userSession.id, "Contacts", contactResult.id, null, null);
foreach (shirus.crm.phpfogapp.com.name_value nameValue in
myContacts.entry_list[0].name_value_list) {
if (nameValue.value.Length > 0) {
Console.WriteLine(nameValue.name + ": " + nameValue.value);
}
}
Console.WriteLine("---------- END CONTACTS DATA ----------");
/**
14/11/11
8
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
9. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
* Step 6) Logout
*/
client.logout(userSession.id);
Console.WriteLine("User disconnected");
Listato
6
Recupero
dei
dati
del
contatto
e
logout
dell’utente.
Ricordo
che
l’intero
progetto
è
disponibile
sul
repository
pubblico
GitHub
https://github.com/amusarra/SugarCRM_CE_SOAP_V21_DotNetClientLibrary
Figura
8
Esecuzione
del
client
SugarCRMClient[0].
Figura
9
Esecuzione
del
client
SugarCRMClient[1].
14/11/11
9
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
10. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Appendice
SugarCRM
on
PHPFog
L’istanza
di
SugarCRM
a
cui
abbiamo
fatto
riferimento
è
installata
sulla
piattaforma
di
cloud
PHPFog
i
cui
dati
di
accesso
sono
i
seguenti:
URL:
https://shirus-‐crm.phpfogapp.com
User
Account:
• Administrator
=>
admin/admin
• User
=>
amusarra/amusarra
Riquadro
1
Dati
di
accesso
all’istanza
SugarCRM.
Creazione
Proxy
Class
via
SDK
.NET
Dato
il
file
WSDL
del
servizio
web,
possiamo
creare
la
Proxy
Class
utilizzando
i
tool
dell’SDK
.NET.
Il
tool
wsdl.exe
ci
permette
di
generare
la
Proxy
Class:
wsdl /language:CS /v /n:shirus.crm.phpfogapp.com /o:
SugarCRM_CE_SOAP_V21_ClientLibrary.cs https://shirus-
crm.phpfogapp.com/service/v2_1/soap.php?wsdl
Il
parametro
language
ci
permette
di
specificare
uno
dei
linguaggi
supportati
da
.NET
Framework
(nell'esempio
è
richiesto
di
generare
una
classe
C#).
Il
risultato
della
precedente
operazione
è
la
generazione
del
file
SugarCRM_CE_SOAP_V21_ClientLibrary.cs,
contenente
il
codice
della
Proxy
Class
per
il
servizio
SOAP
di
SugarCRM.
A
questo
punto
non
ci
resta
che
compilare
il
file
di
cui
sopra,
sempre
utilizzando
l'SDK
.NET:
csc /t:library /out: SugarCRM_CE_SOAP_V21_ClientLibrary.dll
SugarCRM_CE_SOAP_V21_ClientLibrary.cs /r:system.dll /r:system.xml.dll
/r:system.web.services.dll
In
questo
modo
abbiamo
compilato
la
classe
come
libreria
di
classi
(/t:library)
indicando
come
risultato
della
compilazione
l’assembly
SugarCRM_CE_SOAP_V21_ClientLibrary.dll
ed
utilizzando
i
metadati
specificati
nei
parametri
/r.
A
questo
punto
il
file
SugarCRM_CE_SOAP_V21_ClientLibrary.dll
potrà
essere
utilizzato
come
libreria
dalle
applicazioni
.NET.
Riquadro
2
Creazione
della
Proxy
Class
via
SDK
.NET
14/11/11
10
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
11. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Bibliography
Antonio
Musarra's
Blog.
«PHP
Application
on
the
Cloud.»
30
August
2011.
Antonio
Musarra's
Blog.
Antonio
Musarra.
<http://musarra.wordpress.com/2011/08/30/php-‐application-‐on-‐the-‐cloud/>.
IBM.
«Best
practices
for
Web
services
versioning.»
30
Jan
2004.
IBM
DeveloperWorks.
Michael
Ellis
(msellis@ca.ibm.com)
Kyle
Brown
(brownkyl@us.ibm.com).
<http://www.ibm.com/developerworks/webservices/library/ws-‐version/>.
IC#Code.
«SharpDevelop.»
2000.
SharpDevelop.
IC#Code.
<http://sharpdevelop.net/OpenSource/SD/>.
Microsoft.
«.NET
Framework.»
2011.
Microsoft
MSDN.
Microsoft.
<http://msdn.microsoft.com/en-‐en/netframework>.
—.
«Principles
of
Service
Design:
Service
Versioning
.»
August
2005.
Microsoft
MSDN.
John
Evdemon.
<http://msdn.microsoft.com/en-‐
us/library/ms954726.aspx>.
PHPFog.
«Rock-‐solid
Cloud
Platform
for
PHP.»
August
2010.
Rock-‐solid
Cloud
Platform
for
PHP.
Lucas
Carlson.
<https://www.phpfog.com/>.
SOA
World
Magazine.
«Design
Strategies
for
Web
Services
Versioning.»
5
April
2004.
SOA
World
Magazine.
Anjali
Anagol-‐Subbarao
Chris
Peltz.
<http://soa.sys-‐
con.com/node/44356>.
SugarCRM
Inc.
«Sugar
Community
Edition
Documentation.»
2010.
Sugar
Community
Edition
Documentation.
SugarCRM
Inc.
<http://www.sugarcrm.com/crm/support/documentation/SugarCommunityEdi
tion/6.1/-‐docs-‐Developer_Guides-‐Sugar_Developer_Guide_6.1.0-‐
Chapter%202%20Application%20Framework.html#9000244>.
—.
«Sugar
Community
Edition
Documentation.»
2010.
Sugar
Community
Edition
Documentation
|
SugarCRM
-‐
Commercial
Open
Source
CRM.
SugarCRM
Inc.
<http://www.sugarcrm.com/crm/support/documentation/SugarCommunityEdi
tion>.
—.
«Sugar
Community
Edition
Documentation
-‐
API
Definition.»
2010.
Sugar
Community
Edition
Documentation.
SugarCRM
Inc.
<http://www.sugarcrm.com/crm/support/documentation/SugarCommunityEdi
tion/6.1/-‐docs-‐Developer_Guides-‐Sugar_Developer_Guide_6.1.0-‐
Chapter%202%20Application%20Framework.html#9000303>.
—.
«SugarCRM
-‐
Commercial
Open
Source
CRM.»
2004.
SugarCRM
-‐
Commercial
Open
Source
CRM.
SugarCRM
Inc.
<http://www.sugarcrm.com/crm/>.
14/11/11
11
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike
12. Antonio
Musarra's
Blog
The
ideal
solution
for
a
problem
Blog:
http://musarra.wordpress.com
Mail:
antonio.musarra@gmail.com
Wikipedia.
«.NET
Framework.»
15
July
2011.
Wikipedia
-‐
The
Free
Encyclopedia.
Wikipedia.
<http://en.wikipedia.org/wiki/.NET_Framework>.
14/11/11
12
This
document
is
issued
with
license
Creative
Commons
Attribution-‐NonCommercial-‐ShareAlike