so as to not have to restart my application (MDSManager) when updating endpoint url
it is now done and you can update the endpoint on the fly!
note: this post is based on Steve Wilkes’ article (see here)
download the latest version of this class file (right click and ‘save as’ )
usage:
using (ServiceClient c = new ServiceClientWrapper().CreateServiceClient())
{
}
Service Wrapper Code :
using System;
using System.Net;
using System.Net.Security;
using System.ServiceModel;
using Common.ServiceReference1;
using System.ServiceModel.Description;
namespace Common
{
public class ServiceClientWrapper :
ServiceClientWrapper<ServiceClient, ServiceReference1.IService>
{
public ServiceClientWrapper()
: base()
{
}
}
public class ServiceClientWrapper<TClient, IService> : IDisposable
where TClient : ClientBase<IService>
where IService : class
{
public const int maxStringContentLength = 2147483647;
private readonly string _domain;
private readonly string _userName;
private readonly string _password;
private readonly Uri _uri;
private TClient _serviceClient;
public ServiceClientWrapper()
{
this._domain = Globals.Domain;
this._userName = Globals.UserName;
this._password = Globals.Password;
this._uri = Globals.EndPointAddress;
}
public ServiceClientWrapper(string domain, string userName, string password, Uri uri)
{
this._domain = domain;
this._userName = userName;
this._password = password;
this._uri = uri;
}
public TClient CreateServiceClient()
{
this.DisposeExistingServiceClientIfRequired();
if (Globals.EndPointAddress != null)
{
//if (this._config.IgnoreSslErrors)
//{
ServicePointManager.ServerCertificateValidationCallback =
(obj, certificate, chain, errors) => true;
//}
//else
//{
// ServicePointManager.ServerCertificateValidationCallback =
// (obj, certificate, chain, errors) => errors == SslPolicyErrors.None;
//}
//here we can specify the end point identity, so as to avoid security negocation errors
EndpointIdentity epid = EndpointIdentity.CreateUpnIdentity("host\\localhost");
// update : programmatic binding
EndpointAddress epaddr = new EndpointAddress(new Uri(Globals.EndpointAddress), epid);
this._serviceClient = (TClient)Activator.CreateInstance(
typeof(TClient), new WSHttpBinding()
{
MaxBufferPoolSize = maxStringContentLength,
MaxReceivedMessageSize = maxStringContentLength,
OpenTimeout = new TimeSpan(1, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0),
SendTimeout = new TimeSpan(1, 0, 0)
},
epaddr);
//we specify here the windows client credentials
if (!string.IsNullOrEmpty(Globals.EndPointName))
this._serviceClient.Endpoint.Name = Globals.EndPointName;
if (!string.IsNullOrEmpty(Globals.Domain))
this._serviceClient.ClientCredentials.Windows.ClientCredential.Domain = Globals.Domain;
//update to specify UserName and Password for other credentials than ClientCredentials.Windows
if (!string.IsNullOrEmpty(Globals.UserName))
{
this._serviceClient.ClientCredentials.Windows.ClientCredential.UserName = Globals.UserName;
this._serviceClient.ClientCredentials.UserName.UserName = (!string.IsNullOrWhiteSpace(Globals.Domain) ? Globals.Domain + "\\" + Globals.UserName : Globals.UserName);
}
if (!string.IsNullOrEmpty(Globals.Password))
{
this._serviceClient.ClientCredentials.Windows.ClientCredential.Password = Globals.Password;
this._serviceClient.ClientCredentials.UserName.Password = Globals.Password;
}
//here we override the "MaxItemsInObjectGraph" property with max value :2147483647, so as to avoid buffer limit error
var operations = _serviceClient.Endpoint.Contract.Operations;
foreach (var operation in operations)
{
operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = maxStringContentLength;
}
_serviceClient.InnerChannel.OperationTimeout = new TimeSpan(1, 0, 0);
return this._serviceClient;
}
return null;
}
public void Dispose()
{
this.DisposeExistingServiceClientIfRequired();
}
private void DisposeExistingServiceClientIfRequired() { if (this._serviceClient != null) { try { if (this._serviceClient.State == CommunicationState.Faulted) { this._serviceClient.Abort(); } else { this._serviceClient.Close(); } } catch { this._serviceClient.Abort(); } this._serviceClient = null; } }
update october 29 : added 2 catch blocks so as to catch the REAL error message, please see this post:
http://fczaja.blogspot.com/2009/05/communication-object.html
private void DisposeExistingServiceClientIfRequired()
{
if (this._serviceClient != null)
{
try
{
if (this._serviceClient.State == CommunicationState.Faulted)
{
this._serviceClient.Abort();
}
else
{
this._serviceClient.Close();
}
}
catch (CommunicationException)
{
this._serviceClient.Abort();
}
catch (TimeoutException)
{
this._serviceClient.Abort();
}
catch (Exception ex)
{
this._serviceClient.Abort();
throw ex;
}
this._serviceClient = null;
}
}
} }
and your app.config “serviceModel” section will be reduced to: (and could be reduced even more..)
update details (@Oct 16,2011):
programatic bindind in C#
EndpointAddress epaddr = new EndpointAddress(Globals.EndPointAddress, epid); this._serviceClient = (TClient)Activator.CreateInstance( typeof(TClient), Globals.EndPointName, epaddr);
becomes
this._serviceClient = (TClient)Activator.CreateInstance(
typeof(TClient), new WSHttpBinding()
{
MaxBufferPoolSize = maxStringContentLength,
MaxReceivedMessageSize = maxStringContentLength,
OpenTimeout = new TimeSpan(1, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0),
SendTimeout = new TimeSpan(1, 0, 0)
},
epaddr);
update 2011/10/19: added a binding type switch
EndpointIdentity epid = EndpointIdentity.CreateUpnIdentity("host\\localhost");
// update : programmatic binding
EndpointAddress epaddr = new EndpointAddress(Globals.EndPointAddress, epid);
if (Globals.myBindingType == Globals.BindingType.BasicHttpBinding)
{
this._serviceClient = (TClient)Activator.CreateInstance(
typeof(TClient), new BasicHttpBinding()
{
MaxBufferPoolSize = maxStringContentLength,
MaxReceivedMessageSize = maxStringContentLength,
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
{
MaxArrayLength = maxStringContentLength,
MaxBytesPerRead = maxStringContentLength,
MaxDepth = 32,
MaxNameTableCharCount = maxStringContentLength,
MaxStringContentLength = maxStringContentLength
},
MaxBufferSize = maxStringContentLength,
UseDefaultWebProxy = true,
OpenTimeout = new TimeSpan(1, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0),
SendTimeout = new TimeSpan(1, 0, 0)
},
epaddr);
}
if (Globals.myBindingType == Globals.BindingType.WSHttpBinding)
{
this._serviceClient = (TClient)Activator.CreateInstance(
typeof(TClient), new WSHttpBinding()
{
MaxBufferPoolSize = maxStringContentLength,
MaxReceivedMessageSize = maxStringContentLength,
OpenTimeout = new TimeSpan(1, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0),
SendTimeout = new TimeSpan(1, 0, 0),
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
{
MaxArrayLength = maxStringContentLength,
MaxBytesPerRead = maxStringContentLength,
MaxDepth = 32,
MaxNameTableCharCount = maxStringContentLength,
MaxStringContentLength = maxStringContentLength
}
},
epaddr);
}




