cub-e.net

just coding...

Mobile Development Helper Code for Dynamics CRM

Technologies

Web Services, OData, Dynamics CRM, SOAP
OData, Microsoft Dynamics CRM Modern app SOAP endpoint, Dynamics CRM web services
Desktop, Phone, Windows RT
en-US
9/8/2014

Introduction

The Microsoft.Crm.Sdk.Mobile source code sample is a partial re-implementation of the Microsoft Dynamics CRM SDK classes written as a Portable Class Library to facilitate development of store apps for Windows 8.1 desktop, tablets, and phones. The code makes use of the SOAP and OData protocols to issue web service method calls. An organization web service proxy and most of the message response/request classes in the CRM SDK have been implemented. When writing apps that use this code, you don’t have to link to the CRM SDK assemblies to access the organization web service.

This code can also be used when you develop apps using Xamarin. However, you must comment out the EnableProxyTypes method in Microsoft.Xrm.Sdk.Samples.cs when developing iOS or Android apps using Xamarin because that method contains code that is specific to Windows Store. An alternative is to comment out the relevant code as shown here.

 

Copy code
C#
Edit|Remove
public async Task EnableProxyTypes()
{
    List<TypeInfo> typeList = new List<TypeInfo>();
    //// Obtain folder of executing application.
    //var folder = Package.Current.InstalledLocation;
    //foreach (var file in await folder.GetFilesAsync())
    //{
    //    // Not only .dll but .exe also contains types.
    //    if (file.FileType == ".dll" || file.FileType == ".exe")
    //    {
    //        var assemblyName = new AssemblyName(file.DisplayName);
    //        var assembly = Assembly.Load(assemblyName);
    //        foreach (TypeInfo type in assembly.DefinedTypes)
    //        {
    //            // Store only CRM entities.
    //            if (type.BaseType == typeof(Entity))
    //                typeList.Add(type);
    //        }
    //    }
    //}
    typeList.Add(typeof(ActivityParty).GetTypeInfo());
    typeList.Add(typeof(SavedQuery).GetTypeInfo());
    typeList.Add(typeof(Privilege).GetTypeInfo());
    typeList.Add(typeof(SystemUser).GetTypeInfo());
    typeList.Add(typeof(Annotation).GetTypeInfo());
    typeList.Add(typeof(TimeZoneDefinition).GetTypeInfo());
    types = typeList.ToArray();
}
 

 

Building the Sample

Your development computer must have an internet connection to build the library as a NuGet package named Json.NET will be automatically downloaded during the build.

To build the Microsoft.Crm.Sdk.Mobile.dll assembly, follow these steps.

  1. In Visual Studio 2013, with update 2 or later installed, load the Microsoft.Crm.Sdk.Mobile.sln file.
  2. Press F6.

 

Description

The Microsoft Dynamics CRM 2013 SDK (and earlier releases) support client and server side code development for Dynamics CRM. However, the SDK assemblies cannot be used to develop mobile and store applications as the Windows run-time (WinRT) is not supported. To provide support for mobile apps, including cross platform iOS and Android apps, the Dynamics CRM server now supports client access to the organization web service using industry standard protocols such as OAuth (for authentication), plus SOAP and OData for sending web service requests. The problem is that while these protocols are supported, they are difficult to use. The solution is to layer a framework on top of the protocols to make app programming easier. For developing mobile and store apps, you can use the Microsoft Azure Active Directory Library (ADAL) for authentication, and this sample helper code library for web service requests and early-bound type support. 


What is included in the library

This library contains the following key components:

 

  Web Service Proxy

This library provides most methods that the OrganizationServiceProxy class in the CRM SDK does - Create, Update, Assign, Execute, and so on. The class supports early-bound development by providing an EnableProxyTypes method. SOAP implementations of these methods use the same name as are used in the CRM SDK while the OData-based methods have names that begin with “Rest” for example RestCreate.

 

  SDK classes and enumerations

This library supports most common CRM SDK classes and enumerations. With the addition of early-bound type support, you can use Visual Studio IntelliSense when writing your apps.

 

  Organization web service messages

