
Merhaba arkadaşlar,
Uzun bir aradan sonra Dynamics Ax/365 yazısı ile karşınızdayım. Bugün sizlere Dynamics 365 F&O ortamında AIF yazmayı/geliştirmeyi yeni adıyla Custom Service yapımını anlatacağım.
Bu örneğimde, X++ kullanarak bir müşteri listeleme servisinin nasıl kurgulandığını ve AX 2012 dönemindeki AIF yapısından farklarını inceleyeceğiz.
1. Veri Yapısını Tanımlamak: Data Contract Class
Servisimizin dış dünyaya hangi formatta veri sunacağını belirlemek için Data Contract sınıfını kullanıyoruz. Bu sınıf ile aslında şunu sağlayacağım. CustTable’daki tüm alanları dışarı açmak yerine, sadece dışarıya aktarmak istediğim alanları buraya tanımlayacağım. Böylece tüm kontrol elimizde olmuş olacak.
[DataContract]
public final class SEMCustTableContract
{
CustAccount custAccount;
CustName custName;
// Bu attribute, bu metodun dış dünyaya "Name" adıyla açılacağını belirtir.
[DataMember("CustAccount")]
public CustAccount parmCustAccount(CustAccount _custAccount = custAccount)
{
custAccount = _custAccount;
return custAccount;
}
[DataMember("CustName")]
public CustName parmCustName(CustName _custName = custName)
{
custName = _custName;
return custName;
}
}
Bu Contract(model) yapısına göre, bu class sadece 2 alan içeriyor. CustAccount ve CustName şeklinde. Bu noktada hemen 2012 AIF ile 365 farkına bakabiliriz. 2012’de Contract(model) classlar DataContractAttribute olarak işaretleniyordu, üyeleri yani memberları ise, DataMemberAttribute olarak işaretleniyordu. Artık D365’de direkt DataContract ve DataMember dememiz yeterli oluyor.
2. İş Mantığını Kurmak: Service Class
public final class SEMCustTableService
{
///
/// İlk 1000 Müşteri kaydını liste olarak döner.
///
// ÖNEMLİ: List döndürürken AifCollectionTypeAttribute kullanmak ZORUNLUDUR. // Bu, listenin içinde ‘SEMCustTableContract’ tipinde objeler olduğunu sisteme söyler. [ SysEntryPoint(true), AifCollectionTypeAttribute(‘_return’, Types::Class, classStr(SEMCustTableContract)) ] public List getCustTable() { List contractList = new List(Types::Class); SEMCustTableContract contract; CustTable custTable; // Veritabanından ilk 1000 kaydı çekiyoruz while select firstonly1000 custTable { // Her satır için yeni bir kontrat oluşturuyoruz contract = new SEMCustTableContract(); // Alanları dolduruyoruz contract.parmCustAccount(custTable.AccountNum); contract.parmCustName(custTable.name()); // name() metodu müşteri ismini getirir // Listeye ekliyoruz contractList.addEnd(contract); } return contractList; } ///
/// Verilen Müşteri numarasına göre tek bir kayıt döner.
///
[SysEntryPoint(true)] public SEMCustTableContract findByCustNum(CustAccount _custAccount) { SEMCustTableContract contract; CustTable custTable; // Gelen müşteri numarasına göre kaydı bul select firstonly custTable where custTable.AccountNum == _custAccount; if (custTable) { contract = new SEMCustTableContract(); contract.parmCustAccount(custTable.AccountNum); contract.parmCustName(custTable.name()); } else { // Kayıt bulunamazsa null dönebilir veya boş bir kontrat dönebilirsiniz. // Burada null dönüyoruz, böylece karşı taraf kaydın olmadığını anlar. contract = null; } return contract; } }
Dikkat Edilmesi Gereken Teknik Detaylar
AifCollectionTypeAttribute: X++ List yapısı generic olmadığı için, listenin içinde ne tür bir nesne olduğunu (SEMCustTableContract) sisteme bu attribute ile bildirmek zorunludur. Aksi halde servis JSON serileştirme yapamaz.
SysEntryPoint: Metodun dışarıdan tetiklenebilir olduğunu belirtir. Parametre true olduğunda D365’in standart güvenlik katmanı devreye girer.
Hata Yönetimi: Örnekte kayıt bulunamadığında null döndük. Entegrasyon senaryonuza göre boş bir contract veya hata mesajı içeren bir yapı da kurgulayabilirsiniz.
Şuanda kod tarafını tamamlamış bulunuyoruz.
Şimdi bu servis Deploy etme konusuna bakalım;
1. Visual Studio’da projenize yeni bir Service öğesi ekleyin. Ben ismine SEMCustTableServiceNode dedim. Servis özelliklerinden ilgili Servis Class’ınızı belirtin. Benim örneğime göre SEMCustTableService isimli classı seçtim.
2. Yeni bir Service Group öğesi ekleyin ve Servisinizi içerisine atın. Servis group ismine SEMCustTableServiceGroup verdim. Böylece ileride ayırt etmek kolay olacak. Bu kısımlar 2012 ile aynı zaten. Deploy durumu biraz daha farklı artık. 365 bizim için bunu kendisi yönetiyor artık. Sonraki adımda açıklıyorum.
3. Service Group objenizi açın ve özelliklerinden Auto Deploy özelliğini Yes durumuna getirin. Artık projenizi test/canlı ortama deploy ettiğinizde otomatik deploy oluyor. Bunları Microsoft yönetiyor. Aifler durmuş gideyim başlatayım diyebileceğimiz bir ekran maalesef bulunmuyor 🙂
Buraya kadar geldiysek, tebrikler. İşim çoğunu tamamladık. Projeyi çalıştırdığınızda D365 dünyasında artık Sistem Yönetimi altında Gelen/Giden hizmetlerin olmadığını fark edeceksiniz. Zaten proje içinde manuel şekilde deploy da demedik 🙂 Peki bu servis nerede? diye sorularınızı duyar gibiyim? 🙂
Microsoft bunu menüden kaldırmış olsada bir yerde tutuyor. Aşağıdaki yapıda servisinizi yayınlamış oluyor.
Oluşan servis URL adresi şu yapıda oluyor: d365urlAdresiniz/api/services/ServisGrubunuzunAdi/ServisNodeAdiniz/methodadi
Benim örneğime göre şöyle bir url oluştu: mydevboxurl/api/services/SEMCustTableServiceGroup/SEMCustTableServiceNode
Metodu tetiklemek için tam adres şöyle olacaktır: http://mydevboxurl/api/services/SEMCustTableServiceGroup/SEMCustTableServiceNode/getCustTable
Servisinizi gördüyseniz işlem bitmiştir. Deploy olmuştur. Kodlama işlemlerimiz bitmiştir.
Bu servisi dışarıdan kullanmak için, Azure tarafında App Registiration oluşturmalısınız. Bunu yapmadan maalesef bağlantı sağlayamazsınız. Aslında 2012 ile en büyük fark burada başlıyor. Her şey Azure Cloud ortamında olduğu için bağlantı yapmak için ekstra bir ayarlama yapılması gerekiyor.
Adım 1: Azure App Registration (Bir kere yapılır)
- Azure Portal’a gidin > Microsoft Entra ID (eski adıyla Azure AD).
- App Registration > New Registration.
- İsim verin (örn: D365ConsoleApp).
- Oluşan kayıtta Application (client) ID’yi not edin.
- Soldan Certificates & secrets > New client secret diyerek bir şifre oluşturun ve Value kısmını not edin (Bu sayfadan çıkınca bir daha göremezsiniz).
Adım 2: D365 F&O Yetkilendirme (Bir kere yapılır)
- D365 F&O’yu açın.
- System Administration > Setup > Microsoft Entra ID applications yolunu izleyin.
- New diyerek yeni satır açın.
- Client Id: Azure’dan aldığınız ID.
- Name: Console App. Ya da sizin projenize ilgili mantıklı bir isim
- User ID: Admin (veya yetkili bir servis kullanıcısı).
İşlemler bu kadardır. Artık servisiniz bir uç nokta (endpoint) olarak hazır!
Özet bir infografik;
İzlemek isteyenler için yazımın videosu burada;
Sırada Ne Var?
Bu yazıda işin X++ tarafını ve mimari farklarını ele aldık. Bir sonraki yazımda, hazırladığımız bu servisi bir .NET (C#) projesinden OAuth 2.0 kullanarak nasıl tetikleyeceğimizi adım adım anlatacağım.
Takipte kalın!
İyi çalışmalar.

