範例:REST 接聽程式
發行︰ 2017年1月
適用於: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online
這個範例程式碼適用於 Microsoft Dynamics 365 (線上和內部部署)。下載 Microsoft Dynamics CRM SDK 套件。 您可以在下列下載套件找到此程式碼:
SDK\SampleCode\CS\Azure\RestListenere\RestListener.cs
需求
您必須在註冊和執行此範例活動之前設定 Microsoft Dynamics 365 與 Microsoft Azure 整合。
示範
此範例將說明如何撰寫 REST 端點合約的 Microsoft Azure 服務匯流排 接聽程式。
此範例會註冊遠端服務外掛程式,該外掛程式會在 Microsoft Dynamics 365 訊息張貼至服務匯流排上的 REST 端點時執行。 當外掛程式執行時,它會將訊息中所包含 Microsoft Dynamics 365 執行內容的內容列印至主控台。
範例
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
// This namespace is found in the Microsoft.Xrm.Sdk.dll assembly
// found in the SDK\bin folder.
using Microsoft.Xrm.Sdk;
// This namespace is found in Microsoft.ServiceBus.dll assembly
// found in the Windows Azure SDK
using Microsoft.ServiceBus;
namespace Microsoft.Crm.Sdk.Samples
{
/// <summary>
/// Creates a REST endpoint listening for messages from the Windows Azure Service Bus.
/// </summary>
public class RestListener
{
#region How-To Sample Code
/// <summary>
/// The Execute method is called when a message is posted to the Azure Service
/// Bus.
/// </summary>
[ServiceBehavior]
private class RestServiceEndPoint : IWebHttpServiceEndpointPlugin
{
#region IRestServiceEndpointPlugin Member
/// <summary>
/// This method is called when a message is posted to the Azure Service Bus.
/// </summary>
/// <param name="context">Data for the request.</param>
/// <returns>A 'Success' string.</returns>
public string Execute(RemoteExecutionContext context)
{
Utility.Print(context);
return "Success";
}
#endregion
}
/// <summary>
/// Prompts for required information and hosts a service until the user ends the
/// session.
/// </summary>
public void Run()
{
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
Console.Write("Enter your Azure service namespace: ");
string serviceNamespace = Console.ReadLine();
// The service namespace issuer name to use. If one hasn't been setup
// explicitly it will be the default issuer name listed on the service
// namespace.
Console.Write("Enter your service namespace issuer name: ");
string issuerName = Console.ReadLine();
// Issuer secret is the Windows Azure Service Bus namespace current management key.
Console.Write("Enter your service namespace issuer key: ");
string issuerKey = Console.ReadLine();
// Input the same path that was specified in the Service Bus Configuration dialog
// when registering the Azure-aware plug-in with the Plug-in Registration tool.
Console.Write("Enter your endpoint path: ");
string servicePath = Console.ReadLine();
// Leverage the Azure API to create the correct URI.
Uri address = ServiceBusEnvironment.CreateServiceUri(
Uri.UriSchemeHttps,
serviceNamespace,
servicePath);
Console.WriteLine("The service address is: " + address);
// Create the shared secret credentials object for the endpoint matching the
// Azure access control services issuer
var sharedSecretServiceBusCredential = new TransportClientEndpointBehavior()
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerKey)
};
// Using an HTTP binding instead of a SOAP binding for this RESTful endpoint.
WebHttpRelayBinding binding = new WebHttpRelayBinding();
binding.Security.Mode = EndToEndWebHttpSecurityMode.Transport;
// Create the service host for Azure to post messages to.
WebServiceHost host = new WebServiceHost(typeof(RestServiceEndPoint));
host.AddServiceEndpoint(typeof(IWebHttpServiceEndpointPlugin), binding, address);
// Create the ServiceRegistrySettings behavior for the endpoint.
var serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);
// Add the service bus credentials to all endpoints specified in configuration.
foreach (var endpoint in host.Description.Endpoints)
{
endpoint.Behaviors.Add(serviceRegistrySettings);
endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
}
// Begin listening for messages posted to Azure.
host.Open();
Console.WriteLine(Environment.NewLine + "Listening for messages from Azure" +
Environment.NewLine + "Press [Enter] to exit");
// Keep the listener open until Enter is pressed.
Console.ReadLine();
Console.Write("Closing the service host...");
host.Close();
Console.WriteLine(" done.");
}
/// <summary>
/// Containts methods to display the RemoteExecutionContext provided when a
/// message is posted to the Azure Service Bus.
/// </summary>
private static class Utility
{
/// <summary>
/// Writes out the RemoteExecutionContext to the Console.
/// </summary>
/// <param name="context"></param>
public static void Print(RemoteExecutionContext context)
{
Console.WriteLine("----------");
if (context == null)
{
Console.WriteLine("Context is null.");
return;
}
Console.WriteLine("UserId: {0}", context.UserId);
Console.WriteLine("OrganizationId: {0}", context.OrganizationId);
Console.WriteLine("OrganizationName: {0}", context.OrganizationName);
Console.WriteLine("MessageName: {0}", context.MessageName);
Console.WriteLine("Stage: {0}", context.Stage);
Console.WriteLine("Mode: {0}", context.Mode);
Console.WriteLine("PrimaryEntityName: {0}", context.PrimaryEntityName);
Console.WriteLine("SecondaryEntityName: {0}", context.SecondaryEntityName);
Console.WriteLine("BusinessUnitId: {0}", context.BusinessUnitId);
Console.WriteLine("CorrelationId: {0}", context.CorrelationId);
Console.WriteLine("Depth: {0}", context.Depth);
Console.WriteLine("InitiatingUserId: {0}", context.InitiatingUserId);
Console.WriteLine("IsExecutingOffline: {0}", context.IsExecutingOffline);
Console.WriteLine("IsInTransaction: {0}", context.IsInTransaction);
Console.WriteLine("IsolationMode: {0}", context.IsolationMode);
Console.WriteLine("Mode: {0}", context.Mode);
Console.WriteLine("OperationCreatedOn: {0}", context.OperationCreatedOn.ToString());
Console.WriteLine("OperationId: {0}", context.OperationId);
Console.WriteLine("PrimaryEntityId: {0}", context.PrimaryEntityId);
Console.WriteLine("OwningExtension LogicalName: {0}", context.OwningExtension.LogicalName);
Console.WriteLine("OwningExtension Name: {0}", context.OwningExtension.Name);
Console.WriteLine("OwningExtension Id: {0}", context.OwningExtension.Id);
Console.WriteLine("SharedVariables: {0}", (context.SharedVariables == null
? "NULL" : SerializeParameterCollection(context.SharedVariables)));
Console.WriteLine("InputParameters: {0}", (context.InputParameters == null
? "NULL" : SerializeParameterCollection(context.InputParameters)));
Console.WriteLine("OutputParameters: {0}", (context.OutputParameters == null
? "NULL" : SerializeParameterCollection(context.OutputParameters)));
Console.WriteLine("PreEntityImages: {0}", (context.PreEntityImages == null
? "NULL" : SerializeEntityImageCollection(context.PreEntityImages)));
Console.WriteLine("PostEntityImages: {0}", (context.PostEntityImages == null
? "NULL" : SerializeEntityImageCollection(context.PostEntityImages)));
Console.WriteLine("----------");
}
/// <summary>
/// Writes out the attributes of an entity.
/// </summary>
/// <param name="e">The entity to serialize.</param>
/// <returns>A human readable representation of the entity.</returns>
private static string SerializeEntity(Entity e)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0} LogicalName: {1}{0} EntityId: {2}{0} Attributes: [",
Environment.NewLine,
e.LogicalName,
e.Id);
foreach (KeyValuePair<string, object> parameter in e.Attributes)
{
sb.AppendFormat("{0}: {1}; ", parameter.Key, parameter.Value);
}
sb.Append("]");
return sb.ToString();
}
/// <summary>
/// Flattens a collection into a delimited string.
/// </summary>
/// <param name="parameterCollection">The values must be of type Entity
/// to print the values.</param>
/// <returns>A string representing the collection passed in.</returns>
private static string SerializeParameterCollection(ParameterCollection parameterCollection)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, object> parameter in parameterCollection)
{
Entity e = parameter.Value as Entity;
if (e != null)
{
sb.AppendFormat("{0}: {1}", parameter.Key, SerializeEntity(e));
}
else
{
sb.AppendFormat("{0}: {1}; ", parameter.Key, parameter.Value);
}
}
return sb.ToString();
}
/// <summary>
/// Flattens a collection into a delimited string.
/// </summary>
/// <param name="entityImageCollection">The collection to flatten.</param>
/// <returns>A string representation of the collection.</returns>
private static string SerializeEntityImageCollection(EntityImageCollection entityImageCollection)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, Entity> entityImage in entityImageCollection)
{
sb.AppendFormat("{0}{1}: {2}", Environment.NewLine, entityImage.Key,
SerializeEntity(entityImage.Value));
}
return sb.ToString();
}
}
#endregion How-To Sample Code
/// <summary>
/// Standard Main() method used by most SDK samples.
/// </summary>
static public void Main()
{
try
{
RestListener app = new RestListener();
app.Run();
}
catch (FaultException<ServiceEndpointFault> ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Message: {0}", ex.Detail.Message);
Console.WriteLine("Inner Fault: {0}",
null == ex.InnerException.Message ? "No Inner Fault" : "Has Inner Fault");
}
catch (System.TimeoutException ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Message: {0}", ex.Message);
Console.WriteLine("Stack Trace: {0}", ex.StackTrace);
Console.WriteLine("Inner Fault: {0}",
null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message);
}
catch (System.Exception ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine(ex.Message);
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
FaultException<ServiceEndpointFault> fe = ex.InnerException
as FaultException<ServiceEndpointFault>;
if (fe != null)
{
Console.WriteLine("Message: {0}", fe.Detail.Message);
Console.WriteLine("Inner Fault: {0}",
null == ex.InnerException.Message ? "No Inner Fault" : "Has Inner Fault");
}
}
}
finally
{
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
}
}
}
另請參閱
IWebHttpServiceEndpointPlugin
設定 Azure 與 Microsoft Dynamics 365 整合
Microsoft Dynamics 365 和 Microsoft Azure 整合的範例程式碼
範例:持續性佇列接聽程式
Microsoft Dynamics 365
© 2017 Microsoft. 著作權所有,並保留一切權利。 著作權