Błąd „Object reference not set to an instance of an object”

Błąd „Object reference not set to an instance of an object” może pojawiać się w wielu kontekstach w przypadku pisanych przez nas plug-in’ów. Wtedy jednak możemy sami poprawić napisany przez siebie kod. Niestety… błąd ten pojawia się również w plug-in’ie napisanym przez Microsoft, który jest częścią normalnego „execution flow” w szczególnych przypadkach.
Jeśli podczas zapisywania rekordu macie błąd „Object reference not set to an instance of an object„, a w pliku śledzenia (trace) znajdziecie następujące fragmenty:

AssemblyName: Microsoft.Crm.ObjectModel.MultiCurrencyPlugin, Microsoft.Crm.ObjectModel
i
Microsoft.Crm.Sdk.InvalidPluginExecutionException: Object reference not set to an instance of an object.

…to padliście ofiarą nienaprawionego do tej pory przez Microsoft błędu. Błąd ten pojawia się, kiedy utworzycie jakiekolwiek pole typu money na dowolnym obiekcie. CRM automatycznie dodaje wtedy atrybut systemowy exchangerate i od tej pory dołącza do obiektu plugin przeliczający wartość z pola walutowego do waluty bazowej.
Problem zaczyna się, kiedy usunięte zostanie pole walutowe i w obiekcie nie ma już pól typu money. CRM zapomina bowiem… odrejestrować plug-in’a i nie usuwa atrybutu exchangerate, a nadal próbuje liczyć wartość w walucie bazowej, oczekując wartości z chociaż jednego pola walutowego. I… NullPointerException gotowy :) .

Rozwiązanie:
W obiekcie, na którym pojawia się ten błąd, dodajcie jakiekolwiek pole typu money. Pole nie musi być widoczne na formatce, ważne, żeby było atrybutem tego obiektu.

Problem z Blank.aspx i Dynamics CRM 4.0

Wiele osób ma ostatnio problem z dziwnym zachowaniem CRM’a, mianowicie próbą „zachowania” pliku Blank.aspx. Gdzieś na blogach ignoranci zaczęli nawet szerzyć bzdurę, że to błąd Dynamics CRM 4.0 powoduje takie zachowanie. Wszystko wygląda tak:

Dynamics CRM 4.0 Blank.aspx

PRZYCZYNA PROBLEMU:
Takie zachowanie spowodowane jest faktem, że Internet Explorer utracił znaczenie powiązania z plikami typu aspx lub inaczej – Internet Explorer nie wie, co zrobić z plikiem takiego typu. Dlaczego? Wszystkiemu winna jest poprawka do IE, którą większość użytkowników zainstalowało z Windows Update (KB953838 dostępna tutaj).

ROZWIĄZANIE PROBLEMU:
Najprostsze rozwiązanie to przywrócić IE wiedzę jak interpretować pliki aspx :) . W tym celu w okienku, które się pojawia („Czy chcesz zapisać plik Blank.aspx?”) wybieramy „OK” i zapisujemy w jakimś łatwo dostępnym miejscu. Później otwieramy plik prawym guzikiem i wybieramy „Otwórz za pomocą…”. W okienku, które się pojawi wybieramy Internet Explorer i zaznaczamy, żeby IE zawsze otwierał pliki aspx:

Dynamics CRM 4.0 Blank.aspx - Otworz

Problem rozwiązany.

Błąd „Precision must be an integer within the allowed range: 0 for integers, 0 to 4 for money, 0 to 10 for decimal, and 0 to 5 for float fields”

Ostatnio na forum CRM pojawiło się pytanie co w Dynamics CRM znaczy błąd „Precision must be an integer within the allowed range: 0 for integers, 0 to 4 for money, 0 to 10 for decimal, and 0 to 5 for float fields” podczas oglądania w CRM szans sprzedaży, ofert lub produktów na szansach sprzedaży i ofertach. Jeśli też trafiłaś/eś na taki błąd i nigdzie nie możesz znaleźć o co chodzi (google wiele na ten temat nie mówi poza linkami do pytań pozostawionych bez odpowiedzi…), odpowiedź znajdziesz poniżej. A Maciek dostał odpowiedż już wcześniej tutaj: http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/8e02cea2-bef8-45d8-b67a-6cb360ad8f2c :) .

Otóż, ten błąd nie wynika wcale z tego, że któreś pole ma źle ustawioną precyzję. Wynika raczej z faktu, że produkt, który został dodany do oferty lub szansy sprzedaży nie jest obecny w cenniku wykorzystanym przez tę szansę sprzedaży/ofertę. Rozwiązaniem jest dodanie produktu do cennika, który jest użyty w danej szansie lub ofercie. I już. Tyle :)

Strony ASP.NET rozszerzające CRM i ViewState

