Windows Mobile Support

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 26 July 2011

(2) How to use Office in Silverlight applications

Posted on 23:45 by Unknown
Lista postări despre Office interop pe Silverlight:
  • Part 1
  • Part 2
  • Part 3
In postul precedent am povestim despre problemele pe care le putem avea când încercam sa folosim API de Office pe Silverlight. Astăzi o sa discutam despre modul în care care trebuie configurat proiectul pentru a putea sa folosim API de Office și cum putem sa executam câteva funcții de baza.
Pentru a putea apela API de Office pe Silverlight este nevoie sa setam aplicația sa ruleze Out of the brower (OOB) și sa cu permisiuni elevate. Aceste setări trebuie setate pe proiectul de Silverlight care conține App.xml.
Click dreapta pe proiect în tab-ul Silverlight checkbox-ul "Enable running application out of the brower" sa fie check-uit iar în setările pentru out of the brower aveti grija sa check-uit și "Require Elevated trust when running outside the browser".
Pentru a putea sa accesam API de Office (COM-uri in general) din Silverlight o sa fim nevoiți sa lucram cu obiecte de tip dynamic. Crearea unei instante se face folosind AutomationFactory. Următoarea linie de cod creaza un obiect a aplicației Excel, prin intermediul căruia putem sa manipulam fișiere Excel.
dynamic excelApp = AutomationFactory.CreateObject("Excel.Application");
Pentru a putea sa deschidem un fisier deja existent este nevoie sa accesam lista de Workbooks, iar pe aceasta lista sa facem Open
dynamic workbooks = excelApp.Workbooks;
dynamic excelDoc = workbooks.Open([pathToFile]);
In cazul in care vrem sa deschidem un Excel pentru a afisa documentul pe care facem Open trebuie sa setam propietate Vizible pe excelApp pe true.
dynamic excelApp = AutomationFactory.CreateObject("Excel.Application");
excelApp.Visible = true;
dynamic workbooks = excelApp.Workbooks;
dynamic excelDoc = workbooks.Open([pathToFile]);
Bun, am deschis documentul, acuma il putem manipula in orice fel. La final este necesar sa inchidem documentul. Acest lucru se face in felul urmator:
excelDoc.Close(-1,1,true);
Primul parametru reprezinta un enum prin intermediul caruia se specifica daca se doreste sa se faca save la modificari. Din pacate, nu avem access direct la enumuri, din aceasta cauza trebuie sa folosim valoarea lor ca int.
Comanda SaveAs prin interop de Office arata destul de urat. Din cauza ca și parametrii opționali trebuie specificați aceasta ajunge sa arata în felul următor:
document.SaveAs(
[pathToSave],
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
1,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing);
Valoare 1 reprezinta valoarea enum-ului XlSaveAsAccessMode care poate sa aibe urmatoarele valori:
  • xlExclusive - exclusive mode;
  • xlNoChange - default (don't change the access mode);
  • xlShared - share list;
Fiecare document este însoțit de o colecție de propietati numite custom document properties. Acestea reprezinta o colecție de variabile pe care un utilizator le poate seta. In exemplul de mai jos obținem o referința la aceasta colecție pentru a verifica dacă conține variabila cu numele v1. In cazul în care aceasta valoare este "1", o sa ii setam o noua valoare.
dynamic excelCustomProps = excelDoc.CustomDocumentProperties;
for (int i = 1; i <= Count; i++)
{
dynamic property = excelCustomProps[i];
if ((string)property.Name == "v1" &&
(string)property.Value == "1")
{
property.Delete();
excelCustomProps.Add("v1",4,[valoareNoua],false);
}
}
Ce trebuie stiut este faptul ca in momentul in care iteram pe aceasta lista index-ul incepe de la 1 nu de la 0. Iar orice modificare pe propietati se face in momentul in care facem save la document. O valoare a unei propietati nu am reusit sa o modific doar daca stergeam propietatea, iar apoi o adaugam iar.
Descrierea API-ului pentur Excel il puteti gasii aici: http://msdn.microsoft.com/de-de/library/ms262200%28v=Office.11%29.aspx.
In următorul post o sa vedem cum putem sa închidem cu tot procesul Excel pe care noi il lansam si cum putem sa facem unit-teste pentru acestea.
Read More
Posted in excel, interop, office, Silverlight, word | No comments

Sunday, 24 July 2011

(1) How to use Office in Silverlight applications.

Posted on 12:31 by Unknown
Lista postări despre Office interop pe Silverlight:
  • Part 1
  • Part 2
  • Part 3
Acesta este primul post dintr-o serie de trei sau patru posturi în care o sa discutam despre Silverlight și interop (Office interop).
Dupa cum știm Silverlight suporta integrarea cu Office prin intermediul la interop, dar înainte sa ne aruncam cu capul în fata în API si sa vedem ce putem face o sa prezint ce nu putem face din Silverlight.
Nu avem acces la API-ul de Office in totalitate. Chiar daca in teorie folosim COM-urile de Office nu o sa putem apela orice metoda. De exemplu din cauza modului in care o aplicație Silverlight ruleaza pe o masina, nu o sa putem face pe client new la un nou document.
Dar acest lucru este cauzat direct de Silverlight, care nu ne permite sa generam fisiere pe client (in modul in care Office-ul are nevoie).
O solutie la aceasta problema este crearea fisierului pe server, iar apoi sa il copiem pe client. Putem sa avem templaturi care sa le copiem pe client si prin duplicarea lor sa replicam comanda de new.
Din cauza ca folosim obiecte de tip dynamic, putem foarte usor sa gresim apelul unui metode, iar apoi partea de debug pentru a identifica problema o sa fie criminala. Recomand crearea unui wrapper peste API-ul de Office.
Cand o sa incercam sa apelam o metoda o sa observam ca trebuie sa trasmitem ca si parametru valoarea unui enum de care nici nu am auzit pana atunci. Pentru a putea sa il folosim este nevoie sa apelam la msdn si sa trasmitem valorea efectinva a acestuia ca si un intreg.
O alta problema pe care aduce Silverlight-ul si pe care nu o putem rezolva este imposibilitatea de a transmite parametri prin nume:valoare.
De exemplu API-ul de Office este plin de metode cu parametrii optionali, dar din pacate noi nu o sa putem scrie:
document.Find("text",Page:10,Title:false)
O sa fim nevoiti sa specificam toti parametrii, iar cei pe care nu vrem sa ii folosim o sa trebuiasca sa ii specificam prin Type.Missing. Din aceasta cauza codul poate sa ajunga sa aibe forma urmatoare:
document.Find("text",Type.Missing,Type.Missing,Type.Missing,
Type.Missing, 10,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing,false,Type.Missing, Type.Missing)
Maine o sa discutam despre cum trebuie configurata o aplicatie Silverlight pentru a putea folosii API-ul de Office si o parte din API-ul pe care il avem la dispozitie.
Read More
Posted in excel, interop, office, Silverlight, word | No comments

Friday, 22 July 2011

Where constraint wonder

Posted on 07:57 by Unknown
In postul precedent am povestim putin despre where.
Iata o constrîngere destul de interesanta pe care o putem face:
class Car<TTItem,TItem>
where TItem:IItem
{
public TSubItem GetColor<TSubItem>(string name)
where TSubItem:TItem
{
...
}
}
Ce mi-a placut este ca putem sa ne definim o constrangere care sa contina un tip care este deja generic.
Nice :)
Read More
Posted in generic, where clause | No comments

