SilverCRM cz. 3 – kilka aspektów związanych z komunikacją Silverlight i CRM

Część druga projektu SilverCRM zakończyła się wspomnieniem na temat aspektów związanych z komunikacją pomiędzy komponentem Silverlight a CRM. Aby je opisać trzeba zrozumieć różnicę pomiędzy np. stronami *.aspx, które wbudowane są w formatkę CRM i znajdują się na serwerze IIS w katalogu ISV. Strony takie uruchamiane są po stronie IIS a klient (czyli przeglądarka) dostaje efekt pracy wykonanej po stronie serwera. Całe wykonanie kodu leży po stronie serwera. W przypadku komponentu Silverlight sprawa wygląda nieco inaczej. To, że znajduje się on na serwerze IIS w tej samej lokalizacji jak strona *.aspx jest jedyną ich cechą wspólną. Wykonanie kodu w przypadku komponentu jest przeniesione na maszynę klienta, tam następuje wykonanie kodu i jednocześnie prezentacja wyniku. Z jednej strony serwer IIS jest odciążony od obsługi dużej ilości żądań a z drugiej strony nasz komponent rozprzestrzenił się po wszystkich stacjach klienckich, które z niego korzystały.

W przypadku usług, z którymi komponent będzie się łączyć może wystąpić problem komunikacji cross-domain. Polega on na tym, że usługa może znajdować się w innej domenie niż nasz komponent, a wtedy wykonanie naszego kodu zakończy się błędem. Rozwiązaniem tego problemu jest umieszczenie po stronie usługi pliku, w którym należy wyspecyfikować, z którym domen usługa powinna obsługiwać żądania. Plik ten musi być nazwany clientaccesspolicy.xml i znajdować się w musi w katalogu głównym naszej usługi. Przykład takiego pliku jest następujący:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

W tym pliku mamy zezwolenie na łączenie się do usługi z dowolnej domeny: <domain uri="*"/>. Zamiana tego elementu powoduje zezwolenie na łączenie się ze wskazanej domeny. Można również skorzystać z pliku crossdomain.xml, który znany jest chociażby z Flash – na ten temat można znaleźć informacje tutaj: http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx

Kolejnym aspektem jest korzystanie z metod usługi CRM. Jak już możemy się z nią odpowiednio komunikować możemy np. pobrać wszystkie konta, do których mamy prawo. Kod, który to zrobi wygląda tak:

QueryExpression _query = new QueryExpression();
_query.ColumnSet = new AllColumns();
_query.EntityName = "account";
_client.RetrieveMultipleAsync(_query);

Jednakże jak się okazuje, mimo, że kolekcja zawiera odpowiednią liczbę elementów o tyle elementy te mają wszystkie właściwości ustawione na null. Błąd ? Z tego co wyczytałem na forach jest to błąd Silverlight, który powinien zostać wyeliminowany, ale z tego co widać jeszcze nie został. Na szczęście jest tzw. workaround. Zamiast pisać krótki kod do pobierania elementów trzeba zawsze pobierać elementy w postaci DynamicEntity. Wtedy dostając się do kolekcji właściwości otrzymamy dane, które nie będą null.

RetrieveMultipleRequest _request = new RetrieveMultipleRequest();
_request.Query = _query;
_request.ReturnDynamicEntities = true;
_client.ExecuteAsync(_request);

Na szczęście tworząc nowe obiekty w CRM, np. nowe konto nie musimy tworzyć obiektu w postaci DynamicEntity tylko możemy korzystać z bezpośrednich klas.

Mając wiedzę z trzech wpisów, które tutaj zamieściłem każdy będzie mógł zacząć tworzyć to, na co jego biznes ma ochotę. Mając do dyspozycji Silverlight można w CRM wbudować bardzo bogato wyglądające elementy, np. piękne raporty, strumieniowanie - jednym słowem wszystko to co oferuje Silverlight.