Dynamics CRM では 拡張用のアドオン(AddOn)は ISV フォルダ配下に配置されます。今回は WCF Ajax Web Service をアドオンから使用する方法を記載します。 さらにWCFサービスから Dynamics CRM Web サービスにアクセスします。同じ方法で ASP.NET Ajax も使用できると思います。今回の記事は、WCF Sample 026:静的コンテンツ(html)でWCF Ajax Web Service を利用する の内容を Dynamics CRM で使用できるように構成などを応用したものです。

動作確認環境

  • 動作環境: Dynamics CRM 4.0 Rollup 8
  • 開発環境: Visual Studio 2008 SP1
  • .NET 3.5 SP1

1. WCF サービスを作成する

最初に WCF Ajax Web Service 用の WCF サービスを作成します。機能としてはWCF Sample 017:WCF で AJAX Serviceを作成してみる。 で作成したものと同じサービスです。

1.1 プロジェクトの作成

WCF サービスをプロジェクトテンプレートとして、プロジェクトを作成します。プロジェクト名は WcfTest として説明を記述します。既定で作成されるIService1.cs, Service1.svc, Service.svc.cs を削除します。

1.1 PersonService サービスの作成

最初にモデルクラスを作成します。プロジェクトにPerson.cs というクラスを作成します。単純なデータ転送用のクラスです。

namespace WcfTest
{
    [DataContract]
    public class Person
    {
        public Person(int id, string firstname, string lastname)
        {
            ID = id;
            FirstName = firstname;
            LastName = lastname;
        }
        [DataMember]
        public int ID;
        [DataMember]
        public string FirstName = string.Empty;
        [DataMember]
        public string LastName = string.Empty;
    }
}

 

次に プロジェクトから新規項目を追加します。テンプレートにWCFサービスを選択肢、 PersonService を作成します。

サービスコントラクト IPersonService.cs を次のように編集します。

namespace WcfTest
{
    // メモ: ここでインターフェイス名 "IPersonService" を変更する場合は、Web.config で "IPersonService" への参照も更新する必要があります。
    [ServiceContract(Namespace="Wcf.PersonService")]
    public interface IPersonService
    {
        [OperationContract]
        [WebGet]
        IList<Person> GetPersons();

        [OperationContract]
        [WebGet]
        Person GetParsonByID(int id);
    }
}

サービスクラス PersonService.svc.cs を次のように編集します。GerPersons, GetParsenByID を実装しています。サンプルとして使用するために定義しています。

namespace WcfTest
{
    // メモ: ここでクラス名 "PersonService" を変更する場合は、Web.config で "PersonService" への参照も更新する必要があります。
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PersonService : IPersonService
    {
        private static IList<Person> _persons = new List<Person>();

        static PersonService()
        {
            _persons.Add(new Person(1, "AAaiueo", "AUIEO"));
            _persons.Add(new Person(2, "kakikukeko", "KAKIKUKEKO"));
            _persons.Add(new Person(3, "sashisuseso", "SASHISUSESO"));
        }
        #region IPersonService メンバ

        public IList<Person> GetPersons()
        {
            return _persons;
        }

        public Person GetParsonByID(int id)
        {
            using (new CrmImpersonator())
            {
                string orgname = "TA";
                CrmService service = GetCrmService(orgname);
                string fullname = GetFullName(service);

                return new Person(id, fullname, fullname);
            }
        }
        #endregion
        /// <summary>
        /// CrmService のインスタンスを作成する
        /// </summary>
        /// <param name="orgName">組織名</param>
        /// <returns>CrmService インスタンス</returns>
        private CrmService GetCrmService(string orgName)
        {

            CrmAuthenticationToken token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(HttpContext.Current, orgName);

            CrmService service = new CrmService();
            service.Credentials = System.Net.CredentialCache.DefaultCredentials;
            service.CrmAuthenticationTokenValue = token;
            return service;
        }
        /// <summary>
        /// systemuser の fullname を取得する
        /// </summary>
        /// <param name="service">処理を行うCrmService</param>
        /// <returns>ログインユーザのfullname</returns>
        private string GetFullName(CrmService service)
        {
            ColumnSet cols = new ColumnSet();

            cols.Attributes.Add("fullname");
            Guid systemuserGuid = service.CrmAuthenticationTokenValue.CallerId;

            systemuser su = (systemuser)service.Retrieve(EntityName.systemuser.ToString(), systemuserGuid, cols);

            return su.fullname;
        }

    }
}

1.3 Web.config の編集

WCF Ajax Web Service として動作するようにWeb.configを編集します。 behavior をenableWebScript に設定、 バインディングを webHttpBinding となるように設定を変更しています。WCFサービスから Crm Web Service にアクセスしているため、 aspNetCompatibilityEnabled を true にしています。

<system.serviceModel>
   <!-- コンパチビリティレベル -->
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  <services>
   <service behaviorConfiguration="WcfTest.PersonServiceBehavior"
    name="WcfTest.PersonService">
    <endpoint address="" behaviorConfiguration="AjaxBehavior" binding="webHttpBinding"
     contract="WcfTest.IPersonService" />
   </service>
  </services>
  <behaviors>
   <endpointBehaviors>
    <behavior name="AjaxBehavior">
     <enableWebScript />
    </behavior>
   </endpointBehaviors>
   <serviceBehaviors>
    <behavior name="WcfTest.PersonServiceBehavior">
     <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
   </serviceBehaviors>
  </behaviors>
<system.serviceModel />

2. html, ASPX から WCF Ajax Web Service を使用する

2.1 Microsoft ASP.NET Ajax Library をダウンロードしてプロジェクトに設定する

