Skip to main content

Posts

Showing posts from March, 2011

Cum sa scriem un xPath cand avem definit si un namespace

Cand vrem sa aplicam un xPath pe un xml ce conține si un namespace lucrurile se complica.
De exemplu daca pornim de la urmatorul xml:
<?xml version="1.0" ?>
<x xmlns="http://www.xyz.com/">
<y>1</y>
<y>2</y>
</x>
Daca dorim sa aplicam un xPath am scrie un cod asemanator cu acesta:
var xmlDoc = new XmlDocument();
xmlDoc.Load(sursa);
var nodes = xmlDoc.SelectNodes(@"/x/y");
Din pacate din cauza ca in xml este definit un namespace, acest lucru nu o sa functioneze. Numarul de noduri returnate va fi mereu 0. Pentru a putea rezvolta aceasta problema trebuie sa adaugam si un namespace, codul rezultat ajungand sa arate in felul urmator:
var xmlDoc = new XmlDocument();
xmlDoc.Load(sursa);
var nameSpaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
nameSpaceManager.AddNamespace("nm","http://www.xyz.com/");
var nodes = xmlDoc.SelectNodes(@"/nm:x/nm:y",nameSpaceManager);
Dezavantajul la aceasta solu…

Blob content type - Windows Azure

La fiecare blob din Windows Azure se poate seta content type. De cele mai multe ori acest parametru trece neobservat.
Mai jos este un exemplu care arata cum se poate schimba aceasta valoare:
Paste your text here.var blob = Container.GetBlockBlobReference("numeBlob");
blob.Properties.ContentType = "application/octet-stream";
Cand aceasta propietate devine utila? In momentul in care vrem sa stocam pe blob resurse statice. De exemplu vrem sa adaugam un CSS pe blob, iar href pentru CSS sa fie spre adresa din blob. Pentru ca aceasta solutie sa functioneze pe orice brower( Firefox are nevoie de un content type valid) este nevoie sa setam valoarea la content type egala cu "text/css".
var blob = Container.GetBlockBlobReference("numeBlob");
blob.Properties.ContentType = "text/css";
Daca aceasta valoare nu este setata pe Firefox nu o sa se incarce deloc CSS-ul, desi adresa setata este valida.

Nivele de acces pentru containerele din Windows Azure.

Pe blob-urile din Windows Azure putem sa stocam orice fel de conținut, de la poze si filme la carti sau arhive. Cand vrem sa partajam aceasta informație cu alte persoane apare mai multe intrebari:
Ce poate sa faca un utilizator pe blob?Ce poate sa faca un utilizator pe container?Un utilizator are dreptul sa acceseze container-ul si sa il parcurgă?La nivel de container putem sa setam trei nivele de acces. Varianta pe care o alegeți trebuie aleasa cu grija, deoarece aceasta va afecta in mod direct modul in care un utilizator anonim poate sa acceseze un blob.
Prima varianta este "Full public read access". Un utilizator anonim poate sa citească din orice blob sau container. Acesta poate sa itereze in interiorul container. Singurul lucru pe care nu il poate sa faca este sa intereze prin containere.
A doua varianta este "Public read access for blobs only". Aceasta se aseamana cu prima varianta, doar ca un utilizator nu poate sa itereze prin conținutul unui container.
Ultima …

Cum sa facem handling la evenimente dontr-o pagina HTML afisare printr-un controler Silverlight

Pentru a putea face acest lucru avem nevoie de un mecanism prin care sa trasmitem evenimentul produs. O solutie este javascript.
In Silverlight avem doua controlare care se ocupa cu acest lucru WebBrower si HtmlBrush. Din pacare doar WebBrower stie sa faca handling la evenimente de java script. Prin intermediul acestora codul C# poate sa apele metode javascrip din interiorul paginii pe care o afisam sau sa se inregistreze la anumite evenimente(metode).
Pentru a putea face acest lucru este nevoie sa adaugam in fisierul xaml controlerul care ne permite sa afisam continut HTML:
<WebBrowser x:Name="browserControl" />

Pasul urmator este sa ne inregistram la notificarea dorita. Aceasta notificare reprezinta un apel a unei metode din javascript.
browserControl.ScriptNotify += new EventHandler<NotifyEventArgs>(BrowserControl_ScriptNotify);
...
void browserControl_ScriptNotify(object sender, NotifyEventArgs e)
{
...
}
In acest moment toate mesajele de notificare o sa fie pri…

Cum sa faci deploy din Visual Studio direct in cloud