Thursday, 21 July 2011

Where clause

Posted on 23:27 by Unknown
Mai mult ca sigur cu toții am folosit clauza where.
Pe scurt, where este folosit când trebuie sa adaugăm o constrângere la un tip generic specificat la o clasa sau la o metoda.
public class Car<TType>
where TType : ICarModel
{}
In exemplul de mai sus o sa putem folosii tipuri generice TType doar dacă implementează interfața ICarModel. In cazul in care vrem sa specificam ca tipul generic sa fie neaparat o clasa este nevoie sa ne folosim si de cuvantul rezervat class:
public class Car<TType>
where TType : ICarModel, class
{}
In cazul acesta, TType trebuie sa fie obligatoriu sa fie o clasa (nu va putea sa fie o structura de exemplu). Pentru structuri trebuie sa folosim cuvantul rezervat struct:
public class Car<TType>
where TType : struct
{}
Dar dacă vrem sa face new de un obiect de tip generic? In cazul aceasta trebuie sa specificam ca are un constructor default în clasau de where. Din păcate doar constructorul default fără parametri se poate specifica. In restul cazurilor o sa aveți nevoie de un factory sau de reflection pentru a crea noi instante din interiorul clasei Car.
public class Car<TType>
where TType : new()
{}
Gata cu introducerea, sa va zic ce vroiam de fapt. Cand avem 2 clause de where sintaxa este destul de ciudata, trebuie sa specificam de doua ori where.
public class Car<TType,TFormat>
where TType : new()
where TFormat : struct
{}
Mi se pare umpic mai ciudat ca cele doua where-uri nu sunt despartite prin virgula sau alt caracter (cuvînt rezervat).
Voua cum vi se pare sintaxa?
Read More
Posted in generic, where clause | No comments

Wednesday, 20 July 2011

Add files to unit tests output - DeploymentItem

