When building a project using the Footprints API proxy class, generated from importing BMC's WSDL content in WCF, I'm finding that the ExternalApiServiceClient object is always in a "Faulted" state when creating the object and trying to use it. An example error I get when trying to call a function on it is below:
"The communication object, System.ServiceModel.ChannelFactory`1[FootprintsWebServiceAPI.ExternalApiService], cannot be used for communication because it is in the Faulted state."
Below is an example of code that shows the issue after the ExternalApiClientService (serviceClient) has been created:
private static Test()
{
ExternalApiServiceClient serviceClient = null;
SearchRow[] tickets = null;
serviceClient = new ExternalApiServiceClient(new ExternalApiServiceClient.EndpointConfiguration(), uri.ToString());;
serviceClient.OpenAsync();
runSearchRequest._searchId = System.Convert.ToInt64(ConfigurationManager.AppSettings["allOpenIncidentsSearchId"]);
runSearchResponse1 = serviceClient.runSearchAsync(runSearchRequest);
tickets = runSearchResponse1.@return;
}
How can I resolve this?
You're basically running into race conditions where the application is trying to use the object before it's connected with the Footprints service. To mitigate this, have the work implemented as an asynchronous task:
private static async Task Test()
{
ExternalApiServiceClient serviceClient = null;
SearchRow[] tickets = null;
serviceClient = new ExternalApiServiceClient(new ExternalApiServiceClient.EndpointConfiguration(), uri.ToString());;
await serviceClient.OpenAsync();
runSearchRequest._searchId = System.Convert.ToInt64(ConfigurationManager.AppSettings["allOpenIncidentsSearchId"]);
runSearchResponse1 = await serviceClient.runSearchAsync(runSearchRequest);
tickets = runSearchResponse1.@return;
}
Also, make sure within the Reference.cs file that is generated from the footprints WSDL
For this following method
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.ExternalApiServicePort))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
Change it to the following to enable Basic Auth which is needed
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.ExternalApiServicePort))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
#region Enables basic Auth
result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
#endregion
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article