2015-11-23 1 views
1

Привет У меня есть 2013 плагин CRM, который вызывает службу WCF, служба выдает следующее сообщение об ошибке:CRM Dynamics Вызов службы WCF Ошибка

'The communication object, System.ServiceModel.ChannelFactory`1[ISupplyClaimsService], cannot be modified while it is in the Opening state',

Я также иногда получаем, что при звонке на службу , сработает инструмент регистрации плагинов. Можно ли вызвать службу WCF из плагина? Я вижу некоторые сообщения на нем в Интернете, но никакого конкретного рабочего решения нет, даже в CRM SDK. Мой CRM находится на территории 2013 года, плагин зарегистрирован из изоляции Sandbox (NONE), служба WCF использует именованный домен, а не IP-адрес, его прогоняет HTTP-протокол, см. Мой код ниже. Я выполнил все требования в отношении плагинов и внешних систем, но до сих пор не повезло. Я также протестировал сервис в консольном приложении, SOAP UI работает нормально, только в Плагине у меня возникают проблемы.

public void Execute(IServiceProvider serviceProvider) 
    { 
     ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); 
     IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); 

     if (context == null) 
     { 
      throw new ArgumentNullException("loaclContext"); 
     } 

     if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) 
     { 
      Entity supplyClaimsEntity = (Entity)context.InputParameters["Target"]; 

      if (supplyClaimsEntity.LogicalName != "new_supplierclaimsupdate") 
      { 
       return; 
      } 

      IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 

      IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId); 

      string entityBeginUpload = "Start Upload"; 
      try 
      { 
       BasicHttpBinding myBinding = new BasicHttpBinding(); 
       myBinding.Name = "BasicHttpBinding_ISupplyClaimsService"; 
       myBinding.Security.Mode = BasicHttpSecurityMode.None; 
       myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; 
       myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; 
       myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; 

       EndpointAddress endPointAddress = new EndpointAddress(@"http://wmvapps01.tarsus.co.za/SupplyClaimsService.svc"); 

       ChannelFactory<ISupplyClaimsService> factory = new ChannelFactory<ISupplyClaimsService>(myBinding, endPointAddress); 
       ISupplyClaimsService channel = factory.CreateChannel(); 

       channel.StartApplication(); 
       factory.Close(); 


      } 
+0

Обычно этот тип ошибки из-за гонки состояние и многопоточность. Вы сохраняете что-либо в статических переменных в своем плагине? – Daryl

+0

Вы пробовали этот код в консольном приложении? –

+0

Вы также можете добавить инструкцию using, если заводская или поддержка канала IDisposible. – Daryl

ответ

1

У меня есть WCF Rest WebService, которые имеют Rest method. WebService код:

public interface ICRMRestWebService 
{ 
[OperationContract] 
[WebInvoke(Method = "POST", 
RequestFormat = WebMessageFormat.Json,  
ResponseFormat = WebMessageFormat.Json, 
BodyStyle = WebMessageBodyStyle.WrappedRequest, 
UriTemplate = "GetLatestContractByContactIdRestMethod")] 
LatestMembershipResponse GetLatestContractByContactIdRestMethod(string contactId, AuthenticateRequest authenticateRequest); 
} 

Web.config из WCF Rest WebService is:

<system.serviceModel> 
<services> 
    <service name="GRID.CRM.WebServices.CRMRestWebService.CRMRestWebService" behaviorConfiguration="ServiceBehaviour"> 
    <endpoint address="" binding="webHttpBinding" contract="GRID.CRM.WebServices.CRMRestWebService.ICRMRestWebService" behaviorConfiguration="web"> 
    </endpoint> 
    </service> 
</services> 
<bindings /> 
<client /> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="ServiceBehaviour"> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehaviors> 
    <endpointBehaviors> 
    <behavior name="web"> 
     <webHttp/> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" /> 

Я называю этот метод из CRM Plugin, как показано ниже:

public void Execute(IServiceProvider serviceProvider) 
    { 
    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); 
    IOrganizationServiceFactory serviceFactory; 
    IOrganizationService service; 
    if (context.Depth > 1) 
      return; 

    if (context.InputParameters.Contains("Target")) 
    { 
     //Create Service from Service Factory 
    serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 
    service = serviceFactory.CreateOrganizationService(context.UserId); 

    var javaScriptSerializer = new JavaScriptSerializer(); 
    javaScriptSerializer.MaxJsonLength = 104857600; //200 MB unicode 

      StringBuilder URI = new StringBuilder(); 
      URI.Append(crmRestWebServiceUrl).Append(webServiceMethod); 
      //Logger.Info("GetLatestMembershipFromCRMRestWebService is called with Url: " + URI.ToString()); 
      var request = (HttpWebRequest)WebRequest.Create(URI.ToString()); 
      request.Method = "POST"; 
      request.Accept = "application/json"; 
      request.ContentType = "application/json; charset=utf-8"; 

      //Serialize request object as JSON and write to request body 
      if (latestMembershipRequest != null) 
      { 
       var stringBuilder = new StringBuilder(); 
       javaScriptSerializer.Serialize(latestMembershipRequest, stringBuilder); 
       var requestBody = stringBuilder.ToString(); 
       request.ContentLength = requestBody.Length; 
       var streamWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII); 
       streamWriter.Write(requestBody); 
       streamWriter.Close(); 

       // Logger.Info("Request Object that will be sent is: " + stringBuilder.ToString()); 
      } 

      // Logger.Info("Sending Request to CRMRestWebService to get LatestMembership."); 
      var response = request.GetResponse(); 

      //Read JSON response stream and deserialize 
      var streamReader = new System.IO.StreamReader(response.GetResponseStream()); 
      var responseContent = streamReader.ReadToEnd().Trim(); 
      LatestMembershipResponse latestMembershipResponse = javaScriptSerializer.Deserialize<LatestMembershipResponse>(responseContent); 
      // Logger.Info("Latest Membership Reveived is: " + responseContent.ToString() + " has been deserialized Successfully."); 
      return latestMembershipResponse; 

}