Microsoft Ajax Library を以下のサイトからダウンロードします。本記事では、 2009/11/17 stable 版をダウンロードして動作確認をしています。

- Microsoft ASP.NET Ajax Library (記事作成時点で最新版はASP.NET Ajax Library 0911 Beta,2009/11/17 stable)
http://ajax.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35895

- Microsoft ASP.NET AjaxLibrary (ASP.NET Ajax Extention 1.0 に該当をダウンロードする場合)
http://www.asp.net/ajax/downloads/library/ 

ダウンロードした zip ファイルを解凍して、Scriptsフォルダの MicrosoftAjax.js と MicrosoftAjaxWebForms.js を WCFサービスプロジェクトに js フォルダを作成しコピーします。プロジェクトに含めることを忘れないでください。

2.2 HTMLコンテンツを作成する

プロジェクトから新規html を作成します。Wcf.html というファイル名で作成します。次のように編集します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>WCF Ajax Web Service を html で使用する</title>
    <script type="text/javascript">
      function load() {
         var xmlreq = new XMLHttpRequest();
         xmlreq.open('GET', 'js/MicrosoftAjax.js', false);
         xmlreq.send('')
         eval(xmlreq.responseText);

         xmlreq = new XMLHttpRequest();
         xmlreq.open('GET', 'PersonService.svc/js', false);
         xmlreq.send('')
         eval(xmlreq.responseText);

         
         var proxy = new Wcf.PersonService.IPersonService();
         proxy.GetParsonByID(1, onSuccess, onFail, null);
      }
      function onSuccess(result){
        document.getElementById("txtId").value = result.ID;
        document.all.txtName.value = result.FirstName;
        // Microsoft AJAX Library 1.0 の MicrosoftAjax.js を使用する場合は
        // result.d.ID というように d が必要です。
        // document.getElementById("txtId").value = result.d.ID;
      }
      function onFail(result){
      }
    </script>
</head>
<body>
  <p>Dynamics CRM の ISV (html 静的コンテンツ)から、 WCF Ajax Web Service を呼び出す方法</p>
  <input id="txtId" type="text" />
  <input id="txtName" type="text" />
  <input id="btnId" type="button"  value="おして!!" onclick="javascript:load()" />
  <a href="WebForm1.aspx">LINK1</a>
  <a href="WebForm2.aspx">LINK2</a>
</body>
</html>

2.3 ASPX ファイルを作成する

次に、 ASPX から WCF Ajax Web Service を使用してみます。プロジェクトの新規作成で、 Webフォームを作成します。ファイル名をWebForm1.aspx とします。WebForm1.aspxを次のように編集します。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WcfTest.WebForm1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>インテグレーションその1</title>
    <script type="text/javascript" src="js/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="js/MicrosoftAjaxWebForms.js"></script>
    <script type="text/javascript" src="PersonService.svc/js"></script>
    <script type="text/javascript">
    
      function pageLoad() {
         var proxy = new Wcf.PersonService.IPersonService();
         proxy.GetParsonByID(1, onSuccess, onFail, null);
      }
      function onSuccess(result){
        $get("txtId").value = result.ID;
      }
      function onFail(result){
      }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>Dynamics CRM の ISV (aspx 動的コンテンツ)から、 WCF Ajax Web Service を呼び出す方法その1</p>
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:Label runat="server" ID="lblId" Text="ID" />
        <asp:TextBox runat="server" ID="txtId" ReadOnly="true" />
    </div>
    </form>
</body>
</html>

別の方法で ASPX から WCF Ajax Web Service を使用します。プロジェクトの新規作成で、WebForm2.aspx という名前でWebForm2.aspx を作成し次のように編集します。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WcfTest.WebForm2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Dynamics CRM WCF インテグレーション</title>

    <script type="text/javascript">
      function load() {
         var xmlreq = new XMLHttpRequest();
         xmlreq.open('GET', '/ISV/WcfTest/js/MicrosoftAjax.js', false);
         xmlreq.send('')
         eval(xmlreq.responseText);

         xmlreq = new XMLHttpRequest();
         xmlreq.open('GET', '/ISV/WcfTest/PersonService.svc/js', false);
         xmlreq.send('')
         eval(xmlreq.responseText);

         var proxy = new Wcf.PersonService.IPersonService();
         proxy.GetParsonByID(1, onSuccess, onFail, null);
      }
      function onSuccess(result){
        document.getElementById("txtId").value = result.ID;
        document.all.txtName.value = result.FirstName;
      }
      function onFail(result){
      }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>Dynamics CRM の ISV (aspx 動的コンテンツ)から、 WCF Ajax Web Service を呼び出す方法その2</p>
        <input id="txtId" type="text" />
        <input id="txtName" type="text" />
        <input id="btnId" type="button" value="おして!!" onclick="javascript:load()" />
    </div>
    </form>
</body>
</html>

3. 動作結果

AddOnとして追加した動作結果です。静的ページでWCFサービスを呼び出した結果です。

LINK1, LINK2 を選択して、WebForm1.aspx, WebForm2.aspx を表示し、 WCFサービス呼び出した結果を表示します。

表示結果は味気ないですが、WCF Ajax Web Service を呼び出すことができるようになります。

4. まとめ

今回は以上です。 ISV配下にデプロイしたhtml や aspx のアドオンからWCF Ajax Web Service を使用する方法を記載しました。

Dynamics CRMのエンティティ用のフォームに WCF Ajax Web Service を統合する場合は次のリンクが参考になると思います。紹介した方法と同じように、実行時にjsファイルを評価してWCF Ajax Web Service を使用できるようにしています。

CRM WCF Integration
http://waelhamze.com/blog/crm/crm-wcf-integration/