Visual Studio 2010 ne ofera posibilitatea de a face deploy( publish) la un proiect direct in cloud. Mecanismul prin care se face deploy este asemanator cu cel pentru o solutie web.
Primul pas este sa dam click dreapta pe proiectul care contine rolurile pentru Azure si sa selecta "Publish".
Al doilea pas este selectam "Deploy your Windows Azure project to Windows Azure". O sa avem nevoie sa adaugam credentialele daca acestea nu sunt setate deja. Pentru a putea adauga credentialele avem nevoie sa selectam un certificat( putem sa folosim unul deja existent sau sa generam unul local), iar apoi ID-ul subscripției noastre. Insa aici apare o problema cand vrem sa dam OK. Nu o sa putem sa adaugam credentialele pentru subcriptia noastra pana cand nu inregistram certificatul pe platforma de Windows Azure.
Pentru a inregistra certificatul este nevoie sa il exportam de pe masina noastra folosind tool-ul mmc.exe. Iar apoi este nevoie sa ne logam pe https://windows.azure.com/ si s…

Cum sa controlam modul in care un serviciu windows porneste din cod

Prin intermediul la clasei ServiceController putem sa controlam un serviciu windows. Il putem in orice moment porni sau oprii. Dar daca avem nevoie sa ii schimbam startup type? De exemplu daca vreau sa ii schimb startup type-ul de pe manual pe automat?
Din pacate ServiceController nu ne oferă aceasta funcționalitate. Din cod C# nu am gasit o posibilitatea prin care as putea sa fac acest lucru. In schimb am gasit in registry bine ascunse aceste valori.
Daca deschidem registrii si ne uitam sub Local System in path-ul "SYSTEM\CurrentControlSet\Services\" o sa gasim lista cu toate serviciile pe care le avem instalate pe masina. Pentru fiecare serviciu avem:
numedescrieretipulstartup type-ulpath-ul spre serviciu
etcDaca schimbam una din aceste valori, sistemul de operare o sa faca update automat la serviciu. O solutie la probleme noastra este sa facem o metoda care scrie valoarea in registri.
public enum StartupModeType
{
Boot = 0,
System = 1,
Automatic = 2,

Definirea unui mecanism de comparare a entitatiilor din punct de vedere a structurii folosind IStructuralEquatable

Uneori avem nevoie sa putem compara clasele de tip POCO ca pe niste structuri. De exemplu daca avem clasa Student, dorim sa comparam entitatile de acest tip din punct de vedere a datelor pe care le contin.
class Student
{
public string Nume{ get;set;}
public string Prenume{ get;set;}
public int Varsta{ get;set;}
}
Pentru acest lucru sa folosim IStructuralEquatable. Aceasta interfata a fost creata pentru a fi folosita in tupluri. In cazul acestora, doua tupluri sunt egale daca fiecare element din tuplu este egal din celalalt tuplu.
Interfata contine doua metode:
bool Equals(Object other, IEqualityComparer comparer);
int GetHashCode(IEqualityComparer comparer);
Prin intermediul parametrului comparer se defineste mecanismul de comparare. Exista cateva implementari in .NET pentru IEqualityComparer prin care putem sa comparam siruriile de elemente - element cu element.
Valoarea default a acestui parametru este EqualityComparer>Object<.Default.Equals in cazul in care se foloseste mecanismul stand…

MVC 3 - UrlParameter.Optional

Zilele astea am inceput sa ma uit peste MVC 3 si sa vad ce a adus nou. S-a scris foarte mult, nu am de gand sa desfac firul in patru cu fiecare lucru aparut in MVC 3. In schimb vreau sa va spun peste ce problema am dat.
In MVC 2 cand se declara un map route - unul sau mai multi parametrii pot sa fie optionali. In acest caz cand se face apelul unei actiuni, acesti parametri pot sa lipseasca.
De exemplu putem sa avem urmatoarea mapare:
routes.MapRoute(
"Drive",
"drive/go/strada/numar"
controller = "Drive",
new
{
action = "Go",
numar = UrlParameter.Optional
bloc = UrlParameter.Optional
});
Antetul actiuni ar avea forma:
public ActionResult Go(string strada, int? numar,int? bloc);
Apelul spre aceste acțiuni am dorii sa fie de forma:
http://localhost/drive/go?strada=Dunarii
http://localhost/drive/go/Dunarii/10/5
http://localhost/drive/go/Dunarii
O sa observam ca pentru prima varianta http://localhost/drive/go?strada=Du…

Enumerable.Zip

Daca avem doua liste si este nevoie sa facem merge la elemente doua cate doua in ordinea pozitiei din lista este nevoie sa scriem un cod asemanator cu acesta:
var numeList = new[] { "Ioan", "Gheorghe", "Mihai", "Laurentiu" };
var prenumeList = new[] { "Pop", "Rus", "Ratiu", "Negru" };
var numePrenumeList = new List<string>();
for(int i = 0; i < numeList.Count(); i++)
{
numePrenumeList.Add(numeList[i] + " " + prenumeList[i]);
}

Rezultatul ar fi:
Ioan Pop
Gheorghe Rus
Mihai Ratiu
Laurentiu Negru
Acelasi lucru putem sa il facem daca folosim metoda Enumerable.Zip. Prin intermediul acestei metode putem sa facem merge intre doi vectori element cu element:
var numePrenumeList = numeList.Zip(
prenumeList,
(nume, prenume) => nume + " " + prenume);
Nu o sa avem nevoie de acesta metoda in fiecare zi, dar mi s-a parut o metoda pe care merita sa o cunoastem.
Update:
In cazu…

OutputCache in Windows Azure folosind AppFabric.Cache

In post-ul anterior am vorbit despre cum putem sa ne definim propriul nostru mecanism de cache-ing. Dar daca ne aflam in cloud.
Iata urmatorul scenariu: avem o aplicatie MVC 2 pe Windows Azure si vrem sa putem folosii un mecanism de cache-ing. In cazul in care avem mai multe web roluri dorim sa facem un sistem de cache-ing oarecum centralizat. Nu dorim sa încărcam de doua ori anumite date daca acestea sunt deja incarcate.
O varianta pentru a rezolva aceasta problema este sa ne definim propriul mecanism pentru cache-ing. Nu ar fi foarte complicat, dar ne-ar costa ceva timp. Cea mai simpla varianta este sa folosim mecanismul intern de pe Windows Azure. AppFabric ne ofera si posibilitatea sa facem cache-ing la date. Acest provider de cache-ing se numeste DistributedCache, iar pentru al putea folosi este nevoie sa accesam sectiunea de AppFabric din contul de Windows Azure si sa adaugăm un serviciu.
In web.config-ul aplicatiei trebuie sa adauga o noua sectiune prin care sa putem d…

Cum sa definesti un provider custom pentru cache

.NET 4.0 ne-a adus si posibilitatea de a controla output caching. Pana in momentul acesta puteam sa controlam obiectele la care sa se faca cache. Daca de exemplu avem o actiune la care doream sa facem cache, puteam sa folosim atributul OutputCacheAttribute, prin care puteam defini durata la care sa se faca cache si prin ce parametri acest cache sa difere.
[OutputCache(Duration=20, VaryByParam="none")]
public ActionResult GetItems()
{
// Executa ceva.
}
In momentul in care se face un call spre actiunea GetItems, se verifica daca aceasta exista in cache si daca cache-ul este valid( nu a expirat iar parametri trasmisi prin VaryByParam sunt identici). Daca conditiile sunt indeplinite atunci rezultatul se incarca automat din cache si se trimite mai departe, altfel se executa actiunea GetItems, iar rezultatul se salveaza in cache.
In cazul in care dorim sa definim un provider propiu pentru output cache este nevoie sa scriem o clasa ce sa mosteneasca din OutputCacheProvider.
public…

ReadOnlyCollection

Va mai aduceti aminte ca in C++ puteam sa declaram o variabila sa fie constanta, fara a ne face probleme ca un utilizator ii poate schimba valoarea. In C# putem sa facem un lucru asemanator folosindu-ne de readonly.
public class Car
{
internal readonly int _id;

public Car(int id)
{
_id = id;
}
}
Doar in contructor se va putea initializa field-ul _id. Valoarea acestui camp nu se va putea modifica in nici o locatie din cod. Dar daca in loc de int am aveam o lista, ar aparea probleme. Chiar daca nu se va putea instanta din nou acest camp, continutul acestuia se va putea modifica.
public class Car
{
internal readonly List<Component> _components;

public Car(List<Component> components)
{
_components = components;
}
}

public class Logan : Car
{
// ...

public void SomeMethod()
{
_components.Add(..);
_components.Remove(..);
}
}
Oricine ar putea sa adauge sau sa stearga elemente din lista. Am avea nevoie de o lista care sa permit…

Null object pattern - design pattern

Acest design pattern ar trebui sa ne ajute pentru a elimina sau cel putin sa reducem numarul de verificare de genul:
If( obj != null )
{
//Ceva cod.
}
Pentru a putea folosi acest design pattern este nevoie sa declaram o instanta a unui obiect( sau o clasa) care sa joace rolul obiectului care reprezinta valorea null. Exista doua varinte de implementare, de la caz la caz se poate folosi una din ele.
In prima varianta se foloseste o instanta a clasei care joaca rolul de valoarea NULL. Aceasta este oferita dezvoltatorului prin intermediul unei propietati statice.
public class Car
{
public static readonly Car NullObj;

static Car
{
NullObj = new Car();
//Setare valori, propietati cu valori default.
}
}
Deoarece am declarat field-ul ca fiind read-only, setarea acestuia se va putea face doar in constructor. Codul pe care o sa il folosim acuma o sa fie asemanator cu:
if( car == Car.NullObj )
{
//Executa ceva
}
In cazul in care vrem sa apelam metode sau propietati, putem le a…