To, że Microsoft Dynamics CRM 4.0 jest platformą „super-rozszerzalną” wie każdy :) . Do popularnych sposobów rozszerzania należą nasze własne strony ASP.NET wyświetlane np. w pływających ramkach (iframes). Dobre praktyki nakazują umieszczanie naszych stron w folderze ISV w katalogu, do którego zainstalowane zostały pliki ze stronami używane przez Dynamics CRM (katalog CRMWeb lub dowolny wybrany przez nas podczas instalacji). Dzięki umieszczeniu stron w folderze ISV mamy dostęp do kilku ciekawych informacji przekazywanych naszym stronom przez CRM. Niestety, jest też jedna rzecz, o której warto pamiętać: fakt, że nasze strony są w podfolderze używanym przez CRM powoduje m.in., że domyślnie na nasze strony narzucane są ustawienia z web.config CRM’a. Pośród wielu ustawień jest m.in. taka linijka:

<pages buffer=”true” enableSessionState=”false” enableViewState=”false” validateRequest=”false”/>

 

Łatwo zauważyć, że przez tą linijkę nasze strony domyślnie mają wyłączony ViewState (!). Nie jest to sytuacja, której się spodziewamy… Szczególnie może zdziwić Was sytuacja, kiedy tworzycie strony i zaawansowany kod na innym środowisku. Wszystko działa, a po umieszczeniu na serwerze CRM nagle kontrolki gubią „pamięć”, co chwila dostajecie „null reference” itd. Warto wtedy sprawdzić, czy pozwalacie Waszej stronie na zarządzanie stanem (ViewState). Jeśli nie, koniecznie ustawcie to explicite. W tym celu, w kodzie strony .aspx, do pierwszej linijki, należy dodać dyrektywę EnableViewState=”true”, jak w poniższym przykładzie:

<%@ Page Language=”C#” (…) EnableViewState=”true” %>

Jeśli chcecie szyfrować zawartość ViewState, możecie dodać też EnableViewStateMac=”true”.

Miłego kodowania i mniej nerwów, jak po postback’u macie puste listy! :)

Błąd: „Method not found: Single Microsoft.Crm.Sdk.CrmFloat.get_Value()”

Ostatnio potrzebowałem użyć bardzo fajnego narzędzia dostępnego na CodePlex’ie, tzn. CRM 4.0 Bulk Data Export Tool (aplikacja wraz z kodem dostępna jest tu: http://www.codeplex.com/mscrmbulkdataexport, a jej krótki opis w tym poście: ). Niestety każda próba exportu danych kończy się błędem „Method not found: Single Microsoft.Crm.Sdk.CrmFloat.get_Value()”. Zainteresowałem się trochę bardziej tym błędem. W skrócie mówi on o tym, że nie znalazł metody get_Value() w klasie CrmFloat. W reflektorze widać jednak, że ta metoda jest obecna. O co więc chodzi?

Ano, o dość prostą rzecz… Sygnatura metody pokazuje, że metoda zwraca typ „Single”. A to nieprawda od niedawna :) . Bo CrmFloat zwraca w CRM 4.0 typ „Double”. I tyle :) . Dlatego błąd twierdzi, że nie ma metody get_Value(), która zwraca rezultat typu Single. I ma rację! Bo zwraca Double :).

Jak więc poradzić sobie z tym błędem w CRM 4.0 Bulk Data Export Tool’u? Wystarczy, że podmienimy programikowi używaną bibliotekę Microsoft.Crm.Sdk.dll na jej najnowszą wersję i przekompilujemy aplikację. Poniżej kroki, jak tego dokonać:

1. Ściągamy źródła CRM 4.0 Bulk Data Export Tool stąd: http://www.codeplex.com/mscrmbulkdataexport/Release/ProjectReleases.aspx?ReleaseId=12682

2. Ściągamy najnowsze CRM 4.0 SDK stąd: http://www.microsoft.com/downloads/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&displaylang=en

2. Otwieramy projekt „CrmDataExport.sln” w Visual Studio.

3. Z referencji „wyrzucamy” Microsoft.Crm.Sdk i Microsoft.Crm.Sdk.TypeProxy:

4. Dodajemy referencje do najnowszych wersji tych bibliotek. W tym celu klikamy „Add reference” i w okienku w zakładce „Browse” idziemy do folderu z SDK. Z katalogu bin, wybieramy te dwie potrzebne biblioteki: 

5. Kompilujemy projekt (w menu „Build” -> „Build solution”

6. Uruchamiamy programik i wszystko działa! :) Można eksportować dowolne rekordy z naszego CRM’a.

Twój workflow czeka na zasoby? Konfiguracja klienta Outlook się nie udaje?

Jeśli podczas uruchamiania przepływów pracy, żaden z nich nie startuje z uruchomieniem logiki i jest w stanie „Oczekiwanie na zasoby” („Waiting for resources”), jest duże prawdopodobieństwo, że konfiguracja serwera zawarta w tabeli DeploymentProperties na Twoim serwerze Dynamics CRM jest nieprawidłowa.

Podobnie, jeśli klient Outlook dla Dynamics CRM 4.0 podczas konfiguracji wyświetla komunikat „The configuration wizard cannot connect to the Microsoft CRM server. This might indicate that the server is down.” . Wtedy też jest duża szansa, że poniższe zmiany pomogą.

Aby naprawić te błędy i zmienić konfigurację serwera, wykonać należy poniższe kroki:

