从 CRM 2011 插件调用 Web 服务



我创建了一个调用AX自定义Web服务的插件。 Web 服务应返回给定产品和客户的价格。

我可以在CRM之外毫无问题地调用Web服务,但是将其包含在插件中后,它停止了工作。

我收到的错误消息是:

在 ServiceModel 客户端配置部分找不到引用协定"AxIntegrationServices.PriceDiscService"的默认端点元素。这可能是因为找不到应用程序的配置文件,或者因为在客户端元素中找不到与此协定匹配的终结点元素。

这是代码:

//retrieve the entity product as the input Entity
var entity = (Entity)context.InputParameters["Target"];
//Early bound entity
var oppProduct = new opportunityproduct(entity);
var quantity = (Decimal)oppProduct.quantity;
tracingService.Trace("Retrieving Opp with opp ID = {0}", oppProduct.opportunityid.Id.ToString());
//get the early bound opportunity containing the opportunity product
var opp = new opportunity(Helper.ActualEntity(oppProduct.opportunityid, service));
//get the early bound account entity that is the customer for the opportunity
tracingService.Trace("Retrieved, type = {0}", opp.name);
tracingService.Trace("Retrieving Account with accountID={0}", opp.customerid.Id.ToString());
Entity acc = Helper.ActualEntity(opp.customerid, service);
tracingService.Trace("Account retrieved");
var account = new account(acc);
//get the ax integration key for the account
tracingService.Trace("Retrieving Account AX key");
var accountAxKey = account.custom_axrecordid;
tracingService.Trace("Retrieving Product");
//get the early bound account entity that is the customer for the opportunity
var product = new product(Helper.ActualEntity(oppProduct.productid, service, new string[]{ "custom_axrecordid" }));
//get the integration key for the product
tracingService.Trace("Retrieving Product AX key");
var productAxKey = product.custom_axrecordid;
tracingService.Trace("Invoking web service");
PriceDiscServiceClient priceDiscServiceClient = new PriceDiscServiceClient();
CallContext callContext = new CallContext();
priceDiscServiceClient.ClientCredentials.Windows.ClientCredential.UserName = "xxx";
priceDiscServiceClient.ClientCredentials.Windows.ClientCredential.Password = "yyyy!";
priceDiscServiceClient.ClientCredentials.Windows.ClientCredential.Domain = "aaa"; 

PriceDiscServiceContract priceDiscServiceContract = priceDiscServiceClient.getPriceDiscSales(callContext, productAxKey, accountAxKey, quantity);
tracingService.Trace("Price :{0}",priceDiscServiceContract.Price);
tracingService.Trace("Markup :{0}", priceDiscServiceContract.Markup);
tracingService.Trace("PriceUnit :{0}", priceDiscServiceContract.PriceUnit);
tracingService.Trace("DiscAmount :{0}", priceDiscServiceContract.DiscAmount);
tracingService.Trace("DiscPct :{0}", priceDiscServiceContract.DiscPct);
oppProduct.priceperunit = priceDiscServiceContract.PriceUnit;

oppProduct.isproductoverridden = false;
oppProduct.ispriceoverridden = true;

网络服务位于CRM环境的同一网络中,我正在通过VPN连接到它们。

有什么想法吗?

你应该检查你的PriceDiscServiceClient构造函数 - 它应该接受一个BindingEndpointAddress,所以你的代码可能看起来像这样:

//...
BasicHttpBinding binding = new BasicHttpBinding();
// configure Binding as needed (Timeout, etc.) ...
EndpointAddress endpoint = new EndpointAddress(endpointUri);
PriceDiscServiceClient client = new PriceDiscServiceClient(binding, endpoint);
//...

正如 James Wood 已经指出的那样,下一个问题将是用可配置的值填充endpointUri,而不是将其硬编码到您的插件中。

我倾向于更喜欢插件不安全的配置,而不是每次插件执行时往返 crm 设置记录。

James Wood 引用的链接正是我选择配置端点地址 Uri 的解决方案。

如果你的代码依赖于 app.config 中的配置,如 Filburt 建议的那样,那么这种方法不太可能奏效。将插件程序集添加到 MSCRM 时,不包括 app.config(它在单独的配置文件中)。

您将无法将 app.config 中的任何配置添加到 CRM app.config(因为它不受支持)。

我建议你在 app.config 上所做的任何事情都移动到插件本身的代码中。你在 app.config 中所做的任何事情,你也应该能够在代码中做。

如果需要检索设置值(例如连接字符串),则可能需要考虑使用 CRM 中的设置记录并检索该信息。或者使用插件配置部分。

最新更新