CRM Plugins - Json Kullanımı

Working with JSON objects in Dynamics CRM Plugins


CRM üzerinde çalışan pluginlerimizde json formatında veri döndürdüğümüzü düşünelim .

Genellikle bu tür işlemler için .NET Frameworkun bize sunduğu Newtonsoft.json kütüphanesini kullanırız.

Eğer pluginimizi Sandbox a register edersek pluginde kullandığımız javascriptSerializer metodu aşağıdaki hatayı verecektir.

Unhandled Exception: Microsoft.Crm.CrmException: Unexpected exception from plug-in (Execute): XXXXXXXX.CRM2015.WorkflowActivities.XXXXXXXX: System.MethodAccessException: Attempt by security transparent method ‘XXXXXXXX.CRM2015.WorkflowActivities.XXXXXXXX.SetLocationInfo(Microsoft.Xrm.Sdk.IOrganizationService, Microsoft.Xrm.Sdk.ITracingService, System.String)’ to access security critical method ‘System.Web.Script.Serialization.JavaScriptSerializer..ctor()’ failed.
Assembly ‘XXXXXXXX.CRM2015.WorkflowActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3f9fc15734725b08′ is partially trusted, which causes the CLR to make it entirely security transparent regardless of any transparency annotations in the assembly itself.  In order to access security critical code, this assembly must be fully trusted.
Assembly ‘System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ is a conditionally APTCA assembly which is not enabled in the current AppDomain.  To enable this assembly to be used by partial trust or security transparent code, please add assembly name ‘System.Web.Extensions, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9′ to the the PartialTrustVisibleAssemblies list when creating the AppDomain.
at Microsoft.Crm.Sandbox.SandboxCodeUnit.Execute(IExecutionContext context)

at Microsoft.Crm.Workflow.Services.ProxyCustomActivity.Execute(CodeActivityContext executionContext)


 Hatanın sebebi CRM contextinde 3.party dllere erişilememesidir.

Bu hatayı ILMerge kullanarak çözebiliriz. ( .NET dllerini tek bir dll olarak birleştiren araç)

Alternatif bir çözüm olarak ise ; 3.party çözüm kullanmayarak DataContractJsonSerializer kullanmaktır.

Biz örneğimizde DataContractJsonSerializer yöntemini kullanacağız.


CRM Plugininde DataContractJsonSerializer Kullanımı

Servisimizden gelen verileri tutacağımız bir DataContract classı tasarlayalım.


   [DataContract]
    public class JsonSalesServiceTest
    {
        //datamember name value indicates name of json field to which data will be serialized/from which data will be deserialize

        [DataMember(Name = "Status")]
        public string Status { get; set; }

        [DataMember(Name = "Source")]
        public string Source { get; set; }

        [DataMember(Name = "BusinessUnit")]
        public Reference1 BusinessUnit { get; set; }

        [DataMember(Name = "Customer")]
        public Reference1 Customer { get; set; }

        [DataMember(Name = "CustomerAddress")]
        public string CustomerAddress { get; set; }

        public JsonSalesServiceTest() { }
    }

Json dizimizdeki verileri classımıza atayalım.(Deserialize)

Deseriliaze

 #region Deserialize

                using (MemoryStream DeSerializememoryStream = new MemoryStream())
                {
                    //Json String that we get from web api 
                    string ResponseString = "{\"Status\":\"" + "Create" +
                                          "\",\"Source\":\"" + "Dynamics CRM London" + 
                                          "\",\"BusinessUnit\":\"" + "{\"Name\":null,\"Id\":\"01f4f959-ceea-e511-80ed-005056b503b5\"}" + 
                                          "\",\"Customer\":\"" + "{\"Name\":null,\"Id\":\"d43f26ff-8e2c-e611-80ff-005056b503b5\"}" +
                                          "\",\"CustomerAddress\":\"" + "400005" + "\"}";

                    //initialize DataContractJsonSerializer object and pass Student class type to it
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonSalesServiceTest));

                    //user stream writer to write JSON string data to memory stream
                    StreamWriter writer = new StreamWriter(DeSerializememoryStream);
                    writer.Write(ResponseString);
                    writer.Flush();

                    DeSerializememoryStream.Position = 0;
                    //get the Desrialized data in object of type Student
                    JsonSalesServiceTest SerializedObject = (JsonSalesServiceTest)serializer.ReadObject(DeSerializememoryStream);
                }
                #endregion

Seriliaze

Classımızdaki verileir Json formatına çevirelim.

   #region Serialize
               JsonSalesServiceTest json = new JsonSalesServiceTest();
               json.Status = PluginMessages.Cancel;
               json.Source ="Dynamics CRM AGC";

 if (order.OwningBusinessUnit != null && order.OwningBusinessUnit.Id != Guid.Empty)
                        json.BusinessUnit = new Reference1()
                        {
                            Name = order.OwningBusinessUnit.Name,
                            Id = order.OwningBusinessUnit.Id
                        };

                    if (order.CustomerId != null && order.CustomerId.Id != Guid.Empty)
                    {
                        json.Customer = new Reference1() { Name = order.CustomerId.Name, Id = order.CustomerId.Id };
                    }

 json.CustomerAddress = !string.IsNullOrEmpty(order.BillTo_Line1) ? order.BillTo_Line1 : " ";

                string parameter1 = "";
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonSalesServiceTest));
                    serializer.WriteObject(memoryStream, json);
                    parameter1 = Encoding.Default.GetString(memoryStream.ToArray());
                }

#endregion

CRM 2016 - Alt Kayıtları Aktif / Pasif Yapma (MSCRMWorkflowUtilities)