1. Na serwerze z bazami danych Dynamics CRM otwieramy SQL Server Management Studio i przechodzimy do bazy MSCRM_Config

2. Żeby sprawdzić aktualną konfigurację serwera, możemy użyć zapytania:

SELECT NVarCharColumn
FROM DeploymentProperties
WHERE ColumnName IN ('ADWebApplicationRootDomain',
'AsyncSdkRootDomain', 'ADSdkRootDomain');

3. Prawdopodobnie wartości w tych trzech kolumnach nie są prawidłowymi adresami serwera CRM, nie mają prawidłowego portu lub nie są pełna, kwalifikowaną nazwą (FQDN).

4. Robimy update na tabeli DeploymentProperties, używając poniższych instrukcji. Zamiast <nazwa_serwera> używamy pełnej nazwy serwera CRM wraz z numerem portu, za pomocą której dostajemy się do aplikacji poprzez Internet Explorer:

UPDATE dbo.DeploymentProperties SET NVarCharColumn = '<nazwa_serwera>'
WHERE ColumnName IN ('ADWebApplicationRootDomain',
'AsyncSdkRootDomain', 'ADSdkRootDomain');

Jeśli łączymy się z CRM bez SSL, zmieniamy również:

UPDATE dbo.DeploymentProperties SET NVarCharColumn = 'HTTP'
WHERE ColumnName = 'ADRootDomainScheme';

Zmiany te pomagają w przypadkach, kiedy:
- po instalacji Dynamics CRM został zmieniony numer portu, na którym jest aplikacja
- po instalacji został dodany host header
- z jakiś przyczyn klient dla Outlook musi łączyć się po nazwach FQDN zamiast po krótkiej nazwie (np. poprzez VPN)

Dodatkowo zmiany te naprawiają sytuacje, w których występują błędy:
- w przepływie pracy „Oczekiwanie na zasoby”
- w menadżerze konfiguracji klienta Outlook „Nie można połączyć się z serwerem Dynamics CRM”

Będę na MTS 2008…

Tak się składa, że zostałem zaproszony na MTS 2008 (więcej tu: http://www.mts2008.pl) w roli eksperta Dynamics CRM. Razem z moim kolegą Tadkiem Kamińskim będziemy służyli pomocą w strefie Ask-The-Expert w dziale poświęconym Dynamics CRM. Dlatego zapraszam wszystkich do odwiedzenia nas na MTS! :) . Przychodźcie z problemami, z pytaniami, z cukierkami ;)

Tworzenie Mapowania danych i ładowanie przykładowych danych – niedociągnięcia

Tworzenie mapowań danych to bardzo przydatna funkcja w Dynamics CRM 4.0. Raz utworzone mapy mogą być używane do importu danych wielokrotnie. Dodatkowo, mapy pozwalają mapować nie tylko atrybuty podstawowych typów, ale również listy wartości.
Ten post jednak nie będzie zachwalał mechanizmu mapowań (który i tak ma dużo mniejsze możliwości od Menadżera migracji danychData Migration Manager’a), ale miał być poświęcony jednej bardzo uciążliwej rzeczy potrzebnej do utworzenia mapy…

Załóżmy, że mamy plik CSV rozdzielony średnikami (ważne do zapamiętania na później :) ). Bez żadnego problemu możemy go oczywiście zaimportować, używając standardowego mechanizmu importu. Problem (ciekawostka) pojawia się, kiedy chcemy sobie utworzyć nowe mapowanie danych dla konkretnego pliku.
Idąc standardowymi krokami, wybieramy z menu „Narzędzia” -> „Importuj dane”. W kreatorze importu wybieramy plik z danymi źródłowymi. Ten plik może być w jednym z czterech formatów:


W kolejnym kroku możemy wybrać typ rekordu docelowego i istniejące mapowanie. Jeśli nie mamy odpowiedniego mapowania, możemy zdecydować się na utworzenie nowego:


Ciekawie robi się, kiedy w okienku nowego mapowania przejdziemy do atrybutów i klikniemy guzik „Załaduj przykładowe dane”:


Kiedy załadujemy nasz plik źródłowy, który jest rozdzielany średnikami, zdziwimy się, że wszystkie kolumny są zmapowane do jednej:

Dlaczego tak się dzieje? Ano dlatego, że funkcja ładująca przykładowe dane zawsze oczekuje danych rozdzielonych przecinkami! Moim zdaniem jest to niedociągnięcie, bo i w tym miejscu mogliśmy mieć wybór rodzaju „znaku rozdzielającego” podobnie jak przy imporcie, który wcześniej rozpoczęliśmy.

Druga dziwna rzecz z ładowaniem przykładowych danych podczas tworzenia mapowania to fakt, że musimy ręcznie ograniczyć wielkość pliku, który chcemy użyć jako przykład. CRM zamiast załadować tylko nagłówki kolumn i np. pierwszy wiersz, próbuje zawsze ładować cały plik, co często kończy się błędem.

Pamiętajcie więc, że ładowanie przykładowych danych potrzebuje małego pliku rozdzielonego przecinkami niezależnie od tego, że import możemy zrobić swobodnie z pliku, w którym dane rozdzielone są np. tabulatorem…