Pokazywanie postów oznaczonych etykietą Visual Studio 2010. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Visual Studio 2010. Pokaż wszystkie posty

Skróty klawiaturowe w VS 2010

Nowy obraz

Nie wiem jak Wy, ale dla mnie znajomość skrótów klawiaturowych w VS pozwala zaoszczędzić czas i spędzić go na produktywnym kodowaniu niż na “przeklikiwaniu się” poprzez kolejne elementy interfejsu VS.

Dla tych, którzy myślą podobnie :) Microsoft udostępnił listy skrótów klawiaturowych dla różnych języków, które dostępne są na stronie: http://www.microsoft.com/downloads/details.aspx?FamilyID=92CED922-D505-457A-8C9C-84036160639F&displaylang=en

SilverCRM cz. 2 – połączenie z Dynamics CRM.

Silverlight, aby spełnić wymaganie przed nim stawiane – uruchamianie się na różnych systemach operacyjnych (Windows, Linux, Mac) i w różnych przeglądarkach (IE, Firefox, Safari) – został zbudowany niejako obok .NET Framework. Fundamentem .NET Framework jest CLR. Silverlight został wyposażony w specjalne środowisko uruchomieniowe oraz w specjalny zbiór klas, aby móc spełnić tym wymaganiom. Jeśli chodzi o warstwę komunikacyjną to posiada on wbudowany WCF (Windows Communication Foundation). Chcąc skomunikować ze sobą Dynamics CRM oraz Silverlight będziemy łączyć ze sobą technologią ASP.NET oraz WCF. Jak dalej zostanie opisane – nie zawsze jest to, aż takie proste :)

Pierwszym krokiem jest skorzystanie z opcji dodania referencji do usługi. W przypadku starszych technologii w VS posiadaliśmy opcję Add Web Reference. Wraz z WCF dostaliśmy opcję Add Service Reference, którą można było zamienić na zwykłą Web Reference (wchodzą w dodatkowe ustawienia). W Silverlight nie mamy takiej opcji i musimy korzystać tylko z Service Reference – tak jak to jest pokazane na rysunku:

 