Posted on 01:27 by Unknown
Uneori când scriem unit teste avem nevoie sa specificam anumite fișiere care sa fie copiate în directorul de unde rulează testele.
Cea mai simpla variante este sa adaugăm aceste fișiere în *.testsettings (la secțiunea Deployment).
Dar dacă vrem sa specificam aceste dependințe separat, pentru fiecare unit test în parte?
Putem sa facem acest lucru folosindu-ne de atributul DeploymentItem. Acesta poate sa fie specificat per clasa sau metoda de unit test. Putem sa specificam ce fișier sa se copieze în output și opțional și sub ce director.
[TestClass]
[DeploymentItem("text.txt")]
public class ATest
{
[TestMethod]
public void M1Test()
{
...
}
}
In cazul în care vrem sa specificam un director sa fie copiat 1 la 1 în output-ul pentru teste este nevoie sa specificam doar numele la director.
[TestClass]
[DeploymentItem("DirNameSource","DirNameDestination")]
public class ATest
{
[TestMethod]
public void M1Test()
{
...
}
}
In exemplul de mai sus am specificat ca toate fișierele din directorul DirNameSource sa fie copiate sub directorul DirNameDestination din output. In cazul în care acest director nu exista acesta va fi creeat.
Pentru a putea folosii acest atribut este nevoie sa avem "Deployment Enable" din fisierul testconfig.
Read More
Posted in DeploymentItem, unittest | No comments

Thursday, 14 July 2011

Session on Azure AppFabric Cache

Posted on 21:26 by Unknown
Într-un post anterior am prezentat pe scurt API la Azure AppFabric.
http://vunvulearadu.blogspot.com/2011/07/azure-appfabric-cache-api.html
Dupa cum ştim, în momentul în care punem aplicaţie web pe cloud, noţiunea de sesiune nu mai exista din cauza ca nu ştim dacă o sa ajungem la aceiaşi instanta a unui server intre doua apeluri succesive. Pentru a putea rezolva aceasta problema putem sa folosim Azure AppFabric.
Dupa ce configuram Azure AppFabric trebuie sa adaugăm în web.config următoarea secţiune:
<system.web>
<compilation debug="true" targetFramework="4.0">
</compilation>
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider" compressionEnabled="false">
<providers>
<add name="AppFabricCacheSessionStoreProvider"
type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache"
cacheName="default"
useBlobMode="true"
dataCacheClientName=”default”/>
</providers>
</sessionState>
Din acest moment sesiune este pusa direct pe cache.
Read More
Posted in Azure AppFabric Cache, Cloud, sesiune, session | No comments

Wednesday, 13 July 2011

Suppress IE invalid certificate warning

Posted on 07:31 by Unknown
Se da:
  • o aplicatie web dezvoltata in Visual Studio 2010;
  • un certificat care insoteste aplicatia;
  • brower de test IE9;
De fiecare data cand o rulam aplicatia o sa apara urmatorul warning:
The security certificate presented by this website was not issued by a trusted certificate authority.
Security certificate problems may indicate an attempt to fool you or intercept any data you send to the server.
We recommend that you close this webpage and do not continue to this website.
Dupa 10 rulari deja o sa incepem sa ne saturam sa dam Continue. Ca sa scapam de acest mesaj putem sa schimba cheia din registri
HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Internet Settings:WarnonBadCertRecving
cu valoarea 0. Este foarte importat sa nu uitam aceasta cheie setata pe valoarea 0 dupa ce terminam dezvoltarea.
O alta varianta este sa facem disable la acest warning din:
IE Tools->Internet Options->Advanced->Security->Warn about certificate address mismatch
Enjoy.
Read More
Posted in Internet Explorer, visual studio, WebBrower | No comments

Tuesday, 12 July 2011

Azure AppFabric Cache API

