Dynamics CRM üzerinde web servisleri ile çalışırken bir değişkene null
değerini atamanız gerekebilir. Ama CRM içerinde attribute'lar kendine has
olduğundan attribute'a değil onun IsNull ve IsNullSpecified değerlerine
true vermeniz gerekmektedir. Servis bunu arka tarafta veritabanına yazarken o
attribute için null vermesi gerektiğini böyle anlamaktadır. Bunu sql ile ifade
etmeye kalkarsak;
" update xxx set yyy = null "
demenin yolu CRM'de aşağıda örnekleri verilen şekilde olmalıdır.
( String türü için durum biraz farklı, String.Empty değerini vermeniz gerekmekte.
)
Aşağıdaki kod örneği size tüm attribute'lar için nasıl null değer
atanacağını gösterecektir.
CrmDecimal dec =
new CrmDecimal();
dec.IsNull = true;
dec.IsNullSpecified = true;
PickList list = new
PickList();
list.IsNull = true;
list.IsNullSpecified = true;
CrmFloat f =
new
CrmFloat();
f.IsNull = true;
f.IsNullSpecified = true;
CrmMoney money =
new
CrmMoney();
money.IsNull = true;
money.IsNullSpecified = true;
CrmBoolean
boolean = new
CrmBoolean();
boolean.IsNull = true;
boolean.IsNullSpecified = true;
Owner owner =
new
Owner();
owner.IsNull = true;
owner.IsNullSpecified = true;
CrmNumber number
= new
CrmNumber();
number.IsNull = true;
number.IsNullSpecified = true;
Lookup lookup =
new
Lookup();
lookup.IsNull = true;
lookup.IsNullSpecified = true;
Status status =
new
Status();
status.IsNull = true;
status.IsNullSpecified = true;
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
Microsoft Dynamics CRM için program yazarken bilinmesi gereken en
temel şey CRM'in her entity(tablo) üzerinde bulunan ve kullanılmakta olan bir
attribute(özellik) sınıf mimarisine sahip olduğudur. CRM mimarisini kullanarak
program yazmak istediğinizde bunları mutlaka kullanmanız gerekmektedir. Çoğu
kişi kullanım konusunda ilk anda hataya düşmektedir. Nedeni ise standart olarak
şöyle bir tanımlama yapmaya çalışmalarıdır;
CrmNumber number = 5;
Fakat bu yanlış
bir tanımlama biçimidir. Doğru olan ise;
CrmNumber number = new CrmNumber();
number.Value = 5;
Yani sınıf
türetildikten sonra ".Value" kullanılarak değer ataması yapılmalıdır.
Bu
noktada çok sık yapılan başka bir yanlışlığa değinmek istiyorum. CRM üzerinde
bir veriyi güncellerken doğal güncellemek istediğiniz kaydın ID'sini yani
Guid'ini vermeniz gerekmektedir. Sanıyorum sql ile anlatmak daha anlaşılır
olacaktır.
update .. set .. xxx =
'{7649FD8B-D4D2-DB11-90C4-000423CA2056}'
tarzında bir güncelleme
cümlesini servis ile ifade ederken "Key" attribute'unu kullanmamız
gerekmektedir.
lead _lead =
new lead();
......
arada istediğimiz attribute'a yeni
değerini atıyoruz.
......
_lead.leadid = new
Key();
_lead.leadid.Value = new Guid("{7649FD8B-D4D2-DB11-90C4-000423CA2056}");
.....
Artık
Update hangi kayıdı update edeceğini biliyor.
.....
MyService.Update(_lead);
Aşağıdaki tabloda bu sınıfların isimleri verilmiştir.
Sınıf Adı |
Tanım |
CrmBoolean |
boolean. |
CrmDateTime |
date/time. |
CrmDecimal |
decimal. |
CrmFloat |
float. |
CrmMoney |
money. |
CrmNumber |
number ya da integer. |
CrmReference |
Başka bir entity'i referans göstermek için kullanılır. Bu
özelliği kullandığınız zaman value ve type atamak zorundasınız. |
Customer |
customer class'ini refere eder. CrmReference classının
subclass'ıdır. |
EntityNameReference |
Entity ismi için kullanılır. |
Key |
primary key |
Lookup |
Başka bir entity'i referans gösterir. CrmReference classının
subclass'ıdır. |
Owner |
Sahip entitysini referans eder. CrmReference classının
subclass'ıdır. |
Picklist |
picklist |
Status |
status |
UniqueIdentifier |
GUID |
Aşağıdaki örnek
kod bu türlere nasıl değer atayacağınızı göstermektedir. Yanlarındaki değerler
öylesine verilmiştir.
CrmBoolean boolean = new CrmBoolean();
boolean.Value = true;
CrmDateTime dateTime = new CrmDateTime();
dateTime.Value = "20080129 00:00:00";
CrmDecimal dec = new CrmDecimal();
dec.Value = (decimal)5.5;
CrmFloat f = new CrmFloat();
f.Value = (float)5.5;
CrmMoney money = new CrmMoney();
money.Value = (decimal)5.00;
CrmNumber number = new CrmNumber();
number.Value = 5;
Lookup lookup = new Lookup();
lookup.Value = new Guid("{7649FD8B-D4D2-DB11-90C4-000423CA2056}");
lookup.type =
EntityName.account.ToString();
Owner owner = new Owner();
owner.type = EntityName.systemuser.ToString();
owner.Value =
user.UserId;
Picklist list = new
Picklist();
list.Value
= 2;
Status status
= new Status();
status.Value =
4;
EntityNameReference reference = new
EntityNameReference();
reference.Value = EntityName.account.ToString();
Key key = new Key();
key.Value = new Guid("{7649FD8B-D4D2-DB11-90C4-000423CA2056}");
Bir makale daha burada biter. Hepiniz hoşçakalın. Web stiemi ziyaret etmeyi
unutmayın :-)
Barış
KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net
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
Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -3 (FetchXML Kullanarak Veritabanına Erişim)
Önceki iki makalemde Microsoft CRM Web Servislerini ve Sql kullanarak veri sorgulama yöntemlerini örnekler vererek açıklamıştım. Son yöntemimiz ise FetcXML kullanarak CRM veri katmanına erişmek. Bu yöntem bir ad-hoc query yaratır ve bu query Microsoft CRM sistemi üzerindeki entityler üzerinde servisler vasıtasıyla icra edilir. Bu yöntemi QueryExpression (yani 1. makalede ele aldığım konu)'den farklı kılan taraf ise Fetch yönteminin bize Microsoft CRM BusinessEntity sinifindan bir XML döndürmesidir.
FetchXML'in ayrı bir sorgulama dili olduğu ve kendi yazım kuralları olduğu unutulmamalıdır.
Bu yöntemi kullanarak veri okuyabilme işlemi sırasında sorguyu çağıran kişinin sistem erişim hakları (access rights) üzerinde Read privilege yetkisi olması gerekmektedir.
Biçim
|
[Visual Basic]Public Function Fetch( ByVal fetchXml As String) As String
[C#]public string Fetch( string fetchXml);
[JScript]public function Fetch( fetchXml : String) : String;
|
Parametreler |
fetchXml : İcra edilecek Fetch query. |
Dönen Değer |
String türünde içerisinde sorgu sonucunu bulunduran XML döner. |
Sorgu İfadeleri |
Koşul
|
Koşul İfadesi |
Değer |
equals x |
eq |
x |
does not equal x |
ne |
x |
is greater than x |
gt |
x |
is greater than or equal to x |
ge |
x |
is less than x |
lt |
x |
is less than or equal to x |
le |
x |
begins with x |
like |
x% |
does not begin with x |
not-like |
x% |
ends with x |
like |
%x |
does not end with x |
not-like |
%x |
contains x |
like |
%x% |
does not contain x |
not-like |
%x% |
exists |
not-null |
|
does not exist |
null |
|
anytime |
not-null |
|
yesterday |
yesterday |
|
today |
today |
|
tomorrow |
tomorrow |
|
in next 7 days |
next-seven-days |
|
in last 7 days |
last-seven-days |
|
next week |
next-week |
|
last week |
last-week |
|
this week |
this-week |
|
this month |
this-month |
|
last month |
last-month |
|
next month |
next-month |
|
this year |
this-year |
|
next year |
next-year |
|
last year |
last-year |
|
on x |
on |
x |
on or after x |
on-or-after |
x |
on or before x |
on-or-before |
x |
in between |
between |
|
not between |
not-between |
|
in |
in |
|
not in |
not-in |
|
equals user id |
eq-userid |
|
does not equal user id |
ne-userid |
|
equals business id |
eq-businessid |
|
does not equal business id |
ne-businessid |
|
|
Örnek Uygulama :
Yukarıdaki tabloda sorgu ifadeleri kısmında "Koşul İfadesi" kısmında yazan değerler bizim normal sql cümlesinde kullandığımız ifadelere benzemektedir. Tek fark "=","<",">" gibi ifadelerin yerlerine "eq","gt","lt" gibi text bazlı ifadelerin gelmiş olmasıdır. Aşağıdaki örnek kodda ben sql'den bildiğimiz "like" operatörünü kullanacağım.
Herzaman olduğu gibi şimdi de kod üzerinde açıklama yönetimi tercih ediyorum ki kodu uygulamalarınıza kopyalayıp yapıştırdığınızda açıklamalar da beraberinde kodun içinde olsun diye. Unutulmamalıdır ki buradaki uygulamayı çalıştırabilmeniz için Veri Sorgulama Yöntemleri-1 isimli makalemde yer alan CRM Web Servisinin eklenmesi adımının yapılmış olması gerekmektedir.
private void btnQueryWithFetchXML_Click(object sender, EventArgs e)
{
try
{
// CRM Servis'ini cagiriyoruz
CrmService service = new CrmService();
// servise network'te kim oldugumuzu soyluyoruz. (Eger CRM Server'i ile ayni domainde degilseniz
// bunu yapmak zorundasiniz yoksa "The request failed with HTTP status 401: Unauthorized." hatasini alirsiniz)
System.Net.NetworkCredential MyCredential = new System.Net.NetworkCredential();
MyCredential.UserName = ""; // Domain Kullanici Adi
MyCredential.Password = ""; //Domain Kullanicisinin Sifresi
MyCredential.Domain = ""; //Domain Adi
service.Credentials = MyCredential;
// Eger crm server ile ayni domainde iseniz ve sizin crm'de bir rolunuz varsa asagida parantezler icerisinde
// belirttigim komutu yukaridaki 5 satir yerine kullanabilirsiniz
// ( service.Credentials = System.Net.CredentialCache.DefaultCredentials; )
// Geri donecek butun Contact'lardan Contactid ve FullName degerlerini istiyoruz
// Sehir ismi "Istanbul" olanlar cagiriyoruz.
string fetch = "<fetch mapping='logical'>"+
"<entity name='contact'>"+
"<attribute name='contactid'/>"+
"<attribute name='fullname'/>"+
"<filter type='and'>"+
"<condition attribute='address1_city' operator='like' value='İstanbul'/>"+
"</filter>"+
"</entity>"+
"</fetch>";
// Service'e gonderiyoruz
string result = service.Fetch(fetch);
MessageBox.Show(result);
// Gelen result'u XML objeleri ile parse edebiliriz.
}
// Soap yani Web Servisi hatalarini yakalamak icin ilgili Exception sinifimiz ekliyoruz.
catch (System.Web.Services.Protocols.SoapException ex)
{
MessageBox.Show(ex.Message + " " + ex.Detail.InnerText);
}
// Soap disindaki Standart hatalari yakalamak icin Exception'i da kodumuza ekliyoruz.
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Microsoft CRM 3.0'dan veri sorgulama yöntemleri isimli makalemizin sonuna ulaştık. Umarım bu konuları detaylı açıklayabilmişimdir. Bana her türlü sorunda mail adresimden ulaşabilirsiniz. Yeni bir makalede görüşmek üzere.
Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net
Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -2(Sql Kullanarak Veritabanına Erişim)
Bir önceki makalemde Microsoft CRM Web Servislerini kullanarak veri sorgulama yöntemine bir örnek vermiştim. Şimdi ise Microsoft CRM’in veritabanına bağlanarak veri sorgulayacağız. Tabii bu sorgulama işlemi biraz programlama bilen bir kişinin yapabileceği kadar basit ve standart bir işlem. Burada size bir sql cümlesiyle nasıl sorgulama yapılırın ötesinde CRM’in veritabanı yapısı hakkında bilgi vermenin daha faydalı olacağını düşünüyorum.
Microsoft CRM veritabanında bilmeniz gerekenler;
- Bizim üzerinde alan açmamıza izin verdiği bütün entitylerin(CRM tablo nesnesi) çift tablodan oluştuğudur.
- CRM standart kurulumunda bizim onun üzerine açtığımız bütün alanların ve tabloların başına “new_” ibaresini koyar.
- Veri sorgulamakta direkt tablolardan veri sorgulamak Microsoft tarafından yasaktır.
- Bu yüzden Microsoft programlarımızda ve raporlarımızda “FilteredView” ismi verilen güvenlik altyapısını içerisinde bulunduran viewları kullanmamızı ister.
- Veritabanında relation’lar(ilişkiler) için Guid adı verilen unique(tekil) bir tanımlayıcı kullanılır.
- Her ne şartla olursa olsun veritabanına direkt veri yazmak Microsoft tarafından unsupported (sisteminize zarar geldiğinde Microsoft tarafından destek alamayacağınız durum) unsur olarak değerlendirilir. Veri yazmak için web servislerini kullanmak gerekmektedir
Burada sanıyorum açıklanmaya en ihtiyaç duyulan madde 1. Madde. Account(Firma) kartını ele alarak açıklayayım; CRM’in Microsoft tarafından açılmış “name”,”accountnumber” gibi alanları “accountbase” tablosu üzerinde yer alırken, bizim vergi_numarası diye bir alanı açtığımızı varsayalım. Bu alan “new_vergi_numarasi” şeklinde “AccountExtensionBase” tablosu içinde açılacaktır. Bu iki tablo birbirine “AccountId” isimli alandaki Guid ile bağlanacaktır. Bu örnekteki yapı bizim alan açmamıza izin verilen tablolarda buna benzer şekilde olacaktır.
Eğer filteredview kullanacaksanız bu yapının farkında bile olmayacaksınız. Çünkü “filteredview”lar bu ilgili tabloları birbirlerine join yaparak(yani birleştirerek) getirmektedir. “Filteredview”’lar bize, güvenlik,silinmiş ve pasife çekilmiş kayıtları göstermeme gibi bizim uğraşarak yapmamız gereken birçok şeyi içerisinde yapmış bir veri sorgulama ortamı sunmaktadırlar.
Bir filteredview'in yapisini incelerseniz en az 50 tablo ile joinli oldugunu görebilirsiniz; Aşağıdaki resimde FilteredAccount isimli view'in yapisinin bir kısmını bulabilirsiniz (Daha resme sığmayan en az 30 tablo var resmin altında)

Ayrica Özelleştirilebilir tabloların Extension isimli ek tablolarını veritabanında görebilirsiniz.

Benim oluşturduğum test uygulamasının “Veri Çek (Using a Sql Data Access)” düğmesinin altında yer alan kod; (Yine daha kolay olması için kod makale bundan sonra kod üzerindeki açıklamalarla devam edecek)
private void btnQueryOnSql_Click(object sender, EventArgs e)
{
//sql server'a baglanmak icin gerekli olan baglanti cumlesini olusturuyoruz.
string ConnectionString = "data source=**sql_server**;database=**veritabani_adi**;user=**kullanici_adi**;password=**sifre**;";
//Baglanti cumlesini baglanti nesnemize parametre olarak vererek baglanti nesnemizi olusturuyoruz
SqlConnection myConnection = new SqlConnection(ConnectionString);
try
{
//sql server baglantisini aciyoruz.
myConnection.Open();
//veri cekmekte kullanacagimiz sql cumlesini olusturuyoruz.
string SQLstring = "select fullname, contactid from filteredcontact where address1_city like stanbul";
//sql cumlesini ve baglantimizi vererek bir veri cekme arabirimi olusturuyoruz.
SqlDataAdapter myDataAdapter = new SqlDataAdapter(SQLstring , myConnection);
//Verileri icerisinde barindiracak olan nesnemizi olusturuyoruz.
DataSet myDataSet = new DataSet();
//Verileri dolduruyoruz
myDataAdapter.Fill(myDataSet);
if (myDataSet != null)
{
if (myDataSet.Tables[0].Rows.Count > 0)
{
//Verileri gostermesi icin grdi'e veriyoruz.
GridView.DataSource = myDataSet.Tables[0];
}
else
{
throw new Exception("DataSet nesnesi kayt iermiyor.");
}
}
else
throw new Exception("DataSet nesnesi null geldi");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
//Baglanti acik ise kapatiyoruz.
if (ConnectionState.Open == myConnection.State)
myConnection.Close();
}
}
Bir makalemizin daha sonuna geldik. Unutmayın veri sorgulama yöntemleri ile ilgili 1 makale daha var sırada.
Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net
Microsoft Dynamics CRM 3.0 ‘dan Veri Sorgulama Yöntemleri -1 (Web Servisleri)
Microsoft CRM verilerini okumak isimli bir yazı dizisi oluşturmaya karar verdim. Bunun nedeni ise CRM ile uğraşan pek çok insanla tanışmam ve hepsinin farklı bir yol izlediğini görmem. Hepsi bir,iki yol biliyor ama çoğu eksik veya yanlış bilgilerle bu işi yapıyorlar. Bütün yöntemleri biraraya getirip anlatmak en iyisi olacak diye düşündüm.
Microsoft CRM üzerinde veri sorgulaması yapmanın üç yolu bulunmakta ve ben bu üç yolu, bu yazı dizisinde örnekleriyle anlatacağım. Bu üç yol sırasıyla, Web Servislerini kullanmak, Sql kullanarak veritabanına erişim ve FetchXML kullanmak. Yazımızın birinci bölümü web servisleri ile başlıyor;
Microsoft CRM, bizlere üzerinde uygulama geliştirmek için çok iyi bir platform mimarisi sunuyor. Bu mimarinin neredeyse temel yapıtaşı konumunda olan WebServis’leri ise bize özellikle veri yazarken büyük kolaylıklar sağlasa da veri okurken bazen karışık olabiliyor. Web Servisleri class(sınıf) mimarisinde olduğundan nesne paylaşımına dayalı bir altyapı sunuyor. Bu doğru kullanıldığında, bize, program yazarken uzun uzun attribute ve property hazırlamak derdinden kurtarıyor.
Microsoft CRM’in 2 adet temel Web Servisi bulunmakta;
- CRM Service : istediğiniz entity üzerinde Create(Oluşturma),Update(Güncelleme) , Delete(Silme) gibi işlemleri yapmanızı sağlıyor. Adresi;
http://<yourservername(:port)>/mscrmservices/2006/crmservice.asmx
- Metadata Service : CRM’in entity ve picklist mimarisi gibi metadata veritabanında bulunan veriler üzerinde yine Create(Oluşturma),Update(Güncelleme) ,Delete(Silme) gibi işlemleri yapmanızı sağlıyor. Metadata verisi içerisinde bir picklist(yani combobox-dropdownbox)’in içeriği, bir alanın türü gibi sistem üzerinde kullandığımız nesnelere yönelik bilgileri tutmaktadır. Adresi;
http://<yourservername(:port)>/mscrmservices/2006/metadataservice.asmx
Web Servisini Projemize Eklemek :

Visual Studio’da açtığımız uygulamamızın adı üzerinde sağ tuşa tıklayarak getirdiğimiz menüde aşağıdaki gibi “Add Web Reference”’a tıklıyoruz.
Açılan pencereye eklemek istediğimiz servisin url’ini yazıyoruz ve “go” düğmesine tıklıyoruz.


Servis credential yani kimlik doğrulamak için bizden kullanıcı adı ve şifre isteyecek. Bunu geçtikten sonra “Web reference name”’e servise verecegimiz ismi yazıyoruz. Burada ben “MyService” ismini veriyorum. “Add Reference” düğmesine tıklıyoruz.Artık servisimizi projemize eklemiş durumdayız.
XML Web Servisleri hakkinda daha fazla bilgi almak ve kendi web servislerinizi yazmak istiyorsaniz aşağıdaki linklerden gerekli bilgiye ulaşabilirsiniz;
http://www.yazgelistir.com/Makaleler/makaleler.aspx?KatId=1000000009&Kat=XML%20Web%20Servisleri
http://www.codeproject.com/cs/webservices/myservice.asp
Kod Yazmaya Başlamak:
Servisimizi ekledikten sonra kod yazma işlemine geçebiliriz. Örnek kod bize CRM Servislerini kullanarak “ select fullname, contactid from filteredcontact where address1_city like ‘İstanbul’ ’” sorgusunu nasıl çekebileceğimizi gösterecek. Uygulamamızın ekran görüntüsü aşağıdaki gibi olacak ve veri çektikten sonra(Veri Çek (Query Expression) düğmesine bastıktan sonra) bize mesaj kutusu içinde istediğimiz veriyi gösterecek
(Aşağıdaki örnek kodu kendi projeniz üzerine yapıştıbileceğinizi düşündüğümden makalemin bundan sonraki kısmına kod üzerindeki not alanlarında devam ediyorum.)
Düğmenin arkasında yazan kodlar ve bunların açıklamalaı ise aşağıdaki gibidir; (CRM nesnelerine kolayca erişmek için en tepeye “ using TestApplication.MyService; ” kodunu eklemeyi unutmuyoruz tabii ki) (TestApplication burada benim uygulamamın adı siz kendi uygulamanızın adını yazmalısınız bunun yerine)
private void btnRetrieveData_Click(object sender, EventArgs e)
{
try
{
// CRM Servis'ini cagiriyoruz
CrmService service = new CrmService();
// servise network'te kim oldugumuzu soyluyoruz. (Eger CRM Server'i ile ayni domainde degilseniz
// bunu yapmak zorundasiniz yoksa "The request failed with HTTP status 401: Unauthorized." hatasini alirsiniz)
System.Net.NetworkCredential MyCredential = new System.Net.NetworkCredential();
MyCredential.UserName = ""; // Domain Kullanici Adi
MyCredential.Password = ""; //Domain Kullanicisinin Sifresi
MyCredential.Domain = ""; //Domain Adi
service.Credentials = MyCredential;
// Eger crm server ile ayni domainde iseniz ve sizin crm'de bir rolunuz varsa asagida parantezler icerisinde
// belirttigim komutu yukaridaki 5 satir yerine kullanabilirsiniz
// ( service.Credentials = System.Net.CredentialCache.DefaultCredentials; )
// istedigimiz sutunlari getirmemizi saglayacak olan ColumnSet nesnemizi olusturuyoruz.
ColumnSet cols = new ColumnSet();
// ColumnSet nesnemize geri dondurmek istedigimiz sutunlarin adini veriyoruz.
cols.Attributes = new string[] { "fullname", "contactid" };
// ConditionExpression nesnemizi olusturuyoruz.
ConditionExpression condition = new ConditionExpression();
// Bize donecek olan contact'lar icerisinde adresinin sehri stanbul olanlari filtreliyoruz.
condition.AttributeName = "address1_city";
condition.Operator = ConditionOperator.Like;
condition.Values = new string[] { "stanbul" };
// FilterExpression nesnemizi olusturuyoruz.
FilterExpression filter = new FilterExpression();
// Yukarida olusturdugumuz kosul filtresini FilterExpression'a veriyoruz.
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] { condition };
// QueryExpression nesnemizi olusturuyoruz.
QueryExpression query = new QueryExpression();
// Yukarida olusturdugumuz filtremizi ve donmesini istedigimiz sutunlari QueryExpression'a veriyoruz.
query.EntityName = EntityName.contact.ToString();
query.ColumnSet = cols;
query.Criteria = filter;
// Bu kosula uyan contact'lari sistemde sorgulatiyoruz.
BusinessEntityCollection contacts = service.RetrieveMultiple(query);
if (contacts != null)
if (contacts.BusinessEntities.Length > 0)
{
//BusinessEntityCollection array'indan sorgulama sonucunda donen ilk degeri aliyoruz.
//Ve bu ilk degeri contact sinifina ceviriyoruz.
contact myContact = (contact)contacts.BusinessEntities[0];
if (myContact != null)
{
//artik elimizde olan contact sinifi ile yukarida bize donmesini istedigimiz sutunlarin
//iceriklerini alabiliriz.
MessageBox.Show("ad-soyad:" + myContact.fullname.ToString() + " id:" + myContact.contactid.Value.ToString());
}
}
}
// Soap yani Web Servisi hatalarini yakalamak icin ilgili Exception sinifimiz ekliyoruz.
catch (System.Web.Services.Protocols.SoapException ex)
{
MessageBox.Show(ex.Message + " " + ex.Detail.InnerText);
}
// Soap disindaki Standart hatalari yakalamak icin Exception'i da kodumuza ekliyoruz.
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Programımızı çalıştırdığımızda bize istediğimiz bilgiyi sorgulayıp getirecektir. Bir makalemizin daha sonuna geldik. Unutmayın veri sorgulama yöntemleri ile ilgili 2 makale daha var sırada.
Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net
Show navigation bar item in IFrame in Microsoft CRM
We don't make anything without Navigation Bar in CRM. In default, CRM haven't a setting about showing their pages in a IFrame. But we can change this event and we can more effective a usage area in CRM Form. Specially sales persons don't want to click to lot of things and they want see the result of an action. So in this article we will learn how to show associated activities in centre of Contact card. We have a way that have two step. In first step, we will place a IFrame in Contact Card. In second step we will place a little JavaScript code for IFrame that we had placed. Let start;
a) IFrame :
"Settings" -> "Customizations" -> "Customize Entities" after this steps in CRM, we find the Contact card and we open this card. We select the "Forms and Views" in navigation bar at left and we clicked the Form.
Where you want place the your activities screen you select the interested tab and click the "Add IFrame" button. A window will be opened;
- set the Name "HistoryFrame",
- set the URL "about:blank",
- we select the "Pass record object-type code and unique identifier as parameters",
- we unselect the "Restrict cross-frame scripting"
The first step will be completed when we press the ok. Let the show second step;
b) JavaScript :
We click the "Form Properties" in same screen. We click the "OnLoad" on opened window. We replace the code that below. We click the buttons "ok" and "Save Form and Close".
function GetFrameSource(tabSet)
{
if (crmForm.ObjectId != null)
{
var oId = crmForm.ObjectId;
var oType = crmForm.ObjectTypeCode;
var security = crmFormSubmit.crmFormSubmitSecurity.value;
return "areas.aspx?oId=" + oId + "&oType=" + oType + "&security=" + security + "&tabSet=" + tabSet;
}
else
{
return "about:blank";
}
}
crmForm.all.IFRAME_HistoryFrame.src = GetFrameSource("areaActivityHistory"); |
We click to "Publish" that in the "actions" menu. We will see the activity history of contact when we open a contact card.
I hope it will done. Regards.
Barış KANLICA
Software Specialist
brsk@e-kolay.net
www.cub-e.net
Access a web page in Dynamics CRM with JavaScript Code
In this article, I will see how to you can access a web page with JavaScript code in Microsoft Dynamics CRM. You can process about CRM entities or different action in that page.
|
In sample JavaScript code; we will take Guid of on Product and we will pass this Guid to '/QuoteCalcs/Calcs.aspx' page. This page will make some process and it will return a result that in xml tags that in <baris>. If the result is "null" or "false" JavaScript code will show an error alert to user.
If you want cancel the save process of CRM after this error, you must add "event.returnValue = false;" code block after error code.
If there is a value in object that passed a area for show to user.
You will find the c# code after JavaScript code.
This code will show how to you will access a web page with JavaScript;
var oProduct = document.crmForm.all.productid;
// we passed the Lookup object for access to Guid//
var aProduct = new Array();
//The lookup is an array on CRM Form. So we must access to
//this objects of array with an array object.
aProduct = oProduct .DataValue;
//Yeah, we found the Guid of Product
var sProductID = aProduct [0].id;
sProductID = encodeURIComponent(sProductID);
if (sProductID!=null)
{
//We create an Microsoft.XMLDOM object
var oXmlDoc = new ActiveXObject('Microsoft.XMLDOM');
oXmlDoc.async = false; // we don't want asenkron code process
var path = '/QuoteCalcs/Calcs.aspx?productid=' + sProductID ;
//we passed the path of our web page to XMLDOM object
oXmlDoc.load(path);
we look for <baris> xml tag - Baris is my name:-)
var oNode = oXmlDoc.selectSingleNode('baris');
if (oNode != null && oNode.text == 'false')
{
alert('an error');
}
if (oNode != null && oNode.text != 'false')
{
//we set value to price area in CRM Form
crmForm.all.price.value = oNode.text;
}
}
The real process will run on this aspx page. We takes the parameters that passed from our JavaScriptCode. We are looking for that parameters are empty. Later, We access to CRM Web Services with default credential. If you aren't same domain with Microsoft Dynamics CRM you didn't access to CRM Web Service with default credential so you must access to Web Services with username and password. We will send a query that like "select * from filteredproduct where productid=ProductId" with using web services. The response from web services is a BussinessEntityCollection that is the base of all entities in Microsoft Dynamics CRM. We convert the BussinessEntityCollection class to product class. and we are find our value what you want and we return the this value in <baris> xml tag.
<%@ Page Language='c#'%>
<%@ Import Namespace='CrmSdk' %>
<script runat='server'>
protected override void Render(HtmlTextWriter writer)
{
Response.Clear();
Response.ContentType = 'text/xml';
string ProductID = Request.QueryString['ProductID'];
string TYPE = Request.QueryString['Type'];
if (ProductID != null &&
ProductID !='null')
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
QueryByAttribute attributeQuery = new QueryByAttribute();
attributeQuery.ColumnSet = new AllColumns();
attributeQuery.Attributes = new string [] {'productid'};
attributeQuery.Values = new string [] {ProductID};
attributeQuery.EntityName = EntityName.product.ToString();
RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
retrieve.Query = attributeQuery;
RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)service.Execute(retrieve);
if (retrieved.BusinessEntityCollection.BusinessEntities.Length > 0)
{
product prd = (product)retrieved.BusinessEntityCollection.BusinessEntities[0];
if (prd.price!=null)
{
Response.Write('<baris>'+prd.price.Value.ToString()+'</baris>');
}
else
{
Response.Write('<baris>false</baris>');
}
}
else
{
Response.Write('<baris>false</baris>');
}
}
}
</script>
All of this process we have a JavaScript and a c#Script code. In c#Script code we import the CrmSdk dll to the page with import method. You can make your CrmSdk ( Microsoft.Crm.Sdk.Wsdl.dll ) dll. In below you can find how to make your CrmSdk dll. All of those process we must put our code to a server and we must create a virtual directory in CRM Web Site in IIS.
Note:
|
Creating a DLL for the Microsoft CRM Web Service
When developing your solution, you first need to general a WSDL that will provide you with all the classes and methods in Microsoft CRM 3.0. You should always start with a clean installation of Microsoft CRM 3.0, one that has had no customizations made. This way your code will not rely on information not found on a customer installation.
The steps below demonstrate how to generate this reference file for the SDK. You can use the same procedure to generate a reference file for the metadata Web service.
- Click Start, point to All Programs, point to Microsoft Visual Studio .NET 2003, point to Visual Studio .NET Tools, and then click Visual Studio .NET 2003 Command Prompt.
- At the command prompt, create the reference file, Microsoft.Crm.Sdk.Wsdl.cs, by typing the following command, using the URL of your server running Microsoft CRM:
wsdl.exe /out: Microsoft.Crm.Sdk.Wsdl.cs /namespace:CrmSdk http://<yourserver>/mscrmservices/2006/crmservice.asmx
- Generate a WSDL DLL that will be packaged with your solution using the reference created in step 2 using this command:
csc /t:library Microsoft.Crm.Sdk.Wsdl.cs
This DLL can now be packaged with your add-on.
|
Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net