Skorzystanie z opcji dodania referencji do usługi spowoduje wyświetlenie okienka, w którym wprowadzić będzie trzeba adres, pod którym dostępna będzie usługa (np. http://localhost/MSCrmServices/2007/CrmService.asmx). Można tutaj również wskazać np. ścieżkę na lokalnym dysku gdzie znajduje się plik z definicją usługi (*.wsdl). Po odpowiednim skonfigurowaniu i wygenerowaniu namiastki zostanie w projekcie utworzony katalog Service References gdzie znajdziemy kod źródłowy stworzonej namiastki.

 

Oprócz kodu namiastki zostanie wygenerowany plik konfiguracyjny, który będziemy mogli wykorzystać w czasie tworzenia instancji namiastki. Zamiast pisać kod i wskazywać, z których wiązań i w jakiej konfiguracji należy korzystać można te wartości wskazać w pliku konfiguracyjnym i w czasie tworzenia instancji namiastki na ten plik się powoływać. Przykładowy plik konfiguracyjny wygląda następująco:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="CrmServiceSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
                    <security mode="None" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="
http://localhost/MSCrmServices/2007/CrmService.asmx"
                binding="basicHttpBinding" bindingConfiguration="CrmServiceSoap"
                contract="CrmSdk.CrmServiceSoap" name="CrmServiceSoap" />
        </client>
    </system.serviceModel>
</configuration>

Warto tutaj zwrócić uwagę na nazwę końcówki (endpoint), która w pokazanym pliku jest ustawiona na CrmServiceSoap. W momencie tworzenia instancji namiastki będzie można wskazać na jaką konfigurację WCF musi się powołać, aby poprawnie namiastkę zainicjować.

Warto tutaj zwrócić uwagę na nazewnictwo klas wygenerowanym z pliku *.wsdl usługi CRM. W czasie tworzenia namiastki poprzez zwykłe Web Reference dostawaliśmy w efekcie klasę CrmService. Tutaj otrzymujemy CrmServiceSoapClient. Inne klasy takie jak account, contact, reprezentujące obiekty CRM generowane są bez żadnych zmian.

Tworzenie instancji namiastki jest następujące:

CrmServiceSoapClient _client = new CrmServiceSoapClient("CrmServiceSoap");

gdzie CrmServiceSoapClient jest klasą wygenerowaną przez WCF, natomiast argumentem konstruktora tej klasy jest wskazanie konfiguracji końcówki z pliku konfiguracyjnego również wygenerowanego przez WCF.

Silverlight umożliwia wywoływanie tylko i wyłącznie metod asynchronicznych. Zatem w namiastce nie mamy metod CrmService takich jak Execute, Create, Update. Mamy natomiast metody ExecuteAsync, CreateAsync, itd. Wszelkie operacji przy pomocy Silverlight wykonywane są asynchronicznie !!! Mając to na uwadze po utworzeniu namiastki trzeba obsłużyć zdarzenia zakończenia wykonywania operacji asynchronicznej. Przykładowy kod wygląda tak:

_client.RetrieveMultipleCompleted += new EventHandler<RetrieveMultipleCompletedEventArgs>(OnClientRetrievedMultiple);
_client.ExecuteCompleted += new EventHandler<ExecuteCompletedEventArgs>(OnClientExecuteCompleted);

, gdzie metody OnClientRetrievedMultiple oraz OnClientExecuteCompleted są zdefiniowane następująco:

void OnClientExecuteCompleted(object sender, ExecuteCompletedEventArgs e) {}

void OnClientRetrievedMultiple(object sender, RetrieveMultipleCompletedEventArgs e) {}

Aby wiedzieć do jakiej organizacji się połączyć do tej pory (tzn. korzystając z Web Reference) otrzymywaliśmy klasę CrmAuthenticationToken, który umożliwiał wskazanie do której organizacji chcemy się połączyć, w jaki sposób chcemy dokonać uwierzytelnienia, itd. W przypadku WCF oczywiście otrzymujemy klasę CrmAuthenticationToken w namiastce jednakże klasa CrmServiceSoapClient nie posiada właściwości, która umożliwia ustawienia i wykorzystanie tokenu. Aby poprawnie połączyć się z usługą CRM musimy mieć możliwość dołączenia do żądań SOAP nagłówka – musimy mieć metodę GenerateAuthenticationHeader, którą mamy jak piszemy skrypt uruchamiany, np. na zdarzeniu OnLoad formatki CRM. Metodę tą możemy zbudować korzystając z kanały komunikacyjnego, z którego korzysta WCF. Musimy ręcznie dołączyć nagłówek do wiadomości wychodzących od naszego komponentu:

MessageHeader header = MessageHeader.CreateHeader("CrmAuthenticationToken",
                  "http://schemas.microsoft.com/crm/2007/WebServices",
                  "",
                  new CrmAuthenticationTokenSerializer(0, orgname, null));

OperationContext.Current = new OperationContext((IContextChannel)_client.InnerChannel);
OperationContext.Current.OutgoingMessageHeaders.Add(header);

Klasa CrmAuthenticationTokenSerializer jest naszą własną klasą dziedziczącą po XmlObjectSerializer:

    public class CrmAuthenticationTokenSerializer : XmlObjectSerializer
    {
        int _authType;
        string _organizationName;
        string _callerId;

        public CrmAuthenticationTokenSerializer (int authType, string organizationName, string callerId)
        {
            _authType = authType;
            _organizationName = organizationName;
            _callerId = callerId;
            if (_callerId == null)
            {
                _callerId = "00000000-0000-0000-0000-000000000000";
            }
        }


        public override void WriteStartObject(XmlDictionaryWriter writer, Object graph)
        {
        }

        public override void WriteObjectContent(XmlDictionaryWriter writer, Object graph)
        {
            string authToken = string.Format("<AuthenticationType xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>

            {0}</AuthenticationType><OrganizationName xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>

            {1}</OrganizationName><CallerId xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>

            {2}</CallerId>", _authType, _organizationName, _callerId);

            writer.WriteRaw(authToken);
        }

        public override void WriteEndObject(XmlDictionaryWriter writer)
        {
        }


        public override bool IsStartObject(XmlDictionaryReader reader)
        {
            return true;
        }

        public override Object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
        {
            return null; 
        }

    }

Mając tak zdefiniowaną klasę możemy przystąpić do wywoływania metod usługi CRM. Jednakże w czasie wywołania najprostszego żądania, np. WhoAmIRequest dostaniemy błąd związany z komunikacją pomiędzy domenami. Dlaczego tak się dzieje ? O tym w kolejnym wpisie. Tam również kilka informacji na temat błędów związanych z metodami Retrieve oraz RetrieveMultiple.

SilverCRM cz. 1 – nowy projekt

Planując napisanie kilku wpisów poświęconych tworzeniu połączenie CRM z Silverlight jeden wpis chciałem poświęcić narzędziom, które trzeba mieć, aby móc sprostać temu zadaniu. Wtedy na rynku w wersji finalnej był VS 2008 a na portalu www.silverlight.net znaleźć można było szereg toolkitów, które dodawały do tego narzędzi chociażby nowy typ projektu.

W międzyczasie pojawił się produkt VS2010, który wszystkie narzędzia ma w sobie wbudowane więc z wpisu z przygotowania do rozpoczęcia pracy można było zrezygnować. Dla osób, które nie decydują się jeszcze na przejście na VS 2010 polecam lekturę portalu www.silverlight.net – tam są wszelkiego rodzaju informacje jakie narzędzia i jak skonfigurowane są potrzebne aby wykonać to co dalej w tym wpisie (i we wpisach kolejnych będzie opisane).

A więc do dzieła. Korzystam z Visual Studio Web Developer 2010 Express, które bez żadnych kosztów pobrać można ze strony: http://www.microsoft.com/express/

VS 2010

Tworząc nowy projekt wybieram szablon Silverlight –> Silverlight Application (ja preferuję C#). Po ustawieniu nazwy aplikacji, lokalizacji jej plików źródłowych oraz nazwy rozwiązania VS klikamy przycisk OK. Pojawi nam się okienko, przy pomocy którego będziemy mogli wygenerować aplikację internetową, w której będzie masz komponent Silverlight uruchamiany.

imageZ aplikacji takiej można oczywiście zrezygnować, jednakże w naszym przypadku chcemy, aby komponent Silverlight był uruchamiany w kontekście CRM. Zanim jednak ten komponent będziemy wbudowywać w CRM warto popracować nad samym komponentem: zbudować kod, przetestować, popracować nad wyglądem. Temu służy właśnie ta generowana aplikacja.

Na samym dole okienka mamy możliwość wybrania wersji Silverlight, z której będziemy korzystać. Domyślnie VS 2010 zainstalowany jest z wersją 3 Silverlight. Aby móc korzystać z wersji 4 należy doinstalować narzędzie, które jest do pobrania ze strony: http://www.microsoft.com/downloads/details.aspx?FamilyID=bf5ab940-c011-4bd1-ad98-da671e491009&displaylang=en (pamiętać należy, że jest to wersja RC2 – taka przynajmniej była aktualna w czasie pisania tego wpisu). Ja pozostanę na razie przy wersji 3, gdyż to co chcę zaprezentować nie wymaga wersji 4.

Po wybraniu OK czekamy chwilę na zakończenie procesu generowania projektów.

W oknie Solution Explorer zobaczymy dwa projekty – jeden odpowiada komponentowi Silverlight, drugi natomiast odpowiada aplikacji internetowej, która posłuży nam do testowania komponentu. Co wchodzi w skład poszczególnych projektów:

Solution Explorer

  1. Test1
    Jest to projekt naszego komponentu Silverlight. Predefiniowane mamy tutaj dwa pliki *.xaml wraz z plikami codebehind.
  2. Test1.Web
    Projekt ten ma za zadanie uruchomić nasz komponent. W ramach tego projektu znajduje się katalog ClientBin, do którego będzie kopiowany plik wyjściowy projekt Test1 po jego kompilacji (z rozszerzeniem *.xap). Plik ten będzie następnie uruchamiany w kontekście jeden ze stron Test1TestPage.*. Domyślnie mamy tutaj do dyspozycji strony *.html oraz *.aspx.

 

 

 

 

Po zbudowaniu (kombinacja Ctrl + F5) zostanie nam zaprezentowana strona *.aspx z tego projektu, gdyż właśnie ten projekt ustawiony jest domyślnie jako projekt startowy. Gdybyśmy zdecydowali się na stworzenie rozwiązania składającego się tylko z projektu Silverlight w efekcie otrzymalibyśmy plik *.xap, który następnie musimy sami wbudować w stronę internetową.

Kolejnym krokiem będzie nawiązanie połączenie z Dynamics CRM …