This library includes request/response classes for over 200 messages. It covers both data operations, for example Create, and metadata operations, for example RetrieveMetadataChanges.

 

What isn't included in the library

Several functional areas that the library doesn’t cover are as follows:

Authentication

Since this sample code library targets multiple platforms, and each platform has its unique way to authenticate the user, the library doesn’t provide any authentication mechanism. You must obtain an OAuth access token and pass it to an OrganizationDataWebServiceProxy object to access the organization web service. It’s recommended that you use the Microsoft Azure Active Directory Authentication Library (ADAL) for identity authentication. This library is referenced in the CRM SDK documentation and sample code. There is an open source implementation of ADAL available for iOS and Android. There is a Windows 8.1 version available for the desktop, tablets, and phones.

For more information on ADAL see http://www.cloudidentity.com/blog/2014/06/16/adal-for-windows-phone-8-1-deep-dive.

A sample code file named CRMHelpers.cs is provided to demonstrate how to authenticate a universal app. The file is not included in the build of the library.

DiscoveryService, DeploymentService, OrganizationServiceContext

This library doesn’t provide support for the discovery or deployment web services. It also doesn’t support the OrganizationServiceContext class.

How to write apps that use this library

You can build Microsoft.Crm.Sdk.Mobile.dll using the supplied Visual Studio 2013 solution and add a reference for it in your app’s project or you can add the library’s C# sample code files to your project.

In your app, add code to authenticate the user and obtain a security access token. The method used varies depending on platform as mentioned previously. Next, instantiate the OrganizationDataWebServiceProxy class.

Copy code
C#
Edit|Remove
OrganizationDataWebServiceProxy _proxy = new OrganizationDataWebServiceProxy();
 

Set the access token and web server URL in the OrganizationDataWebServiceProxy object.

Copy code
C#
Edit|Remove
_proxy.ServiceUrl = "<your CRM server URL goes here>";
_proxy.AccessToken = "<access token>";
 

Call EnableProxyTypes to use early-bound types and optionally assign a service time-out interval.

Copy code
C#
Edit|Remove
await _proxy.EnableProxyTypes();

_proxy.Timeout = 600;

Send a message request to the web service by using an async/await pattern.

Copy code
C#
Edit|Remove
WhoAmIResponse whoAmIResponse = (WhoAmIResponse)await _proxy.Execute(new WhoAmIRequest());

// Retrieve User Info

SystemUser user = (SystemUser)await _proxy.Retrieve(SystemUser.EntityLogicalName, whoAmIResponse.UserId, new ColumnSet(true));
 

How to update existing application code

If you want to use existing application code that was written for the CRM SDK with this library, make the following code changes.

1. Add the async keyword to methods.

2. Add await before the call to a proxy method.

3. When accessing the property of a web service response, do so as shown here.

 

Original CRM SDK code

Copy code
C#
Edit|Remove
_proxy.RetrieveMultiple(new QueryExpression(“account”, new Columns(true)).Entities)
 

Modified code

Copy code
C#
Edit|Remove
(await _proxy.RetrieveMultiple(new QueryExpression(“account”, new Columns(true))).Entities)
 

Important notes

  • The sample files are not intended to be used in a production environment. You should deploy this sample to a test environment and examine it for interaction or interference with other parts of the system.
  • Before you deploy this sample to a production environment, make sure that you consider the existing customizations you may have implemented in Microsoft Dynamics CRM 2013.
  • This library was written by Kenichiro Nakamura at Microsoft.

Source code for the CrmSvcMobileUtil program is provided in a separate sample. Use that program to generate any custom or customized entity types in your organization for inclusion in your application.

Source Code Files

  • Microsoft.Xrm.Sdk.Utility.Samples.cs - This file implementes a utility class that provides methods used by the other code files. There is no equivalent for this functionality in the CRM 2013 SDK.


More Information

For more information on Dynamics CRM authentication and app development, see Write mobile and modern apps.

download the code : View this sample online