Posted on 06:22 by Unknown
Nu de mult a fost lansat CTP pentru Azure AppFabric Caching. In ultima perioada am început sa studiez API-ul acestuia mai în detaliu. O sa încerc în urmatoarele rânduri sa trec în revista API-ul acestuia si sa fac highlight la cea ce ii mai important.
In primul rand este bine de stiut ca Azure AppFabric nu este totuna cu Windows Server AppFabric. Chiar daca cele doua se aseamana, acestea au assembly-uri diferite pe partea de client. Totodata nu avem posibilitatea sa facem switch intre Windows Server AppFabric si Azure AppFabric. API-ul care îl ofera Azure în acest moment nu este atât de larg, partea de notificari si regiuni înca nu este suportata în întregime.
Am scris într-un post trecut modul în care trebuie sa se configureze Azure AppFabric. In momentul în care am configurat cache-ul în cloud, acesta ne pune la dispozitie sectiunea care trebuie sa adaugam în fisierul de configurare (aceasta v-a contine inclusiv token-ul de autentificare). http://vunvulearadu.blogspot.com/2011/03/outputcache-in-windows-azure-folosind.html
In cache putem sa punem orice fel de obiect serializabil. In acest moment dimensiunea maxima a unui obiect poate sa fie de 8MB, dar aceasta valoare se poate schimba.
Pentru a putea folosii un obiect de tip Datacache trebuie sa folosim factory-ul DataCacheFactory. Acesta poate sa primeasca în constructor un obiect de tip DataCacheFactoryConfiguration, prin intermediul caruia se poate configura cache-ul.
Pe partea de configurare cred ca merita sa mentionez faptul ca în mod default, un obiect expira în cache dupa 10 minute, daca nu este setata o alta valoare, iar în cazul în care salvati în cache foarte mult text putem sa ne folosim de flag-ul IsCompressionEnabled. O setare care nu trebuie niciodata sa ne scape, este MaxConnectionsToServer. In functie de dimensiunea instantei pe care rulam aceasta valoare trebuie aleasa cu grija.
Odata ce avem o instanta a unui obiect de tip DataCacheFactory, putem sa obtinem orice cache pe baza numelui. Cache-ul default are numele "default" si se poate obtine prin metoda GetDefaultCache(). Pentru a obtine un cache pe baza numelui trebuie sa apelam metoda GetCache(numeCache).
DataCacheFactory citeste toata partea de configurarea din fisierul de configurare, dar daca dorim putem sa specificam si din cod aceste date (de exemplu token-ul de autentificare).
Mai jos, puteti sa gasiti un exemplu unde cream un DataCacheFactory, iar apoi obtinem o referinta la cache-ul default:
 DataCacheFactoryConfiguration dataCacheConfig = new DataCacheFactoryConfiguration()
{
RequestTimeout = new TimeSpan(0, 0, 60),
};
dataCacheFactory = new DataCacheFactoru(dataCacheConfig);
DataCache defaultCache = dataCacheFactory.GetDefaultCache();
Nu trebuie sa uitam ca daca adaugam un obiect intr-un cache, acesta nu o sa fie vizibil in celelalte cache-uri, asa ca aveti grija pe ce cache executati put si get.
In cazul în care vrem sa folosim si un cache-ul local putem sa îl cream în felul urmator:
 DataCacheFactoryConfiguration dataCacheConfig = new DataCacheFactoryConfiguration()
{
RequestTimeout = new TimeSpan(0, 0, 60),
LocalCacheProperties = new DataCacheLocalCacheProperties(5, new TimeSpan(0, 0, 10),
DataCacheLocalCacheInvalidationPolicy.TimeoutBased)
};
Mai sus avem un cache local, care poate sa stocheze maxim 5 obiecte. In momentul in care vrei sa luam din cache un obiect, acesta este cautat in cache-ul local, iar versiunea este verificata. Daca acesta nu este gasit obiectul urmeaza sa fiu cautat in cache-ul de pe cloud.
Înainte sa trecem la modul în care un obiect se poate adauga sau extrage din cache trebuie sa stim ca Azure AppFabric cache suporta doua tipuri de concurenta:
  • Optimist
  • Pesimist
