How to use duplex in netnamedpipe in wcf 4.0 - wcf

Is there any way that we can use netnamedpipe binding with duplex ?
I am getting the following error.
Contract requires Duplex, but Binding 'NetNamedPipeBinding' doesn't support it or isn't configured properly to support it.
ServiceHost host = new ServiceHost(typeof(MyService));
NetNamedPipeBinding npb = new NetNamedPipeBinding();
npb.MaxBufferSize = Int32.MaxValue;
npb.MaxReceivedMessageSize = Int32.MaxValue;
npb.OpenTimeout = new TimeSpan(200000);
npb.CloseTimeout = new TimeSpan(200000);
npb.SendTimeout = new TimeSpan(200000);
npb.TransferMode = TransferMode.Streamed;
host.AddServiceEndpoint(typeof(IMyService), npb, "net.pipe://localhost/MyService");
host.Open(); // I am getting above error here
Please guide me.

Duplex communication works with a net named pipe binding. Try removing:
npb.TransferMode = TransferMode.Streamed;

Related

Using WCF in .net 2

I've got a method of connecting and use a WCF method, which is on HTTPS and requires a username and password in .net 4.
Now I need to do the same but within .Net 2 and I can't seem to get it to work. I keep on getting the below error. Can anyone help?
Error
{"The underlying connection was closed: An unexpected error occurred on a receive."}
Inner Exception
{"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}
.Net 4 Original Code:
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress ea = new EndpointAddress(wcfURL);
var web = new Gateway.GatewayClient(myBinding, ea);
// var web = new Gateway.GatewayClient();
XMLCrypto crypto = new XMLCrypto();
web.ClientCredentials.UserName.UserName = crypto.DecryptString(username);
web.ClientCredentials.UserName.Password = crypto.DecryptString(password);
web.Open();
web.Inbound("HOLog", message.Trim().Replace("\n", "").Replace(#"\\", ""));
web.Close();
.Net 2 Code
XMLCrypto crypto = new XMLCrypto();
url = "http://..../gateway/gateway.svc";
userName = crypto.DecryptString(userName);
password = crypto.DecryptString(password);
var web = new Gateway.Gateway();
var credentials = new NetworkCredential(userName, password);
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri(url), "Basic", credentials);
web.Credentials = credentials;
string returnMessage = web.Inbound("LSOA", " ");
After a long trolling over the web and testing different ways of talking to a WCF method, I have found the reason why it does not work.
Currently the WCF is set to use wsHttpBinding and now I know that .net 2, does not support it. My work around was to change the Binding from wsHttpBinding to basicHttpBinding within the Web.config of the WCF.
To do this and not effect anything using the WCF, I have to create a seprate Sub domain that will ref a WCF with the config that has the corrected Binding.
"The wsHttpBinding is not compatible with the ASMX-style web references used in .NET 2.0."
How to consume WCF wsHttpBinding Service in application built in 2.0?

WCF: Invalid Security Header

Usually when I consume a web service I add a service reference, put in the URL for the WSDL, and then finagle my way through the API's.
This time around I get a FaultException with the message: "Invalid security header".
Here is my binding:
CustomBinding bindingBNP = new CustomBinding();
SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128;
securityElement.KeyEntropyMode = System.ServiceModel.Security.SecurityKeyEntropyMode.CombinedEntropy;
securityElement.IncludeTimestamp = false;
securityElement.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
MtomMessageEncodingBindingElement mtomElement = new MtomMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8);
HttpsTransportBindingElement httpsElement = new HttpsTransportBindingElement();
httpsElement.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
httpsElement.BypassProxyOnLocal = false;
httpsElement.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
httpsElement.ManualAddressing = false;
httpsElement.ProxyAuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
httpsElement.TransferMode = TransferMode.Buffered;
httpsElement.UnsafeConnectionNtlmAuthentication = false;
httpsElement.RequireClientCertificate = false;
httpsElement.UseDefaultWebProxy = false;
bindingBNP.Elements.Add(securityElement);
bindingBNP.Elements.Add(mtomElement);
bindingBNP.Elements.Add(httpsElement);
Related question: for diagnostic purposes, how do I know what the inbound/outbound communication is?
Fiddler doesn't seem to pick up anything (I guess it would have to be on the server machine, which I'm probably not going to be able to negotiate). WCF tracing only seems to surface communication "milestones" (if that word connotates some flavor of victory I am ways off!).
Fiddler runs on the client:
Did you start Fiddler before your client?
Did you configure your application to proxy its traffic?
Are you sure your WCF is using HTTP as the transport?

Specifying Castle WCF Integration Facility Endpoint Behavior per Endpoint

