Dynamics CRM 2011 の IOrganizationService を使用したLate Binding によるレコードの操作のサンプルを掲載します。使用できるメソッドやリクエストの種類の一覧については、下記リンクを参照してください。
Organization Service Methods
http://technet.microsoft.com/en-us/library/gg328198.aspx
xRM Messages in the Organization Service
http://technet.microsoft.com/en-us/library/gg334698.aspx
CRM Messages in the Organization Service
http://technet.microsoft.com/en-us/library/gg309482.aspx
OrganizationRequest を使用する場合は、重複レコードの登録・更新を行うかや、メタデータ操作時にソリューションを指定するなどオプションパラメータが指定できます。 詳細は下記のリンク参照
Use Messages (Request and Response Classes) with the Execute Method
http://technet.microsoft.com/en-us/library/gg328075.aspx
今回は、 OrganizationServiceProxy を使用して、レコードの簡単なCRUD操作のサンプルを掲載します。OrganizationRequest を継承した CRUD用のRequest クラスを使用した CRUD のサンプルも掲載します。
動作環境
- Windows Server 2008 R2 上に構築したオールインワンのDynamics CRM 2011 UR 3
- Visual Studio 2010 Professional
1. プロジェクトのセットアップ
Visual Studio を起動し、コンソール用のプロジェクトを新規作成します。必要なdllの参照設定は、[Dynamics CRM 2011]遅延バインディング(Late Binding) でCRM Webサービス に接続するを参照してください。
2.IOrganizationServiceを使用したレコードのCRUDサンプルプログラム
IOrganizationServiceの Retrieve, Create, Delete, RetrieveMultiple, Update メソッドを使用したサンプル(CRUDContactメソッド)とOrganizationRequest を使用したサンプル(CRUDContactWithOrganizationRequest) を掲載します。サンプルでは所属企業の上司にハードコードでGUIDを設定しているので、サンプルを動作させる場合は、コメントにするが、環境に実在するレコードのGUIDを設定してください。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk;
using System.ServiceModel;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
namespace LateBindingSample04
{
class Program
{
static void Main(string[] args)
{
using (OrganizationServiceProxy service = GetOrganizationService("crmsvr01", "org01"))
{
try
{
// コンタクトの操作
CRUDContact(service);
//CRUDContactWithOrganizationRequest(service);
}
catch (TimeoutException)
{
Console.WriteLine("Timeout");
}
catch (FaultException<OrganizationServiceFault> fe)
{
Console.WriteLine("FaultException<OrganizationServiceFault>");
Console.WriteLine(fe.Detail.Message);
}
catch (FaultException)
{
Console.WriteLine("FaultException");
}
catch (Exception ex)
{
Console.WriteLine("Exception");
Console.WriteLine(ex.Message);
}
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
}
/// <summary>
/// contact エンティティを作ったり削除したり検索したり更新したり状態変更したり
/// </summary>
/// <param name="service"></param>
public static void CRUDContact(IOrganizationService service)
{
// 取引先担当者の作成 Create
Entity contact1 = new Entity("contact");
// string
contact1["firstname"] = "名1";
contact1["lastname"] = "コンタクトの姓";
// 通貨
contact1["annualincome"] = new Money(10000000m);
// OptionSet
contact1["accountrolecode"] = new OptionSetValue(2); // 会社員
Guid contact1id = service.Create(contact1);
// 単一レコードを取得 Retrieve
// 全フィールドを検索.実際には必要なフィールドのみ指定すること
contact1 = service.Retrieve("contact", contact1id, new ColumnSet(true));
// 更新 Update
// 値がnullかのチェック。ContainsKeyなどでもチェックできそう
if (contact1.GetAttributeValue<Money>("creditlimit") == null)
{
contact1.Attributes["creditlimit"] = new Money(2010);
}
if (contact1.GetAttributeValue<double?>("address1_latitude") == null)
{
// Do nothing
}
// 年収を更新
contact1["annualincome"] = new Money(9999m);
contact1.Attributes.Remove("annualincome"); // 更新取り消し
contact1.Attributes["lastname"] = null; //null値で更新
// customer(所属取引先企業/上司)の設定(Lookupも同じ)
contact1.Attributes["parentcustomerid"] = new EntityReference("account", new Guid("F718680D-4BFA-E011-85FA-00155D0A0B14"));
service.Update(contact1);
contact1 = service.Retrieve("contact", contact1id, new ColumnSet(true));
// 取引先担当者の非アクティブ化 Execute (SetStateRequest)
contact1 = new Entity("contact");
SetStateRequest setstateRequest = new SetStateRequest();
setstateRequest.EntityMoniker = new EntityReference("contact", contact1id);
setstateRequest.State = new OptionSetValue(1);
setstateRequest.Status = new OptionSetValue(-1); // 既定のステータス
service.Execute(setstateRequest);
// 複数レコード検索 RetrieveMultiple
// QueryExpression や FetchExpressionでレコードを検索
QueryExpression query = new QueryExpression("contact");
query.Criteria.Filters.Add(new FilterExpression()
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("firstname", ConditionOperator.Equal, "名1")
}
});
query.ColumnSet = new ColumnSet("firstname", "lastname");
EntityCollection results = service.RetrieveMultiple(query);
foreach (var result in results.Entities)
{
Console.WriteLine("{0} {1}", result.GetAttributeValue<string>("firstname"), result.GetAttributeValue<string>("lastname"));
}
// 取引先担当者の削除 Delete
service.Delete("contact", contact1id);
// NN関連を設定する場合は Associate, Disassociate を使用する
}
/// <summary>
/// OrganizationRequest を使用して、contact エンティティを作ったり
/// 削除したり検索したり更新したり状態変更したり
/// </summary>
/// <param name="service"></param>
public static void CRUDContactWithOrganizationRequest(IOrganizationService service)
{
// 取引先担当者の作成 CreateRequest
Entity contact1 = new Entity("contact");
// string
contact1["firstname"] = "名2";
contact1["lastname"] = "コンタクトの姓";
// 通貨
contact1["annualincome"] = new Money(10000000m);
// OptionSet
contact1["accountrolecode"] = new OptionSetValue(2); // 会社員
CreateRequest createRequest = new CreateRequest()
{
Target = contact1
};
CreateResponse createResponse = service.Execute(createRequest) as CreateResponse;
Guid contact1id = createResponse.id;
// 単一レコードを取得 Retrieve
// 全フィールドを検索.実際には必要なフィールドのみ指定すること
RetrieveRequest retrieveRequest = new RetrieveRequest()
{
Target = new EntityReference("contact", contact1id),
ColumnSet = new ColumnSet(true)
};
RetrieveResponse retrieveResponse = service.Execute(retrieveRequest) as RetrieveResponse;
contact1 = retrieveResponse.Entity;
// 更新 Update
// 値がnullかのチェック。ContainsKeyなどでもチェックできそう
if (contact1.GetAttributeValue<Money>("creditlimit") == null)
{
contact1.Attributes["creditlimit"] = new Money(2010);
}
if (contact1.GetAttributeValue<double?>("address1_latitude") == null)
{
// Do nothing
}
// 年収を更新
contact1["annualincome"] = new Money(9999m);
contact1.Attributes.Remove("annualincome"); // 更新取り消し
contact1.Attributes["lastname"] = null; //null値で更新
// customer(所属取引先企業/上司)の設定(Lookupも同じ)
contact1.Attributes["parentcustomerid"] = new EntityReference("account", new Guid("F718680D-4BFA-E011-85FA-00155D0A0B14"));
UpdateRequest updateRequst = new UpdateRequest()
{
Target = contact1
};
UpdateResponse updateResponse = service.Execute(updateRequst) as UpdateResponse;
contact1 = service.Retrieve("contact", contact1id, new ColumnSet(true));
// 取引先担当者の非アクティブ化 Execute (SetStateRequest)
contact1 = new Entity("contact");
SetStateRequest setstateRequest = new SetStateRequest();
setstateRequest.EntityMoniker = new EntityReference("contact", contact1id);
setstateRequest.State = new OptionSetValue(1);
setstateRequest.Status = new OptionSetValue(-1); // 既定のステータス
service.Execute(setstateRequest);
// 複数レコード検索 RetrieveMultipleRequest
// QueryExpression や FetchExpressionでレコードを検索
QueryExpression query = new QueryExpression("contact");
query.Criteria.Filters.Add(new FilterExpression()
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("firstname", ConditionOperator.Equal, "名2")
}
});
query.ColumnSet = new ColumnSet("firstname", "lastname");
RetrieveMultipleRequest retrieveMultipleRequest = new RetrieveMultipleRequest()
{
Query = query,
};
RetrieveMultipleResponse retrieveMultipleResponse = service.Execute(retrieveMultipleRequest) as RetrieveMultipleResponse;
EntityCollection results = retrieveMultipleResponse.EntityCollection;
foreach (var result in results.Entities)
{
Console.WriteLine("{0} {1}", result.GetAttributeValue<string>("firstname"), result.GetAttributeValue<string>("lastname"));
}
// 取引先担当者の削除 DeleteRequest
DeleteRequest deleteRequest = new DeleteRequest()
{
Target = new EntityReference("contact", contact1id)
};
DeleteResponse deleteResponse = service.Execute(deleteRequest) as DeleteResponse;
}
/// <summary>
/// Crm On-Premise に接続する
/// </summary>
/// <param name="server">サーバー名</param>
/// <param name="orgname">組織名</param>
/// <returns>OrganizationServiceProxy のインスタンス</returns>
public static OrganizationServiceProxy GetOrganizationService(string server, string orgname)
{
string endpointaddress = string.Format("http://{0}/{1}/XRMServices/2011/Organization.svc", server, orgname);
OrganizationServiceProxy organizationService = new OrganizationServiceProxy(new Uri(endpointaddress), null,
new System.ServiceModel.Description.ClientCredentials(), null);
return organizationService;
}
}
}
3. まとめ
今回の説明は以上です。 Organization Service を使用すると、CRM 4.0 の CrmService や MetadataService と同様の操作が実現できます。
On-Premise環境で、port:443での接続する環境にAD接続出来なくて困ってます。
【接続URL】https://server:443/orgname/main.aspx
上記の構成では、下記の処理部分では、どのように記述すれば良いのかわからなくて困っています。参考になるサンプルなどございませんでしょうか?
【該当の箇所】
string endpointaddress = string.Format("http://{0}/{1}/XRMServices/2011/Organization.svc", server, orgname);
上記処理で、次のエラーが発生します。「メタデータに、解決できない参照が含まれています。'http://server/orgname/XRMServices/2011/Organization.svc?wsdl'。」
http → https にて、確認させて頂きましたが、現象は改善せずです。勉強不足で大変恐縮ですが、おすすめのデバッグ方法などが有りましたらご提示頂けますと幸いです。
ブラウザで、接続先「("https://{0}/{1}/XRMServices/2011/Organization.svc」の証明書をインポートする事で、接続できるようになりました。
「この Web サイトのセキュリティ証明書には問題があります。」と表示されていたのに、気づけませんでした。お騒がせしました。
ご教授ありがとうございます。