Bir plug-in için Microsoft Dynamics CRM’de opsiyonel olarak kullanabileceğiniz
yapici metod(constructor) türleri mevcuttur. Hic parametre vermeden yapici
metod cagirabileceginiz gibi bir ya da iki parametre vererek de
cagirabilirsiniz.
SamplePlugin isimli plug-in için 3 cesit yapici metod ornegi
asagidaki gibidir.
public SamplePlugin()
public SamplePlugin(string unsecure)
public SamplePlugin(string unsecure,
string secure)
Yapici metodun ilk parametresi public yani unsecure bilgi yigini içermelidir.
Ikinci parametre ise non-public (secure) bilgi yigini içermelidir. Buradan da
anlayabileceğiniz uzere secure string encrypted yani sifrelenmis veri unsecure
ise unencrypted yani sifrelenmemis değer içermelidir. Office Outlook client da
calisan bir plug-in yazdiysaniz bilmelisiniz ki secure string offline yani
cevrimdisi modda calismayacaktir.
Bu bilgileri bir plug-in’e Plugin Registration Tool
vasitasiyla bir step’in kaydi sirasinda sisteme iletiyoruz. Bu mesajlar için ayrilmis
2 alan bulanmaktadır.

Step içerisinde bu ayarlamalari yaptıktan sonra yazmis olduğumuz
degerlere kod içerisinden asagidaki gibi ulaşabilirsiniz.
private readonly string _unsecureString;
private readonly string _secureString;
public AdvancedPlugin(string unsecureString, string secureString)
{
if (String.IsNullOrWhiteSpace(unsecureString) ||
String.IsNullOrWhiteSpace(secureString))
{
throw new InvalidOperationException
("Unsecure
and secure strings are required
by the Advanced Plug-in, but not
provided.");
}
_unsecureString = unsecureString;
_secureString = secureString;
}
Eger sizde benim gibi Dynamics CRM kurulumunuz ile ADFS 3.0'i ayni server uzerinde kullaniyorsaniz Outlook Client Configuration Wizard ile yapilandirma sirasinda authentication probleminden dolayi bir hata alabilirsiniz.
Log dosyasini incelediginizde asagidaki gib bir hata mesaji olacaktir.
"Error connecting to URL: https://org.contoso.com/XRMServices/2011/Discovery.svc Exception: Microsoft.Crm.CrmException: Authentication failed"
Bu hata ile ilgili nette buldugun bircok cozeum yolunu denesem de sonuc vermedi. Bende Fiddler ile arka tarafatki iletisimde neler oldugunu izlemeye karar verdim. Fiddler ile gordum ki Configuration Wizard'in gitmeye calistigi bir adreste 503 hatasi almaktayim, Adres ise su formattaydi:
"https://adfs.contoso.com/adfs/services/trust/mex"
Evet sorun ADFS'deydi. CRM web arabiriminde sorunsuzca gorevini yerine getiren ADFS Outlook Client'da ise hataya neden olmaktaydi. Bunun uzerine hemen ADFS Servera gittim ve arastirmalara basladim.
ADFS Serverda Event Viewer'da sorunun kaynagini yakaladim:
Event ID: 102
Description:
There was an error in enabling endpoints of Federation Service. Fix configuration errors using PowerShell cmdlets and restart the Federation Service.
Additional Data
Exception details:
System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:808. This could happen if there is another application already listening on this endpoint or if you have multiple service endpoints in your service host with the same IP endpoint but with incompatible binding configurations. ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
Yani ADFS Server 808 nolu bir portu kullanmaktaydi. 808 Portu ayni zamanda Asynchronous Service tarafinda da kullanilmakta.
Protocol | Port | Description | Explanation |
---|
TCP | 808 | CRM server role communication | The Asynchronous Service and Web Application Server services communicate to the Sandbox Processing Service through this channel. The default port is 808, but can be changed in the Windows registry by adding the DWORD registry value TcpPort in the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\. |
Yeri gelmisken bahsedeyim CRM tarafindan kullanilan diger portalarin listesi de soyle:
Protocol | Port | Description | Explanation |
---|
TCP | 80 | HTTP | Default web application port. This port may be different as it can be changed during Microsoft Dynamics CRM Server Setup. For new websites, the default port number is 5555. |
TCP | 135 | MSRPC | RPC endpoint resolution. |
TCP | 139 | NETBIOS-SSN | NETBIOS session service. |
TCP | 443 | HTTPS | Default secure HTTP port. The port number may differ from the default port. This secure network transport must be manually configured. Although this port is not required to run Microsoft Dynamics CRM, we strongly recommend it. For information about how to configure HTTPS for CRM, see “Make Microsoft Dynamics CRM client-to-server network communications more secure” in Post-installation and configuration guidelines for Microsoft Dynamics CRM in the Installing Guide. |
TCP | 445 | Microsoft-DS | Active Directory service required for Active Directory access and authentication. |
UDP | 123 | NTP | Network Time Protocol. |
UDP | 137 | NETBIOS-NS | NETBIOS name service. |
UDP | 138 | NETBIOS-dgm | NETBIOS datagram service. |
UDP | 445 | Microsoft-DS | Active Directory service required for Active Directory access and authentication. |
UDP | 1025 | Blackjack | DCOM, used as an RPC listener. |
Listenin tamamina bu adresten ulasabilirsiniz.
https://technet.microsoft.com/en-us/library/hh699823.aspx
Sorunumuza geri donersek 808 nolu portu degistirmem gerekiyordu. Iste asagidaki komut da tam bu ise yariyor:
Set-ADFSProperties –nettcpport 809
ADFS portunu 809 olarak degistirdim ve servisi yeniden baslattim.
Configuration Wizard'a geri dondum ve tekrar denedim sorun cozulmustu. Zaten Fiddler'da da ilgili bolumu sorunsuzca gectigini gordum.
Umarim sizlere de faydali olur.
*************************
21/05/2015 tarihinde ek:
Yukaridaki durum update rollup 0.1 yukledikten sonra yine devam etti. Konuyu arastirinca bu sefer de 49443 portunda ayni sorunun oldugunu gordum. Konuyu inceleyince bu portu da ADFS TlsClientPort oldugunu ogrendim.
Bu portu da yukaridaki konutla baska bir porta yonlendirdim.
Set-ADFSProperties -tlsclientport 42223
firewall ve diger ayarlari yaptiktan sonra ADFS Servisi yeniden baslattim ve hersey yoluna girdi.
Dynamics CRM 2013 ile neler yapabilecegimizi, yeni versiyonun sp1'den sonra gelen yeteneklerini bu seminerde inceliyoruz.
Etkinlige asagidaki linkten kayit olabilir gelismleri takip edebilirsiniz.
Dynamic Entity'ler ile ilgili birinci makalemiz veri sorgulama idi. İkinci
makalede ise veri yazma yöntemlerini göreceğiz. Burada dynamic entity'i
anlatmadan önce core entity yöntemiyle veri yazmaya değineceğim. Böylece aradaki
farkları görmemiz daha kolay olacaktır.
Konuyu hatırarsak; bir web servisini add web reference diyerek projenize dahil ettiğinizde visual
studio arka tarafta bir bir class mimarisi oluşturur ve siz o mimariyi
kullanırsınız. Eğer core enitity kullanırsanız, bu class özelleştirme nedeniyle
her firmada farklı bir hal alabilir ve kodu yeniden derlemize neden olur. İşte
bundan kurtularak çalışma zamanında nesneler yaratıp bunlara değer atamayı
göreceğiz.
Hatırlarsanız bir örnek uygulamamız vardı. Senaryo şöyle idi; bir web sitemiz olacak ve bu web sitemize insanlar
ad,soyad,e-mail,ilçe ve il bilgilerini yazarak kayıt olacaklar. Fakat biz forma
girilen e-mail'i kullanarak veritabanımızda bu kişinin kayıtlı olup olmadığını
kontrol edeceğiz eğer yoksa müşteri adayı (lead) olarak bu kişiyi Microsoft
Dynamics CRM'e
kaydedeceğiz.
Kaydet düğmesinin arkasında aşağıdaki kod yer almakta.
Mail adresinin yazılıp yazılmadığına bakıyoruz. Eğer yazıldı ise
dynamicRetrieve metodu ile bu mailinde
birilerinin sistemde olup olmadığına bakıyoruz.

///
<summary>
///
Kaydet Dugmesi Click Olayi
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected
void btnSave_Click(object
sender, EventArgs e)
{
if (txtMail.Text
!= "")
{
if (!dynamicRetrieve(txtMail.Text))
{
if (coreCreate())
lblMessage.Text =
"başarıyla oluşturuldu";
if (dynamicCreate())
lblMessage.Text =
"başarıyla oluşturuldu";
}
}
}
Birinci makalede e-mail adresinden kontrol etmeyi gördük. Kontrol
sonucunda e-mail adresinin sistemde bulunmadığını ve oluşturmamız gerektiğini
düşünelim.
1.Core Entity
Burada önemli 3 adım bulunmakta.
1. web servisteki lead sınıfını çağırıyoruz
lead myLead =
new
lead();
2. class içerisindeki proprty'e ilgili değeri atıyoruz
myLead.firstname = txtName.Text.ToString();
3. içersisini veri ile doldurduğumuz class'ı servise oluşturması için
veriyoruz.
MyService.Create(myLead);
///
<summary>
///
coreCreate metdodu Core Entity kavramiyla lead olusturmayi bize gosterecek
///
</summary>
private
bool coreCreate()
{
try
{
// CRM Servis'ini cagiriyoruz
CrmService
MyService = service();
//lead sınıfımız aryoruz ve
üretiyoruz.
lead myLead =
new
lead();
//textbox'ın değer içerip içermediğine
bakıyoruz.
if (txtName.Text
!= string.Empty)
//eğer değer içeriyor ise class
içerisindeki ilgili attribute a değerini veriyoruz.
myLead.firstname = txtName.Text.ToString();
if
(txtSurname.Text != string.Empty)
myLead.lastname = txtSurname.Text.ToString();
if (txtMail.Text
!= string.Empty)
myLead.emailaddress1 = txtMail.Text.ToString();
if (txtState.Text
!= string.Empty)
myLead.address1_stateorprovince = txtState.Text.ToString();
if (txtCity.Text
!= string.Empty)
myLead.address1_city = txtCity.Text.ToString();
//Son olarak da değer atamalarımız bitince
servisin Create metodu ile
//lead imizi oluşturuyoruz.
MyService.Create(myLead);
return
true;
}
catch (Exception
ex)
{
HandleException(ex);
return
false;
}
}
2. Dynamic Entity
Eğer bu oluşturma işlemini dynamic entity özelliğini kullanarak yapmış
olsaydık kod bu sefer aşağıdaki gibi olacaktı.
Ama önce ne yaptığımızı anlatalım;
1. CRM Servis'ini cagiriyoruz. Burada service(); benim
yazdığım bir metod ve crm servisini oluşturuyor.
CrmService
MyService = service();
2. DynamicEntity nesnesini yaratyoruz
DynamicEntity
leadEntity = new
DynamicEntity();
3. Entity ismini veriyoruz.
leadEntity.Name = EntityName.lead.ToString();
4. Eger deger iceriyorsa; Property
nesnemizi cagiriyoruz ve adın ve degeri veriyoruz. Boylece
calisma aninda bir class'in icerisindeki bir nesneye deger
vermis oluyoruz.
StringProperty
firstname = new
StringProperty();
firstname.Name = "firstname";
firstname.Value = txtName.Text;
Tabii burada yeri gelmişken söz etmekte fayda var CRM sadece string türünde bir
değişken biçimi ile çalışmıyor. Yukarıdaki örnek "StringProperty" classından bir
değişken türeterek string oluşturmaya yarıyor. Diğer değişken türleri (sınıflar)
ise aşağıdaki listede yer almakta;
Sınıf Adı |
Microsoft Dynamics CRM Attribute Türü |
CrmBooleanProperty |
CrmBoolean |
CrmDateTimeProperty |
CrmDateTime |
CrmDecimalProperty |
CrmDecimal |
CrmFloatProperty |
CrmFloat |
CrmMoneyProperty |
CrmMoney |
CrmNumberProperty |
CrmNumber |
CustomerProperty |
Customer |
DynamicEntity |
N/A |
DynamicEntityArrayProperty |
N/A |
EntityNameReferenceProperty |
EntityNameReference |
KeyProperty |
Key |
LookupProperty |
Lookup |
OwnerProperty |
Owner |
PicklistProperty |
Picklist |
Property |
N/A |
StateProperty |
State |
StatusProperty |
Status |
StringProperty |
String |
UniqueIdentifierProperty |
UniqueIdentifier |
N/A |
Internal
Memo
Virtual
|
///
<summary>
///
dynamicCreate metdodu Dynamic Entity kavramiyla lead olusturmayi bize gosterecek
///
</summary>
private
bool dynamicCreate()
{
try
{
// CRM Servis'ini cagiriyoruz
CrmService
MyService = service();
// DynamicEntity nesnesini yaratyoruz
DynamicEntity
leadEntity = new
DynamicEntity();
// Entity ismini veriyoruz.
leadEntity.Name = EntityName.lead.ToString();
// Property'ler icin bir Array
olusturuyoruz.
ArrayList
arrProps = new
ArrayList();
// Textbox deger iceriyor mu diye
kontrol ediyoruz.
if (txtName.Text
!= string.Empty)
{
// Eger deger iceriyorsa; Property
nesnemizi cagiriyoruz ve
// adn ve degeri veriyoruz. Boylece
calisma aninda bir class'in
// icerisindeki bir nesneye deger
vermis oluyoruz.
StringProperty
firstname = new
StringProperty();
firstname.Name = "firstname";
firstname.Value = txtName.Text;
arrProps.Add(firstname);
}
if
(txtSurname.Text != string.Empty)
{
StringProperty
lastname = new
StringProperty();
lastname.Name = "lastname";
lastname.Value = txtSurname.Text;
arrProps.Add(lastname);
}
if (txtMail.Text
!= string.Empty)
{
StringProperty
mail = new
StringProperty();
mail.Name = "emailaddress1";
mail.Value = txtMail.Text;
arrProps.Add(mail);
}
if (txtState.Text
!= string.Empty)
{
StringProperty
state = new
StringProperty();
state.Name = "address1_stateorprovince";
state.Value = txtState.Text;
arrProps.Add(state);
}
if (txtCity.Text
!= string.Empty)
{
StringProperty
city = new
StringProperty();
city.Name = "address1_city";
city.Value = txtCity.Text;
arrProps.Add(city);
}
// Property'leri bir DynamicEntity'e
teslim ediyoruz.
leadEntity.Properties = (Property[])arrProps.ToArray(typeof(Property));
// Ve final entity'imizi olusturmasi
icin servise veriyoruz.
MyService.Create(leadEntity);
return
true;
}
catch (Exception
ex)
{
HandleException(ex);
return
false;
}
}
Uygulamamızı çalıştırdığımızda aşağıdaki ekran görüntüsünü elde edeceğiz.

Bir makale daha burada biter. Hepiniz hoşçakalın.
Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net