I'm using Castle WCF Integration Facility and I have everything working properly for my first webHttp endpoint. For this endpoint to work, it requires that the endpoint have the WebHttpBehavior enabled. I was able to achieve this using:
container.Register(Component.For<IEndpointBehavior>()
.ImplementedBy<WebHttpBehavior>());
This becomes a problem when I try to enable a second endpoint using BasicHttpBinding which is not compatible with the WebHttpBehavior.
Is there someway to specify that the IEndPointBehavior registration above is only applicable to a certain endpoint?
This is my full installer for the service:
container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
.Register(Component.For<IDiagnosticService>()
.ImplementedBy<DiagnosticService>()
.Named("DiagnosticService")
.LifestyleTransient()
.AsWcfService(new DefaultServiceModel()
.Hosted()
.AddEndpoints(WcfEndpoint.BoundTo(new WebHttpBinding()).At("json"))
.AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding()).At("soap"))
.PublishMetadata(o => o.EnableHttpGet())));
container.Register(Component.For<IEndpointBehavior>()
.ImplementedBy<WebHttpBehavior>());
Ok. I finally figured this out. Turns out that the majority of my problem had to do with the Azure emulation environment rather than Castle WCF Integration. The answer is pretty straight forward -- just setup the ServiceEndpoint instances and use the WcfEndpoint.FromEndpoint() method.
Here is my working installer:
String internalEndpointAddress = string.Format("http://{0}/DiagnosticService.svc",
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint);
// This ContractDescription instance must be used for both endpoints in this case
ContractDescription description = ContractDescription.GetContract(typeof(IDiagnosticService));
// Create JSON webHTTP Binding
WebHttpBinding webhttpbinding = new WebHttpBinding();
string jsonURI = internalEndpointAddress + "/json";
EndpointAddress jsonEndpointAddress = new EndpointAddress(new Uri(jsonURI));
ServiceEndpoint jsonEndpoint = new ServiceEndpoint(description, webhttpbinding, jsonEndpointAddress);
jsonEndpoint.Behaviors.Add(new WebHttpBehavior());
// Create WSHTTP Binding
WSHttpBinding wsHttpBinding = new WSHttpBinding();
string soapURI = internalEndpointAddress + "/soap";
EndpointAddress soapEndpointAddress = new EndpointAddress(new Uri(soapURI));
ServiceEndpoint soapEndpoint = new ServiceEndpoint(description, wsHttpBinding, soapEndpointAddress);
container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
.Register(Component.For<IDiagnosticService>()
.ImplementedBy<DiagnosticService>()
.Named("DiagnosticService")
.LifestyleTransient()
.AsWcfService(new DefaultServiceModel()
.Hosted()
.AddEndpoints(WcfEndpoint.FromEndpoint(jsonEndpoint))
.AddEndpoints(WcfEndpoint.FromEndpoint(soapEndpoint))
.PublishMetadata(o => o.EnableHttpGet())));

WCF Security exception when calling from Windows Service

I have some code which consumes a WCF service. The service is protected by basic authentication, so on creating the client, I'm using the following code:
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
httpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
httpBinding.Security.Transport.Realm = service_realm;
EndpointAddress address = new EndpointAddress(service_address);
Service.ServiceClient client = new Service.ServiceClient(httpBinding, address);
client.ClientCredentials.UserName.UserName = service_username;
client.ClientCredentials.UserName.Password = service_password;
Works fine when I run the code from a console app. But when I run the same code from a windows service, a MessageSecurityException is being thrown telling me that my request was unauthorized. For some reason it seems to be using the current Windows account for authentication, because my own account does have access to the service. But I don't want it to, I want it to use the stored credentials. What am I missing here?
WCF basicHttpBinding does not support plaintext credentials; the reason is because the moment you want pass credentials around on a transport binding, WCF requires the underlying transport to be a secure transport, such as SSL.
In order for your code to work, you would then need to use service via https or using certificates or encryption.
Seems to be fixed using this config:
_httpBinding = new BasicHttpBinding();
_httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
_httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
_httpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
_httpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
_httpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
_httpBinding.AllowCookies = false;
_httpBinding.BypassProxyOnLocal = false;
_httpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
_httpBinding.MessageEncoding = WSMessageEncoding.Text;
_httpBinding.TextEncoding = Encoding.UTF8;
_httpBinding.TransferMode = TransferMode.Buffered;
_httpBinding.UseDefaultWebProxy = false;
Service.ServiceClient client = new Service.ServiceClient(_httpBinding, _address);
client.ClientCredentials.UserName.UserName = service_username;
client.ClientCredentials.UserName.Password = service_password;

Given the Following Code how Would i Change/Set my Silverlight WCF Service URI in code?

Given the Following Code how Would i Change/Set my Silverlight WCF Service URI in code?
mySvc.InsertPOCompleted += new EventHandler<SalesSimplicityPO_SL.POSvc.InsertPOCompletedEventArgs>(mySvc_InsertPOCompleted);
mySvc.InsertPOAsync(InitialsTextBox.Text.ToString(), DescTextBox.Text.ToString(), ClientTextBox.Text.ToString());
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(new Uri("http://localhost/POSystem/POSvc.svc"));
POSvc.POSvcClient mySvc = new POSvc.POSvcClient(binding, address);