In cazul în care lucram cu modelul optimist, în momentul în care luam un obiect din cache un version number vine însotit cu acesta. In momentul în care editam acest obiect si vrem sa facem update, version number poate sa fie specificat.
Pentru modelul pesimist, lucrurile stau diferit. In momentul în care se face get pe un obiect, se face automat si lock pe acest obiect pana când nu mai este nevoie de el. Dar trebuie avut grija cum este folosit acest model, deoarece lock-ul o sa fie valabil doar pentru cei care folosesc acelasi mecanism de concurenta. Pe obiectul pe care s-a facut lock se va putea face oricând update prin modelul optimist (nu e tocmai nice).
dataCache.Add("currentUser",user);    //Adauga un cache obiectul user.
var user = dataCache.Get("currentUser"); // Se obtine obiectul "currentUser" din cache.
user = dataCache["currentUser"];
user = dataCache.GetCacheItem("currentUser");
user = dataCache.GetAndLock("currentUser", TimeSpan.FromSeconds(10), out lockHandlerUser); // Se obtine un obiect din cache prin modelul pesimist, pentru obiectul dat se face un lock timp de 10 secunde;
Daca mai sus am vazut cum se poate adauga sau obtine un element din cache mai jos o sa prezint 2 mecanisme prin care putem sa stergem obiecte din cache:
dataCache.Remove("currentUser");
datacache["currentUser"] = null;
In cazul in care vrem adaugam un element in cache si sa controlam timpul de expirare putem sa facem acest lucru prin intermediul metodei Put:
dataCache.Put("currentUser",user,TimeSpan.FromMinutes(100);
Metoda Put poate sa fie folosita si pentru a face update la un element care este deja in cache. In cazul in care avem doua instante a unui obiect din cache si incercam sa facem put pentru fiecare in parte fara sa verificam versiunea, cel de-al doilea put nu o sa se termine cu succes, deoarece versiunea este prea vechie:
DataCacheItem dci1 = dataCache.GetCacheItem("currentUser");
DataCacheItem dci2 = dataCache.GetCacheItem("currentUser");
dataCache.Put("currentUser", new User(),dci1.Version);
dataCache.Put("currentUser", new User(), dci2.Version); // Acest Put esueaza.
Daca nu folosim versiunea atunci ambele update-uri s-ar termina cu succes. Acesta a fost modelul optimist de concurenta. In cazul modelului pesimis, lucrurile sunt destul de clare cand si cine poate sa faca update. Nu uitati doar daca mergeti pe modelul pesimist atunci orice consumator trebuie sa foloseasca API-ul specific pentru acest model:
  • GetAndLock
  • PutAndUnlock
Cam astea sunt cele mai importante lucruri pe care trebuie sa le stim despre Azure AppCache. Maine o sa vedem cum putem sa avem sesiune în Azure AppCache si cum ne putem folosii de ea.
Read More
Posted in Azure, Azure AppFabric Cache, cache, Cloud | No comments

Tuesday, 5 July 2011

Client IP Filter on Windows Azure

Posted on 06:47 by Unknown
Pornim de la următoarea problema:
  • Avem un site în cloud. Dorim sa restricționam accesul pe baza de IP. Vrem sa excludem o anumita clasa de IP-uri.
Cautînd pe google și prin blog-uri am găsit doua soluții propuse, care sa și funcționează pe Azure:
  1. IPSecurity
  2. IHttpModule
1. In prima varianta trebuie sa restricționam accesul la clasele de IP-uri din fișierul de configurare.
<location path="CarWebSite">
<system.webServer>
<security>
<ipSecurity>
<add ipAddress="123.456.0.0" subnetMask="255.255.0.0" allowed="false" />
</ipSecurity>
</security>
</system.webServer>
</location>
Mai sus am restrictionat accesul la IP-urile 123.254.0.1 pana la 123.254.255.255 pentru path-ul CarWebSite. Daca am fi pe un Windows Server 2003 acesta setare ar functiona fara nici o problema. In schimb pe Windows Azure o sa avem o mica surpriza. Din cauza ca pe IIS din cloud modulul pentru IP Security nu este (încă) instalat.
Pentru a putea totuși sa folosim aceasta funcționalitate trebuie sa facem un mic hack și sa instalam acest modul în momentul în care instanta pornește. Primul pas este sa ne definim task-ul în *.csdef.
<Startup>
<Task commandLine="Startup.cmd" taskType="simple" executionContext="elevated" />
</Startup>
In momentul in care instanta porneste, cmd cu numele specificat o sa ruleze intr-un context elevat (cu drepturi de administrator).
Atributul TaskType specifica modul în care as fie rulat acest task:
  • Simple - sistemul așteaptă comanda sa se termine de executat, înainte ca un alt task sa fie lansat;
  • Background - sistemul nu așteaptă ca cmd-ul sa se termine de executat și trece la următoarea comanda;
  • Foreground - la fel ca și Background, doar ca instanta nu se va restarta pana cînd comanda nu se termina de executat;
In fișierul Startup.cmd trebuie sa instalam modulele de care avem nevoie și sa facem unlock la secțiune ipSecurity:
%windir%\System32\ServerManagerCmd.exe -install Web-IP-Security
%windir%\system32\inetsrv\AppCmd.exe unlock config -section:system.webServer/security/ipSecurity
Acest fisier trebuie sa fie in root-ul proiectului si sa aibe setat flag-ul Content setat cu valoarea Copy Always. Dupa ce o sa facem deploy la solutie, filtrarea după ip-uri ar trebui sa functioneze.
Din cauza ca instalam un nou modul de IIS, inițializarea rolului s-ar putea sa dureze mai mult (~5 minute în plus în cazul unei instante de tip small).
2. Următoarea soluție pe care am găsito este sa implementam interfața IHttpModule și sa ne definim un modul http propriu. In momentul în care acesta se inițializează ar trebuii sa citească lista de IP-uri restricționate dintr-o anumita locație, iar apoi la fiecare acces, în funcție de IP-ul clientului sa nu permită accesul la aplicația pentru anumite IP-uri.
public class IPBlockHttpModule : IHttpModule
{
private void HandleBeginRequest( object sender, EventArgs evargs )
{
if (!sender is HttpApplication)
{
return;
}

HttpApplication app = (HttpApplication)sender;
string IPAddress = app.Context.Request.ServerVariables["REMOTE_ADDR"];
if (string.IsNullOrEmpty(IPAddress))
{
return;
}
if (IsBlockedIP(IPAddress))
{
app.Context.Response.StatusCode = 404;
app.Context.Response.SuppressContent = true;
app.Context.Response.End();
return;
}
}
}
In momentul în care se face un request verificam dacă ip-ul clientului este are drepturi sa acceseze situl. In cazul în care acesta nu are drepturi returnam eroarea 404. Metoda IsBlockedIP verifica dacă IP-ul clientului are drepturi sa acceseze situl nostru.

Daca in prima varianta partea de filtrare o face în totalitate IIS-ul, în a doua varianta acest lucru o sa îl facă codul nostru. Ma aștept ca în viitor sa apară aceasta funcționalitate și în Azure, din aceasta cauza recomand prima varianta.
Read More
Posted in Azure, Cloud, HttpModule, IP Filter | No comments

Monday, 4 July 2011

REST Client - RESTSharp

Posted on 06:55 by Unknown
In urma cu cîteva luni aveam nevoie de un un mecanism prin intermediul căruia sa consum servicii REST din .NET.
La prima strigare acest lucru este destul de simplu de făcut (de implementat), avem nevoie un obiect de tip HttpRequest. Dar am vrut mai mult de atît, doream un API simplu prin care sa pot sa fac apeluri REST.
O soluție la îndemîna era sa încep implementarea unui astfel de API de la 0, cea ce am și făcut în prima faza, deoarece nu este foarte complicat (mi-a luat in jur de 12 ore pana sa ajuns la un API destul de bogat).
Intre timp am început sa caut pe web ce soluții free exista și am descoperit RestSharp. Este un client pentru servicii în format REST open-source destul de robust și bine gîndit.
Ce mi-a plăcut la el cel mai mult și m-a făcut sa îl folosesc este numele la clase (foarte sugestive) și ușurința cu care se poate folosii plus ca primele linii de cod pe care le-am scris pentru acest IP au funcționat din prima. Mai jos puteți sa găsit un exemplu:
RestClient restClient = new RestClient("www.car.com");
RestRequest restRequest = new RestRequest();
restRequest.Method = Method.GET;
restRequest.Resource = "Cars/Get";
restRequest.AddParameter(
new Parameter()
{
Name = "id",
Value = "123",
Type = ParameterType.GetOrPost
});
Car car = restClient.Execute<Car>(restRequest);
Prin intermediul la restRequest putem sa facem unu sau mai multe apeluri. Detalii pentru fiecare apel de serviciu în parte sunt specificate prin intermediul unei instante de tip RestRequest. Resource se refera la adresa relativa a serviciului fata de adresa de baza.
Putem sa adaugăm oricîți parametrii, iar pentru fiecare parametru în parte se poate specifica tipul acestuia. Tipurile de parametri suportați sunt:
  • Cookie
  • GetOrPost
  • UrlSegment
  • HttpHeader
  • RequestBody
Ce mi-a plăcut este ca pot sa controlez destul de ușor unde se va adaugă fiecare parametru în parte, iar în cazul în care lucrați și cu cookie, lucrurile se simplifica destul de mult.
Parametrii de tip UrlSegment sunt destul de interesanți. Îți permit sa specifici în Resource o adresa dinamica, care în funcție de parametrii sa se poată modifica. De exemplu daca lucram cu doua versiuni de servicii, ne-ar fi util sa putem specifica locația la fiecare versiune de serviciu în parte. Pentru a putea face acest lucru putem sa scriem următorul apel:
RestRequest restRequest = new RestRequest();
restRequest.Method = Method.GET;
restRequest.Resource = "{version}/Cars/Get";
request.AddParameter("version", _version, ParameterType.UrlSegment);
In request putem sa adaugăm fișiere prin metoda AddFile, totodată putem sa specificam formatul datelor JSON sau XML. In cazul în care avem un de-serializator custom putem sa îl specificam în momentul în care setam obiectul de tip RestClient.
restClient.AddHandler("*", new JsonDeserializer());
Obiectul care este returnat nu trebuie sa fie neapărat un obiect serializabil, putem sa apelam doar metoda Execute, aceasta ne va returna un obiect de tip RestResponse, care va conține toate informațiile de care avem nevoie. Proprietatea Content ne va returna conținutul returnat de către serviciu.
Apeluri se pot face și async fără nici o problema, iar fiecare clasa din API are unit teste pentru o mare parte din funcționalități.
Un lucru destul de draguț este ca suporta cîteva tipuri de autentificare in mod default. In cazul în care aveți nevoie de un mecanism mai complicat, se poate extinde foarte ușor acest lucru prin implementarea unei interfețe.
In general cam toate cazurile de care o sa avem nevoie pentru a consuma un serviciu în format REST sunt acoperite, dar putem fără probleme sa extindem acest API. Chiar am avut nevoie sa fac acest lucru, pentru un serviciu de la Yahoo destul de ciudat. Mi-a luat cam 20 de minute sa fac acest lucru cu tot cu testare. Pana acuma personal nu am descoperit nici un bug la RESTSharp.
Din punct de vedere a documentației, exista un wiki destul de okay. Ultimul release a fost făcut în mai 2011.
Ca un overall, sunt mulțumit de acest client de REST. Daca nu o sa îl folosiți, măcar merita sa va uitați peste codul sursa înainte sa începeți sa faceți ceva asemănător. Cea mai frumoasa idee mi s-a părut ideea de a putea seta tipul la fiecare parametru în parte. A.i. aceasta lista se poate refolosii și la alte requesturi fără nici o problema.
Read More
Posted in .NET, REST, REST Client, RESTSharp | No comments
Newer Posts Older Posts Home
Subscribe to: Comments (Atom)

Popular Posts

  • Service Bus Topic - Automatic forward messages from a subscription to a topic
    Windows Azure Service Bus Topic is a service that enables us to distribute the same messages to different consumers without having to know e...
  • CDN is not the only solution to improve the page speed - Reverse Caching Proxy
    I heard more and more often think like this: “If your website is to slow, you should use a CDN.” Great, CDN is THE solution for any kind of ...
  • Patterns in Windows Azure Service Bus - Message Splitter Pattern
    In one of my post about Service Bus Topics from Windows Azure I told you that I will write about a post that describe how we can design an a...
  • E-Learning Vendors Attempt to Morph Mobile
    The sign should read: " Don't touch! Wet Paint !" I had a good chuckle today after receiving my latest emailed copy of the eLe...
  • Content Types - Level 6: Rich Media
    Level 6: Rich Media NOTE: This is part 7 of 7 and the conclusion of this continuing series; please see earlier posts for more background inf...
  • Publishing our CellCast Widget for iPad
    The rush has been on this week as our development team worked to design a new version of our CellCast Widget specifically for Apple's up...
  • Content Types - Level 5: Courseware
    Level 5: Content and Courseware NOTE: This is part 6 of 7 in a continuing series; please see earlier posts for more background information. ...
  • SQL - UNION and UNION ALL
    I think that all of us used until now UNION in a SQLstatement. Using this operator we can combine the result of 2 queries. For example we wa...
  • Cum sa salvezi un stream direct intr-un fisier
    Cred ca este a 2-a oara când întâlnesc aceasta cerința in decurs de câteva săptămâni. Se da un stream și o locație unde trebuie salvat, se c...
  • Task.Yield(...), Task.Delay(...)
    I think that a lot of person already heard about these new methods. In this post I want to clarify some things about these new methods that ...

Categories

  • .NET
  • .NET nice to have
  • #if DEBUG
  • 15 iunie 2011
  • 15 octombrie 2011
  • 2011
  • abstracta
  • action
  • adaugare
  • ajax
  • Amsterdam
  • Android
  • aplicatii
  • App Fabric
  • Apple iSlate
  • array
  • as
  • ASP.NET
  • AsReadOnly
  • Assembly comun
  • async
  • Asynchronous programming
  • asyncron
  • Autofac
  • AutoMapper
  • az
  • Azure
  • Azure AppFabric Cache
  • Azure backup solution
  • Azure Storage Explorer
  • azure. cloud
  • backup
  • BCP utility
  • bing maps v7
  • BitArray
  • BlackBerry
  • blob
  • BlobContainerPublicAccessType
  • breakpoint
  • bucuresti
  • C#
  • cache
  • CallerMemberName
  • CellCast
  • Certificate
  • CES
  • change
  • ChannelFactory
  • clasa
  • classinitialize
  • clean code
  • click event
  • close
  • Cloud
  • Cluj
  • cluj-napoca
  • Code contracts
  • code retrat
  • codecamp
  • CollectionAssert
  • Compact Edition
  • compara
  • Comparer T .Default
  • CompareTo
  • comparison
  • comunitate
  • concurs
  • Conditional attribute
  • configurare
  • connection string
  • container
  • content type
  • control
  • Convert
  • convertAll
  • convertor
  • cross platform
  • CRUD
  • css
  • custom properties
  • custom request
  • DACPAC
  • Daniel Andres
  • data sync service
  • database
  • date time
  • datetime
  • debug
  • default
  • delegate
  • dependency injection
  • deploy
  • DeploymentItem
  • design patterns
  • Dev de Amsterdam
  • development stoage
  • dictionary
  • diferente
  • digging
  • director
  • Directory.Exist
  • disable
  • dispatcher
  • dispose
  • dropdown
  • dynamic
  • EF
  • email
  • encoding
  • entity framework
  • enum
  • enumerable
  • Environment.NewLine
  • error
  • error 404
  • error handling
  • eveniment
  • event
  • ews
  • excel
  • exception
  • exchange
  • exita
  • explicit
  • export
  • extension
  • field
  • File.Exist
  • finalize
  • fire and forget
  • Fluent interface pattern
  • format
  • func
  • GC.SuppressFinalize
  • generic
  • getdirectoryname
  • globalization
  • gmail
  • hackathon
  • Hadoop
  • handle
  • HTML
  • html 5
  • Html.ActionLink
  • http://www.blogger.com/img/blank.gif
  • HttpModule
  • IComparable
  • IE
  • ienumerable
  • IIS
  • image
  • implicit
  • import
  • int
  • internationalization
  • Internet Explorer
  • interop
  • Ioc
  • IP Filter
  • iPhone
  • iQuest
  • IStructuralEquatable
  • ITCamp
  • itspark
  • java script
  • javascript
  • July 2012
  • KeyedByTypeCollection
  • KeyNotFoundException
  • Kinect SDK
  • lambda expression
  • LightSwitch Microsoft Silverlight
  • linq
  • list
  • lista
  • lista servicii
  • liste
  • Live Connect
  • Live ID
  • load
  • localization
  • lock
  • m-learning
  • MAC
  • Mango
  • map
  • mapare
  • mapare propietati
  • messagequeue
  • meta properties
  • method
  • MethodImpl
  • Metro App
  • Microsoft
  • Microsoft Sync Framework
  • mlearning
  • mlearning devices
  • Mobile Apps
  • mobile in the cloud
  • mobile learning
  • mobile services
  • Mobile Web
  • mongoDb
  • monitorizare
  • msmq
  • multitasking
  • MVC
  • MVC 3
  • MVVM
  • namespace
  • nextpartitionkey
  • nextrowkey
  • Ninject
  • nivel acces
  • no result
  • normalize
  • nosql
  • null expcetion
  • null object pattern
  • NullReferenceException
  • OAuth API
  • office
  • offline
  • Open ID
  • openhackeu2011
  • operations
  • operator
  • optimization
  • option
  • outputcache
  • OutputCacheProvider
  • override
  • paginare
  • pagination
  • path
  • persistare
  • Portable Library tool
  • Post event – CodeCamp Cluj-Napoca
  • predicate
  • predictions
  • prezentare
  • process
  • proiect
  • property
  • propietati
  • query
  • ReadOnlyCollection
  • ReadOnlyDictionary
  • referinta
  • reflection
  • remote
  • reply command
  • request
  • request response
  • resouce
  • REST
  • REST Client
  • RESTSharp
  • ronua
  • rss
  • rulare
  • salvare in fisier
  • sc
  • schimbare timp
  • select
  • select nodes
  • send
  • serializare
  • serialization
  • Server.Transfer. Resposen.Redirect
  • service bus
  • ServiceBase
  • servicecontroller
  • sesiune
  • session
  • Session_End
  • Session_Start
  • setup
  • Sibiu
  • signalR
  • Silverlight
  • sincronizare
  • Single Responsibility Principle
  • SkyDrive
  • skype
  • smartphones
  • smtp
  • Snapguide
  • sniffer
  • socket
  • solid
  • spec#
  • sql
  • Sql Azure
  • SQL CE
  • sql server 2008 RC
  • SRP
  • startuptype
  • stateful
  • stateless
  • static
  • stergere
  • store
  • store procedure
  • stream
  • string
  • string.join
  • struct
  • StructuralEqualityComparer
  • submit
  • switch
  • Symbian
  • Synchronized
  • system
  • tabele
  • table
  • techEd 2012
  • tempdata
  • test
  • testcleanup
  • testinitialize
  • testmethod
  • thread
  • timer
  • ToLower
  • tool
  • tostring
  • Total Cost Calculator
  • trace ASP.NET
  • transcoding
  • tuplu
  • tutorial
  • TWmLearning
  • type
  • unit test
  • unittest
  • UrlParameter.Optional
  • Validate
  • validation
  • verificare
  • video
  • view
  • ViewBag
  • virtual
  • visual studio
  • VM role
  • Vunvulea Radu
  • wallpaper
  • WCF
  • WebBrower
  • WebRequest
  • where clause
  • Windows
  • windows 8
  • Windows Azure
  • Windows Azure Service Management CmdLets
  • windows live messenger
  • Windows Mobile
  • Windows Phone
  • windows service
  • windows store application
  • Windows Task
  • WinRT
  • word
  • workaround
  • XBox
  • xml
  • xmlns
  • XNA
  • xpath
  • YMesseger
  • Yonder
  • Zip

Blog Archive

  • ►  2013 (139)
    • ►  November (17)
    • ►  October (12)
    • ►  September (10)
    • ►  August (7)
    • ►  July (8)
    • ►  June (15)
    • ►  May (12)
    • ►  April (17)
    • ►  March (16)
    • ►  February (9)
    • ►  January (16)
  • ►  2012 (251)
    • ►  December (9)
    • ►  November (19)
    • ►  October (26)
    • ►  September (13)
    • ►  August (35)
    • ►  July (28)
    • ►  June (27)
    • ►  May (24)
    • ►  April (18)
    • ►  March (17)
    • ►  February (20)
    • ►  January (15)
  • ▼  2011 (127)
    • ►  December (11)
    • ►  November (20)
    • ►  October (8)
    • ►  September (8)
    • ►  August (8)
    • ▼  July (10)
      • (2) How to use Office in Silverlight applications
      • (1) How to use Office in Silverlight applications.
      • Where constraint wonder
      • Where clause
      • Add files to unit tests output - DeploymentItem
      • Session on Azure AppFabric Cache
      • Suppress IE invalid certificate warning
      • Azure AppFabric Cache API
      • Client IP Filter on Windows Azure
      • REST Client - RESTSharp
    • ►  June (5)
    • ►  May (8)
    • ►  April (9)
    • ►  March (14)
    • ►  February (20)
    • ►  January (6)
  • ►  2010 (26)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (4)
    • ►  March (1)
    • ►  February (1)
    • ►  January (14)
Powered by Blogger.

About Me

Unknown
View my complete profile