从CRM 2011插件调用Web服务

时间:2014-01-21 14:23:01

标签: c# wcf web-services dynamics-crm-2011

我创建了一个调用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;

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

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您应该检查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设置记录。

link James Wood refers to正是我选择配置端点地址Uri的解决方案。

答案 1 :(得分:2)

如果你的代码依赖于app.config中的配置,就像Filburt所建议的那样,这种方法不太可行。将插件程序集添加到MSCRM时,不包含app.config(它位于单独的配置文件中)。

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

我会建议你在app.config上做什么,然后移植到插件本身的代码中。您在app.config中所做的任何事情都应该能够在代码中完成。

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