I have a Self-Hosted WCF Service and client.
The client does not have a service reference, I have linked it to the endpoint programmatically.
The bindings are set to BasicHttpBinding in both the client and service -
Service
Uri baseAddress = new Uri("http://localhost:8733/Design_Time_Addresses/DSCentralService/Service1/");
DSCentralService.Service1 contentServer = new DSCentralService.Service1();
//initialise the servicehost
centralSvrHost = new ServiceHost(typeof(DSCentralService.Service1), baseAddress);
//add bindings
centralSvrHost.AddServiceEndpoint(
typeof(DSCentralService.IService1),
new BasicHttpBinding(),
baseAddress
);
Client
serviceFactory = new ServiceFactory<DSCentralService.IService1>();
String serviceAddress="http://localhost:8733/Design_Time_Addresses/DSCentralService/Service1/";
iContentServer = serviceFactory.GetService(serviceAddress);
Service Factory Class
public class ServiceFactory<T> where T : class
{
private T _service;
public T GetService(string address)
{
return _service ?? (_service = GetServiceInstance(address));
}
private static T GetServiceInstance(string address)
{
BasicHttpBinding basicBinding = new BasicHttpBinding();
basicBinding.Name = "DSCentralSvr";
basicBinding.TransferMode = TransferMode.Streamed;
basicBinding.MessageEncoding = WSMessageEncoding.Mtom;
basicBinding.MaxReceivedMessageSize = 10067108864;
basicBinding.SendTimeout = new TimeSpan(0, 10, 0);
basicBinding.OpenTimeout = new TimeSpan(0, 10, 0);
basicBinding.CloseTimeout = new TimeSpan(0, 10, 0);
basicBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
EndpointAddress endpoint = new EndpointAddress(address);
return ChannelFactory<T>.CreateChannel(basicBinding, endpoint);
}
}
Yet upon debugging, I receive the common error of
The client and service bindings may be mismatched
There are no settings for bindings in any config files of either the client or service, to avoid conflicts with the programmatic settings.
Is there something I have missed, which is necessary when doing this programmatically? What is causing this mis-match?
You are hosting the service with a default BasicHttpBinding which means TransferMode Buffered and MessageEncoding Text.
In your client you are using Streamed and Mtom, respectively.
Related
I add a reference to a service in my .net core 2.2 project using svcutil 2.0.2 from here :
http://sms.magfa.com/services/urn:SOAPSmsQueue?wsdl
the created service proxy send the request to server and server send reply back to the us but the proxy can not get the result !!
we use this service in our asp .net web app but in .net core 2.2 using svcutil 2.0.2 we can not get the result.
what is the problem ?
thank you
my code :
BasicHttpBinding basicHttpBinding = null;
EndpointAddress endpointAddress = null;
ChannelFactory<ServiceReference1.SoapSmsQueuableImplChannel> factory = null;
ServiceReference1.SoapSmsQueuableImplChannel serviceProxy = null;
try
{
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
endpointAddress = new EndpointAddress(new Uri("https://sms.magfa.com/services/urn:SOAPSmsQueue?wsdl"));
factory = new ChannelFactory<ServiceReference1.SoapSmsQueuableImplChannel>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "**";
factory.Credentials.UserName.Password = "****";
serviceProxy = factory.CreateChannel();
//((ICommunicationObject)serviceProxy).Open();
//var opContext = new OperationContext((IClientChannel)serviceProxy);
//var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
//OperationContext.Current = opContext;
using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
{
var result = await serviceProxy.getCreditAsync("***").ConfigureAwait(false);
}
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
// *** ENSURE CLEANUP (this code is at the WCF GitHub page *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
My app uses WCF to transfer data from server and app.It works well all along.But recently,if the app does not operate after a period of time,there's always throwing a timeout exception.When the timeout exception was thrown,winform application can call WCF normally。If restart debug,the app can call WCF again;and after a while,it throw timeout exception again.What can I do for this?
My code like this:
// CreateBinding
private static BasicHttpBinding CreateBasicHttp()
{
BasicHttpBinding binding = new BasicHttpBinding
{
Name = "basicHttpBinding",
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 2147483647
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
TimeSpan timeout = new TimeSpan(0, 0, 30);
binding.SendTimeout = timeout;
binding.OpenTimeout = timeout;
binding.ReceiveTimeout = timeout;
return binding;
}
// Create Endpoint
private static EndpointAddress CreateEndPoint(string serviceName)
{
string serviceUrl = App.RemoteUrl + serviceName + ".svc";
EndpointAddress EndPoint = new EndpointAddress(serviceUrl);
return EndPoint;
}
// Create binder
public static WCFBinder GetBinder<T>()
{
WCFBinder binder;
Type t = typeof(T);
string serviceName = t.Name.Substring(1, t.Name.Length - 1);
binder.Binding = CreateBasicHttp();
binder.EndPoint = CreateEndPoint(serviceName);
return binder;
}
// Create a client
var binder = SDHCommonMethod.GetBinder<IAAA001BLLService>();
IAAA001BLLService asc = new AAA001BLLServiceClient(binder.Binding, binder.EndPoint);
// Call WCF
var obj = await Task.Factory.FromAsync(asc.BeginSelectAAA001, asc.EndSelectAAA001, dto, TaskCreationOptions.None);
The code is right. In vs2017,it can work.Maybe my vs2015 has something wrong.
I've spent 3 hours looking for any samples and going through many articles. I am trying to get WCF adhoc discovery mechanism to work for a self hosted windows service. If I run the client on the same machine it works, but on a different machine it doesn't. Every tutorial/sample (conveniently) shows it on the same machine which works.
I disabled firewall on both machines.
If I directly use the end point in the client, it works. So, it's only service discovery that is not working.
Here is my server code:
static void Main(string[] args)
{
Uri baseAddress = new Uri(string.Format("http://{0}:12345/discovery/Myservice/", System.Net.Dns.GetHostName()));
Console.WriteLine(baseAddress);
using (ServiceHost serviceHost = new ServiceHost(typeof(SampleService.Service1), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(SampleService.IService1), new BasicHttpBinding(), string.Empty);
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
ServiceMetadataBehavior metaDataBehavior = new ServiceMetadataBehavior();
metaDataBehavior.HttpGetEnabled = true;
serviceHost.Description.Behaviors.Add(metaDataBehavior);
serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
serviceHost.Open();
Console.WriteLine("Press to terminate service.");
Console.ReadLine();
}
}
Here is my client code:
static void InvokeService()
{
Console.WriteLine("\nFinding Service ..");
DiscoveryClientBindingElement discoveryClientBindingElement =
new DiscoveryClientBindingElement();
var Services =
discoveryClientBindingElement.FindCriteria = new FindCriteria(typeof(ServiceReference1.IService1));
discoveryClientBindingElement.DiscoveryEndpointProvider = new UdpDiscoveryEndpointProvider();
// The service uses the BasicHttpBinding, so use that and insert the DiscoveryClientBindingElement at the
// top of the stack
CustomBinding binding = new CustomBinding(new BasicHttpBinding());
binding.Elements.Insert(0, discoveryClientBindingElement);
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client(binding, DiscoveryClientBindingElement.DiscoveryEndpointAddress);
Console.WriteLine("Data = " + client.GetData(1));
}
Any help is greatly appreciated.
I've been doing tests using the following sample from Microsoft :
http://msdn.microsoft.com/en-us/library/ff521581.aspx
it works, but it is a basichttp endpoint.
is there a way to make it a CustomBinding endpoint with binaryMessageEncoding?
Thanks,
Alex
This will create a custom binding using Http transport and binary encoding:
protected override Binding CreateBinding()
{
BinaryMessageEncodingBindingElement messageEncoding = new BinaryMessageEncodingBindingElement();
TransportBindingElement transport = new HttpTransportBindingElement();
BindingElementCollection bindingElements = new BindingElementCollection()
{
messageEncoding, transport
};
return new CustomBinding(bindingElements);
}
I would like to be able to use username/password authentication with nettcpbinding, is that possible? (UserNamePasswordValidator or something like that), no windows authentication.
I'm configuring everything with code, so please only use code and not app.config in any examples.
This is what I came up with, I have no idea if some of the code is not required:
Service host:
ServiceHost host = new ServiceHost(concreteType);
var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential, true);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
host.AddServiceEndpoint(serviceType, binding, "net.tcp://someaddress:9000/" + name);
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
host.Credentials.ServiceCertificate.Certificate = new X509Certificate2("mycertificate.p12", "password");
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =
UserNamePasswordValidationMode.Custom;
And client side:
var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential, true);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var factory = new ChannelFactory<ISwitchService>(binding,
new EndpointAddress(
new Uri("net.tcp://someaddress:9000/switch")));
factory.Credentials.UserName.UserName = "myUserName";
factory.Credentials.UserName.Password = "myPassword";