CRM Service Utility for Mobile Development

Technologies

Dynamics CRM
Code Generation, Dynamics CRM metadata access
Desktop, Phone, Windows RT
en-US
9/8/2014

Introduction

This sample is a custom extension to the CrmSvcUtil.exe program that ships in the Dynamics CRM 2013 SDK. The purpose of this program is to generate C# or VB source code containing early-bound entity types and option set types from the metadata of your CRM server. This code can then be included in your mobile app projects. This enables you to make use of both out-of-box and any custom or customized entities in your code.

 

Building the Sample

To build the program, follow these steps.

  1. Obtain the CrmSvcUtil.exe program and the Microsoft.Xrm.Sdk.dll assembly from the Bin folder of the CRM 2013 SDK. You can download the SDK from http://msdn.microsoft.com/en-us/dynamics/crm/dn467921.aspx.
  2. Load the CrmSvcMobileUtil.sln solution file into Visual Studio 2013.
  3. Add references to CrmSvcUtil.exe and Microsoft.Xrm.Sdk.dll in the project.
  4. Press F6 to build the program.

 

Running the Program

For information on how to run the program, see the SDK topic: Create early bound entity classes with the code generation tool (CrmSvcUtil.exe).

 

Important Notes

    • The sample files are not intended to be used in a production environment. You should deploy this sample to a test environment and examine it for interaction or interference with other parts of the system.
    • This program was written by Kenichiro Nakamura at Microsoft.

       

      More Information

      For more information about writing an extension to the CrmSvcUtil program, see Create extensions for the code generation tool.

      You can download code:

      CRM Service Utility for Mobile Development.zip (48.2KB)

      Dynamics CRM 2013 and Microsoft Dynamics CRM Online nedir?

      Microsoft Dynamics CRM 2013 ve Microsoft Dynamics CRM Online güçlü ve gelişmiş bir iş platformu deneyimini kullanıcılarına sunmaktadır. Dynamics CRM içerisine entegre edilmiş gelişmiş uygulama altyapısı sayesinde sadece uygulamayı kullanmakla kalmıyor aynı zamanda onun istediğimiz yerlerini işimize uygun halde yeniden programlayarak hem kendi içinde hem de dış uygulamalarla konuşabilen kendi iş çözümümüzü oluşturabiliyoruz. Bu şekilde genişlemeye biz xRM adını vermekteyiz. Yani herşeyin yönetilebildiği bir platform.


      Dynamics CRM Microsoft tarafından çeşitli zamanlarda çıkartılan çeşitli service pack ve rollup paketleriyle genişlemekte ve yeni özellikler kazandırılmaktadır.

      Dynamics CRM mevcutta üç farklı çeşitte paketlenmektedir;

      • Microsoft Dynamics CRM 2013 on-premises deployment
      • Microsoft Dynamics CRM 2013 Internet-facing deployment (IFD)
      • Microsoft Dynamics CRM Online

      Bu üç çeşitte de aşağıdaki şekillerde son kullanıcı arabirimi sunmaktadır;

      • Microsoft Dynamics CRM Web client
      • Microsoft Dynamics CRM for Microsoft Office Outlook
      • Microsoft Dynamics CRM for Microsoft Office Outlook with Offline Access
      • Microsoft Dynamics CRM for phones and tablets

      Yani siz Dynamics CRM’i şirketiniz için kullanmaya başladıktan sonra isterseniz Internet Explorer, Chrome, Safari gibi browserlardan sisteme girebilir isterseniz de cep telefonu ya da Outlook üzerinden de kullanabilirsiniz.

      Oluşturduğunuz uygulamaları Dynamics CRM ile Web Servisleri aracılığıyla entegre edebilirsiniz. Bu web servisleri arka tarafta Dynamics CRM’in kalbi olan xRM platform katmanı ile iletişim halinde bulunmaktadır.

      Bu katmanda güvenlik gibi genel kısımları içermektedir ve bir uygulamanın çalışması için gerekli olan yapı taşlarını içerir fakat kendisi ilgili nesnelerinin bir koleksiyonun başka bir şey değildir. Nesneler arasındaki iletişimi sağlar ve tekliften siparişe, siparişten faturaya gibi fiyatlandırma mantığı gibi daha genişletilebilir bir mantığı uygulamak için kullanılır.

      XRM platformu ayrıca, güvenlik yoluyla verilere ve veritabanına erişimi denetler. Ayrıca iş akışı ve özel iş mantığı uygulamaları (plugins) için süreçlerinin tetiklenmesini denetler. Bu katman Microsoft Exchange Server üzerinden gelen ve giden e-posta işleme alır.

      Microsoft Dynamics CRM 2013 'de FetchXML ile Aggregate(Toplama Sorguları) İşlemleri

      Bir önceki makalede FetchXML ile neler yapabileceğimize değindik. (Buraya tıklayarak o makaleye ulaşabilirsiniz) Eğer istersek FetchXML ile grouping ve aggregate işlemlerini de yapabilmekteyiz. FetchXML ile aşağıdaki işlemler desteklenmektedir;

      ·         sum

      ·         avg

      ·         min

      ·         max

      ·         count(*)

      ·         count(attribute name)

       

      Aggregate yapabileceğimiz sorgu örneği standart olarak bildiğimiz fetchXML kurgusundan farklı değil burada sadece attribute kısmında aggregate ile ilgili keyword yer almakta. Aggregate=true diyerek bu şekilde bir sorgulama yapacağımızı sisteme söylüyoruz. Sonrasında ise sırasıyla hangi alan üzerinden işlem yapılacağını, alias yani etiketin ne olacağını ve aggregate türümüzün ne olacağını sisteme söylüyoruz.

      <fetch distinct='false' mapping='logical' aggregate='true'>

        <entity name='opportunity'>

          <attribute name='name' alias='opportunity_count' aggregate='count'/>

        </entity>

      </fetch>

      Bu şekilde oluşturduğumuz bir sorgu ile aslında şunu demek istiyoruz : “select count('name') as opportunity_count from opportunity” yani standart bir count işleminden fazlası değil yaptığımız.

       

      Bu fetchXML’i çalıştırmak için ise aşağıdaki gibi bir kod hazırladım;

       

      string opportunity_count = @" <fetch distinct='false' mapping='logical' aggregate='true'>

                                                      <entity name='opportunity'>

                                                          <attribute name='name' alias='opportunity_count' aggregate='count'/>

                                                      </entity>

                                                    </fetch>";

       

                      EntityCollection opportunity_count_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(opportunity_count));

       

                      foreach (var c in opportunity_count_result.Entities)

                      {

                          Int32 aggregate2 = (Int32)((AliasedValue)c["opportunity_count"]).Value;

                          System.Console.WriteLine("Count of all opportunities: " + aggregate2);

                      }

       

      Burada dikkat edilmesi gereken nokta geriye EntityCollection döndürmesi. Bir önceki makalemden hatırlarsanız normalde bu tarz sorgulama ile biz geriye account, contact gibi sitem içerisindeki nesnelerden oluşmuş bir dizi alıyoruz. FetchXML yapısı gereği tek bir metod kullanıyoruz ve bu metod sonucunda yukarıdaki örnekte olduğu gibi tek bir satır dahi dönecek olsa bile yine sonucu bir collection içerisinde almaktayız. Bu nedenle mecbur foreach içerisinde dönüyoruz ya da collection’un 0. üyesini alıyoruz. Ben örneğimde foreach ile collection içinde döndüm ve gördüğünüz gibi değeri aldım.

       

      Yine bir önceki makalemde ileri düzey sorgular bölümünde anlattığım gibi eğer nesne üzerinden direkt bir değer döndürmeyeceksek sonuç her zaman AliasedValue olarak gelmekte. işte bu nedenden dolayı şu şekilde bir convert işlemi yapıyoruz;

       

      Int32 aggregate2 = (Int32)((AliasedValue)c["opportunity_count"]).Value

       

      Bu işlem sonucunda bu koddan aşağıdaki gibi çıktımızı alabiliyoruz.

       

       

      Eğer distinct yapmak istersek de fetchXML içerisine yerleştireceğimiz bir distinct=”true” ifadesiyle ile sisteme bunu beliretebiliriz.

      Aşağıda ise distinct yapılmış bir kod örneği bulunmakta;

       

      <fetch distinct='false' mapping='logical' aggregate='true'>

        <entity name='opportunity'>

          <attribute name='name' alias='opportunity_distcount' aggregate='countcolumn' distinct='true'/>

        </entity>

      </fetch>

       

      Bu FetxhXML’i de aşağıdaki kodla çalıştırabiliriz.

       

                      string opportunity_distcount = @"

                                                 <fetch distinct='false' mapping='logical' aggregate='true'>

                                                     <entity name='opportunity'>

                                                        <attribute name='name' alias='opportunity_distcount' aggregate='countcolumn' distinct='true'/>

                                                     </entity>

                                                 </fetch>";

       

                      EntityCollection opportunity_distcount_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(opportunity_distcount));

       

                      foreach (var c in opportunity_distcount_result.Entities)

                      {

                          Int32 aggregate4 = (Int32)((AliasedValue)c["opportunity_distcount"]).Value;

                          System.Console.WriteLine("Distinct name count of all opportunities: " + aggregate4);

                      }

       

                      Console.ReadLine();

       

      Bu kod sonucunda da aşağıdaki gibi bir cevap alabiliriz sistemden;


       

      Gelin olayı biraz renklendirelim. Bu sefer de bir sorgu içerisinde birden fazla aggregate seçeneğinin cevabını isteyelim. Böyle bir işlem için standart fetchXML’in içerisinde sırasıyla hangi özelliklerin bize geri döneceğini belirtiyoruz tabii unutulmaması gereken nokta ise hepsi için ayrı birer alias olması gerektiğidir.

       

      <fetch distinct='false' mapping='logical' aggregate='true'>

        <entity name='opportunity'>

          <attribute name='opportunityid' alias='opportunity_count' aggregate='count'/>

          <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum'/>

          <attribute name='estimatedvalue' alias='estimatedvalue_avg' aggregate='avg'/>

        </entity>

      </fetch>

       

      Bu sorgu için ise aşağıdaki kodu hazırladım;

       

                      string estimatedvalue_avg2 = @"

                                          <fetch distinct='false' mapping='logical' aggregate='true'>

                                              <entity name='opportunity'>

                                                 <attribute name='opportunityid' alias='opportunity_count' aggregate='count'/>

                                                 <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum'/>

                                                 <attribute name='estimatedvalue' alias='estimatedvalue_avg' aggregate='avg'/>

                                              </entity>

                                          </fetch>";

       

                      EntityCollection estimatedvalue_avg2_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(estimatedvalue_avg2));

       

                      foreach (var c in estimatedvalue_avg2_result.Entities)

                      {

                          Int32 aggregate8a = (Int32)((AliasedValue)c["opportunity_count"]).Value;

                          System.Console.WriteLine("Count of all opportunities: " + aggregate8a);

                          decimal aggregate8b = ((Money)((AliasedValue)c["estimatedvalue_sum"]).Value).Value;

                          System.Console.WriteLine("Sum of estimated value of all opportunities: " + aggregate8b);

                          decimal aggregate8c = ((Money)((AliasedValue)c["estimatedvalue_avg"]).Value).Value;

                          System.Console.WriteLine("Average of estimated value of all opportunities: " + aggregate8c);

       

                      }

       

                      Console.ReadLine();

       

      İşte bu şekilde aynı anda count, sum ve avg işlemlerini yapabilmekteyim. Sonuç ise aşağıdaki gibi;

       

       

      Bu iki makalede FetchXML’ler üzerinde konuştuk. Umarım faydalı olmuştur.

      CRM 2013 Quick Start - Jumpstart your CRM 2013 learning curve

      I would like to introduce a new CRM book which you can access ebook version from that website www.crm2013quickstart.com

      Discount: JulieYackCRMQuickStartEBook (20% off the ebook)

      The CRM 2013 Quick Start is a first look at Microsoft Dynamics CRM 2013 and all the new features that have been included. 

      In the CRM 2013 Quick Start you will find details that can help administrators, customizers (functional consultants) and developers; not to mention power business users wanting to know all the details the admin never tells them. If you run CRM in the cloud or sitting in a server room at your office the information is useful. 

      This book is targeted to someone who has some CRM prior experience. By that we simply don’t spend any time explaining the basics of Microsoft Dynamics CRM from a beginner’s point of view. That said, the information in this book would still be useful on your journey to become proficient. 

      Chapter 1 - Hello I’m CRM 2013

      Microsoft Dynamics CRM 2013 is a major release building on the strong foundation of CRM 2011. From the user experience to platform capabilities CRM 2013 has changes that are targeted for everyone as users, customizers, IT Pros, and developers. In this chapter we give you a 50,000 foot tour of what’s new.

      Chapter 2 – The User Experience

      Before you can build solutions in CRM 2013 you should learn how the new user experience works. In this chapter we will dive into the new experience and break down all the key changes so you are ready to start thinking about customizing it.

      Chapter 3 – Customizing CRM Forms

      The 2013 user experience requires rethinking how we customize forms. From the new layout options, new controls and even new form types we have a lot to talk about. We also can’t forget you might have CRM 2011 forms and want to know how to move them forward into this release.

      Chapter 4 – Security Model Changes

      Today’s global business challenges the traditional organization structure as people form dynamic teams to work on individual opportunities or other data in CRM. CRM 2013 addresses that with Access Teams which challenge past thinking of how to handle these types of needs. In this chapter we will explore the new feature and discuss how and when to use the different CRM security concepts.

      Chapter 5 – Building Business Processes

      To consistently bake good cookies people often times use their favorite recipe. The Business Process feature of CRM 2013 brings that to CRM allowing you to bake in a business process into the life cycle of a CRM record. In fact you can even blur the lines of multiple CRM entities and have a business process cross the entity boundaries reflecting more real-world business processes. In this chapter we look at the features and how to leverage them to improve user productivity and consistency.

      Chapter 6 – No Code Business Rules

      Portable Business Rules, or PBL for short, offer a declarative way to define business rules. This new feature represents the start of a journey to a common need of having simple rules like “This field is required”. In this chapter we will explore the capability of PBL and when to use it versus other concepts in CRM that can enforce business rules.

      Chapter 7 – Real Time Workflows

      Workflows offer an easy way to compose flexible business processes that can optionally include custom code created by a developer. Prior to CRM 2013 these had to run asynchronously in the background and never could happen in real time. This caused a lot of plug-ins to be built to handle the requirement. New in CRM 2013 is real time workflows that can allow processing of events real time. In this chapter we discuss when and how to use the new feature.

      Chapter 8 – Upgrading to CRM 2013

      Next, Next, Next…Done… If it was only that easy it would be an automated upgrade. In this chapter we explore what you should consider before you upgrade and how to prepare.

      Chapter 9 – Solutions going forward

      As the pace of CRM releases increases, understanding how to package and deploy solutions becomes increasingly important. In this chapter we will discuss changes to the Solution Framework and how to prepare for the bold new world of frequent CRM releases.

      Chapter 10 – Taking CRM on the Road

      There is no question Microsoft was behind in mobile applications for CRM but came back strong with the introduction of the new tablet application for IPad and Windows. Learn how this fits in with the customizations you are doing to CRM and limitations you should be aware of in this first generation release. This chapter will also cover Outlook enhancements and Server Sync that in many scenarios will free the deployment from having an E-mail router.

      Chapter 11 – Developers, Developers, and Developers

      This release doesn’t have huge new API changes but it does have a lot of small useful changes across the different parts of the developer features. In this chapter we will explore from oAuth authentication support to Custom Actions and all the little changes between them.