我创建了一个调用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连接它们。
有什么想法吗?
答案 0 :(得分:3)
您应该检查PriceDiscServiceClient
构造函数 - 它应该接受Binding
和EndpointAddress
,因此您的代码可能如下所示:
//...
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。