CRM arayüzü üzerinden  bir kayda aktif , pasif , birleştir, paylaştır gibi işlemleri kolaylıkla yapabiliriz. Peki bu kaydın altındaki kayıtlara da aynı işlemleri yapmak istersek nasıl yapabiliriz.

Örnek vermek gerekirse bir firmayı pasif yaptığımız zaman altındaki ilgili kişilerini de pasif yapmak istiyoruz.Aynı şekilde aktif yaptığımızda altındaki ilgili kişilerininde aktif olmasını isteyebiliriz.

Herhangi bir kod yazmadan bu işlemleri MSCRMWorkflowUtilities solutionı ile yapabiliyoruz. Tek yapmak gereken çözümü indirip crm e yüklemektir.

Not: CRM versiyonunuza uygun paketi indirmelisiniz.

Çözüm bize SetState operatorunu workflow üzerinde kullanılmasını sağlayacaktır. Bu şekilde kayıtların durumlarını güncelleyebileceğiz.

İlk olarak ana kayıt için bir iş akışı oluşturalım.

Firma kayıtları için alt kayıtlarının durumlarını güncellemek için bir iş akışı oluşturalım.Ardından istediğimiz koşullarda ve birçok basamaklı adım girebiliriz.

Aşağıdaki örnekte , firma aktif olduğunda altındaki ilgili kişileri aktif , firma pasif olduğunda altındaki ilgili kişileri pasif edilecektir.

Not: Firmanın  ilgili kişileri ve aktivitelerini de pasif yapacaksak bunlar için de ek adımlar tanımlayabiliriz.



Eklediğimiz her  Cascade SetState adımı için  3 parametre tanımlamamız gerekir.



1- Alt Varlığın Adı ( Child Entity Name )

SetState işlemini basamaklamak için kullanılacak alt vrlığın adıdır .
Bizim örneğimizde "contact" olacaktır.
Şema adını varlığın tanımından bulabilirsiniz.



2- Ana Varlıkla Kurulan İlişki Alanı ( Child Lookup Attribute To Parent )

Ana varlık ile alt kaydın birbirine bağlandığı arama alanının şema adıdır.
Bizim örneğimizde "parentcustomerid" dir.
Bu adı alt varlığın ana varlığa bağlandığı arama alanının tanımlarından ulaşabilirsiniz.



3- Alt Varlığın Durum Kodu ( Target Child State Code )

Alt varlıkların durumunu içeren değerdir. Bu değer çoğu zaman pasif için 1 , aktif için 0 dır.

Not :Bazı fırsat gibi özel varlıklarda SetState mesajının kullanılması desteklenmez. Tüm özel varlıklar destekler.


CRM 2016 Customizations - Aktivite Butonlarını Düzenleme

Restore Add Activity Buttons 


Aktivite butonları CRM 2013 ten itibaren default olarak ribbon bar da görünmez.  Bu işlemleri aşağıdaki ekran görüntüsünde görüldüğü gibi form üzerindeki Activities tabı altından yapabiliriz.


Bu butonları ribbon barında görebilmek için Ribbon WorkBench üzerinde aşağıdaki işlemleri yapmamız gerekir.

Not : Ribbon WorkBench solutionını buradan indirip crm e import etmeniz gerekecektir.

-- İlk olarak hangi entity formu üzerinde işlem yapacaksak o entitiye air bir solution oluşturalım . Ben account formu için çalışma yapacağım.

 İlk olarak Solutionlara gidelim. Setting > Customization > Solutions



Yeni solution oluşturmak için New butonuna basalım.


Solutionımızın bilgilerini girelim.Save butonuna basalım.

Gelen ekrandan Add Existing butonuna basalım ve sonrasında Entity i seçelim.

Gelen pencereden Accountu seçelim ve OK butonuna basalım.


Gelen ekranda Forms tabı altından Main formumuzu seçelim . Burada sadece Main formunu almak yeterli olacaktır. Finish butonuna basalım.

Missing Required Components penceresinde No , do not include required components i seçelim ve OK butonuna basalım.


Artık solutionımızı oluştıurmuş olduk .


Sıra geldi Ribbon WorkBench ile solutionımızı düzenlemeye;

Daha önce sistemimize yüklediğimiz RibbonWorkBench2013  managed solutionımızı acalım.





 Açılan pencereden Open Solution butonuna basalım ve oluşturduğumuz solutionı açalım.


 Ribbon görünümüne geçmek için Ribbon tabına tıklayalım.


 Daha sonra entitimizin Form görünümünü seçelim.


Bir sonraki adımda activite butonlarının bulunduğu Add tabına tıklayalım.


İlk olarak Task butonunu seçelim ve fare ile sağ tık yaptıktan sonra  Customize Command ı seçelim.


Orta bölümde bulunan Solution Elements altında Commands bölümünü genişletelim ve Task için geçerli olan Mscrm.AddTaskToPrimaryRecord u seçip , görünümünü düzenlemek için Edit Display Rules seçeneğini seçelim.


Display Rules penceresinden sağ panelden Mscrm.HideOnCommandBar ı seçelim ve Remove butonuna basalım.


Yapılan işlemleri tamamlamak için OK butonuna basalım.


Daha sonra bu yaptığımız işlemleri diğer aktivite butonları içinde yapalım . (Fax , Phone Call , Email , Letter , Service Activity , Appointment , Recurring Appointment )

İşlemlerimizi tamamladıktan sonra crme yansıması için Publish butonuna basalım.


Daha sonra işlemlerimizi test etmek için bir account kaydı açalım ve ribbonumuzu kontrol edelim.



Yukarıdaki ekran görüntüsünde görüldüğü gibi aktivite butonlarımız ribbonda görünür duruma gelmiştir.