When I try to call the method in the WCF host I get this error:
There was no endpoint listening at net.pipe://localhost/PipeReverse
that could accept the message. This is often caused by an incorrect
address or SOAP action. See InnerException, if present, for more
details.
I have a class that starts the WCF host:
public class ProcessUnderMouseServer
{
public ProcessUnderMouseServer()
{
using (host = new ServiceHost(
typeof(PrcoessUnderMouse),
new Uri[]
{
new Uri("net.pipe://localhost")
}))
{
host.AddServiceEndpoint(
typeof(IPrcoessUnderMouse),
new NetNamedPipeBinding(),
"PipeReverse");
host.Open();
}
}
}
this class is in a different library project than the consuming project
Then I try to consume it like this:
ProcessUnderMouseServer ProcessUnderMouseServer = new ProcessUnderMouseServer();
ChannelFactory<IPrcoessUnderMouse> pipeFactory =
new ChannelFactory<IPrcoessUnderMouse>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/PipeReverse"));
IPrcoessUnderMouse pipeProxy = pipeFactory.CreateChannel();
string str = Console.ReadLine();
Console.WriteLine("pipe: " + pipeProxy.GetProcessUnderMouse());
Shouldn't
host.AddServiceEndpoint(typeof(IPrcoessUnderMouse),new NetNamedPipeBinding(), "PipeReverse");
be sufficient to add the end point? why it says that no endpoint listening at net.pipe://localhost/PipeReverse ??
Related
I need to create a self-hosted WCF service, which allows access through the internet, and it throws this error at me ”System.ServiceModel.EndpointNotFoundException: There was no end listening on http://fabianwesling.dynu.com:28620/HostManager/Service that could accept the message. The cause is usually an incorrect SOAP address or action. ”
can someone help me what is the mistake I am making, I have opened the ports on the router, router firewall and Windows and deactivate the antivirus
… I show you what I have done.
Service
[ServiceContract()]
public interface IService
{
[OperationContract()]
int SumValues(int value1, int value2);
}
public class Service : IService
{
public static void Configure(ServiceConfiguration config)
{
config.Description.Behaviors.Add(new ServiceMetadataBehavior
{
HttpGetEnabled = true
});
config.Description.Behaviors.Add(new ServiceDebugBehavior
{
IncludeExceptionDetailInFaults = true,
});
config.EnableProtocol(new BasicHttpBinding() );
config.EnableProtocol(new NetTcpBinding());
}
public int SumValues(int value1, int value2)
{
return value1 + value2;
}
}
Run server local Host
Uri http_Uri = new Uri("http://192.168.1.100:28620/HostManager/Service");
Uri netTCP_Uri = new Uri("net.tcp://192.168.1.100:28621/HostManager/Service");
host = new ServiceHost(typeof(HostManager.Services.Service), http_Uri,netTCP_Uri );
host.Open();
Run server to access from internet
Uri http_Uri = new Uri("http://fabianwesling.dynu.com:28620/HostManager/Service");
Uri netTCP_Uri = new Uri("net.tcp://fabianwesling.dynu.com:28621/HostManager/Service");
host = new ServiceHost(typeof(HostManager.Services.Service), http_Uri);
host.Open();
client local connection
EndpointAddress uri = new EndpointAddress("http://192.168.1.100:28620/HostManager/Service");
ServiceReference1.ServiceClient service = new ServiceReference1.ServiceClient("BasicHttpBinding_IService", uri);//http binding
//EndpointAddress uri = new EndpointAddress("net.tcp://192.168.1.100:28621/HostManager/Service");
//ServiceReference1.ServiceClient service = new ServiceReference1.ServiceClient("NetTcpBinding_IService", uri); ///net-tcp binding
var result = service.SumValues(GetNumber(), GetNumber());
client connection through internet
//http binding
EndpointAddress uri = new EndpointAddress(" http://fabianwesling.dynu.com/:28620/HostManager/Service");
ServiceReference1.ServiceClient service = new ServiceReference1.ServiceClient("BasicHttpBinding_IService", uri);
//net-tcp binding
//EndpointAddress uri = new EndpointAddress(" http://fabianwesling.dynu.com/:28620/HostManager/Service");
//ServiceReference1.ServiceClient service = new ServiceReference1.ServiceClient("NetTcpBinding_IService", uri);
var result = service.SumValues(GetNumber(), GetNumber());
Modify domain name to IP address:
EndpointAddress uri = new EndpointAddress(" http://xxx.xxx.xxx.xxx/:28620/HostManager/Service");
ServiceReference1.ServiceClient service = new ServiceReference1.ServiceClient("BasicHttpBinding_IService", uri);
var result = service.SumValues(GetNumber(), GetNumber());
Ensure that the IP address is an IP address on the public network.
I need some example of how to implement a RESTfull service with WCF tecnology on a self-host environment and by using a DI container (possibly SimpleInjector).
On https://simpleinjector.readthedocs.io/en/latest/wcfintegration.html i have found how to integrate a custom factory but it's made for ServiceHost but this it's not suitable for a RESTFull service that instead use WebServiceHost?
I tried to configure service host to be compatible with webHttpBinding but nothing happened and i receive this kind of error:
<Fault
xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value
xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable
</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="it-IT">Impossibile elaborare nel destinatario il messaggio con To 'http://localhost:8733/3AdispPushBatchService/pushpost' a causa di una mancata corrispondenza AddressFilter in EndpointDispatcher. Controllare la corrispondenza di EndpointAddresses del mittente e del destinatario.</Text>
</Reason>
</Fault>
There is another integration package to use for WebServiceHost?
This is the example that i have made
AAADispPushBatchService.cs
using System;
using System.Configuration;
using System.IO;
using System.ServiceModel.Activation;
using System.Text;
using Newtonsoft.Json;
namespace AAARestService
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AAADispPushBatchService : IAaaDispPushBatchService
{
public string GetBatchJson(Stream jsonFileContent)
{
try
{
var sr = new StreamReader(jsonFileContent, Encoding.UTF8);
var str = sr.ReadToEnd();
if (String.IsNullOrWhiteSpace(str))
throw new ArgumentException("No data inside body request");
var definition = new { BatchName = "" };
var json = JsonConvert.DeserializeAnonymousType(str, definition);
if (json == null)
throw new ArgumentException("No valid json inside");
if (String.IsNullOrWhiteSpace(json.BatchName))
throw new ArgumentException("BatchName not present");
var currentDir = ConfigurationManager.AppSettings["BatchPath"];
Directory.CreateDirectory(currentDir);
var filepath = Path.Combine(currentDir, json.BatchName+".json");
File.WriteAllText(filepath, str);
return $"Saved in {filepath}";
}
catch (Exception e)
{
return e.Message;
}
}
}
}
IAaaDispPushBatchService.cs
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace AAARestService
{
[ServiceContract(Name = "AAADispPushBatchService")]
public interface IAaaDispPushBatchService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "pushpost", BodyStyle = WebMessageBodyStyle.Bare,ResponseFormat = WebMessageFormat.Json)]
string GetBatchJson(Stream jsonFileContent);
}
}
EDIT!!!!!
BTW I try to add simpleinjector here are the example based on what i found in the blog
Bootstrapper.cs
using System.Reflection;
using SimpleInjector;
namespace AAARestService
{
public static class BootStrapper
{
public static readonly Container Container;
static BootStrapper()
{
Container container = new Container();
container.Register<IMyDateTimeService,MyDAteTimeService>();
container.RegisterWcfServices(Assembly.GetExecutingAssembly());
Container = container;
}
}
}
MyWebServiceHostFactory.cs
public class MyWebServiceHostFactory : SimpleInjectorServiceHostFactory
{
public ServiceHost GetWebServiceEndpoint(Type serviceType,Uri baseAddress)
{
Uri[] addresses=new Uri[]{baseAddress};
var service = CreateServiceHost(serviceType, addresses);
ServiceEndpoint sep = service.AddServiceEndpoint(typeof(IAaaDispPushBatchService), new WebHttpBinding(), baseAddress);
sep.EndpointBehaviors.Add(new WebHttpBehavior());
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
service.Description.Behaviors.Add(smb);
return service;
}
protected override ServiceHost CreateServiceHost(Type serviceType,
Uri[] baseAddresses)
{
var host = new SimpleInjectorServiceHost(
BootStrapper.Container,
serviceType,
baseAddresses);
return host;
}
}
Main
static void Main(string[] args)
{
try
{
Uri httpUrl = new Uri("http://localhost:8733/3AdispPushBatchService");
Uri httpUrl1 = new Uri("http://localhost:8734/3AdispPushBatchService");
//ServiceHost selfhost = new ServiceHost(typeof(AAADispPushBatchService), httpUrl);
//ServiceEndpoint sep =selfhost.AddServiceEndpoint(typeof(IAaaDispPushBatchService),new WebHttpBinding(), httpUrl);
//sep.EndpointBehaviors.Add(new WebHttpBehavior());
//ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
//smb.HttpGetEnabled = true;
//selfhost.Description.Behaviors.Add(smb);
MyWebServiceHostFactory factory = new MyWebServiceHostFactory();
var selfhost=factory.GetWebServiceEndpoint(typeof(AAADispPushBatchService), httpUrl);
selfhost.Open();
//WebServiceHost webHost = new WebServiceHost(typeof(AAADispPushBatchService),httpUrl1);
//webHost.Open();
foreach (ServiceEndpoint se in selfhost.Description.Endpoints)
Console.WriteLine("Service is host with endpoint " + se.Address);
//foreach (ServiceEndpoint se in webHost.Description.Endpoints)
// Console.WriteLine("Service is host with endpoint " + se.Address);
//Console.WriteLine("ASP.Net : " + ServiceHostingEnvironment.AspNetCompatibilityEnabled);
Console.WriteLine("Host is running... Press <Enter> key to stop");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
I haven't tried integration with WCF using dependency injection technology, maybe the solution in that blog is worth a try. I also don't recommend you use dependency injection in WCF, because it does not support dependency injection natively. In addition, for servicehost hosting WCF REST-style services, we need to add WebHttp behavior on the service endpoint. Please refer to the following code implementation.
Uri uri = new Uri("http://localhost:8004");
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.None;
using (ServiceHost sh = new ServiceHost(typeof(MyService), uri))
{
ServiceEndpoint se=sh.AddServiceEndpoint(typeof(IService), binding,"");
se.EndpointBehaviors.Add(new WebHttpBehavior());
sh.Opened += delegate
{
Console.WriteLine("Service is ready");
};
sh.Closed += delegate
{
Console.WriteLine("Service is clsoed");
};
sh.Open();
Console.ReadLine();
//pause
sh.Close();
Console.ReadLine();
Feel free to let me know if there is anything I can help with.
We have a WCF Service (ServiceContact + Implementation class). The service was originally self hosted using ServiceHost and BasicHttpBinding using TransportWithMessageCredential.
Clients have been configured to use this service and cannot be changed except to be pointed to a new url.
Now we want to change how the service is hosted. The entry point on the new host (not IIS) is an Http request message (headers and body). The idea is that we point clients to the new host and bridge the gap between the Http request and the WCF Stack.
In theory it sounds like we have to create a new TransportBindingElement, followed by a CustomBinding to use this transport. This is proving mind bogglingly complicated.
Alternatively, what sounds easier is, if possible, to create a WCF Message instance from the http request, and somehow send it through the various existing binding elements used by BasicHttpBinding (mainly so all the Security headers are processed), and somehow end up in our WCF Service implementation.
Does anyone have any idea on if and how this may be possible?
2019-06-14: Adding sample to demonstrate challenge:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace ConsoleApp5
{
[ServiceContract]
public interface IService
{
[OperationContract]
string Invert(string s);
}
public interface IServiceChannel : IService, IClientChannel
{
}
public class Service : IService
{
public string Invert(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
}
class Program
{
static void Main(string[] args)
{
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
Console.WriteLine("Enter 1 for WCF Listene, anything else for HttpListener");
var option = Console.ReadLine();
if(option == "1")
{
Task.Run(() => StartWCFHost());
}
else
{
Task.Run(() => StartHttpListenerHost());
}
Console.WriteLine("hosting");
Console.WriteLine("Enter string to invert");
var streingToInvert = Console.ReadLine();
var binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
var cf = new ChannelFactory<IService>(binding, new EndpointAddress("https://localhost:20443/myservice"));
cf.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "dc72486676c5e983589897fca5051a360376777d");
var client = cf.CreateChannel();
try
{
var r = client.Invert(streingToInvert);
Console.WriteLine(r);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
private static void StartHttpListenerHost()
{
var web = new HttpListener();
web.Prefixes.Add("https://localhost:20443/");
Console.WriteLine("Listening..");
web.Start();
while(true)
{
var context = web.GetContext();
var soapMessage = Message.CreateMessage(XmlReader.Create(context.Request.InputStream), int.MaxValue, MessageVersion.Soap11);
//TODO: How do we process request security related headers and give a proper response to client?
//Ideally we want to use Service implementation class and WCF Bindings/BindingElements to process headers and generate response message
//For the time being just read body write it to console
var body = soapMessage.GetReaderAtBodyContents().ReadOuterXml();
Console.WriteLine(soapMessage.ToString());
Console.WriteLine(body);
context.Response.Close();
}
}
private static void StartWCFHost()
{
ServiceHost sh = new ServiceHost(typeof(Service), new Uri("https://localhost:20443/myservice"));
var binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
var se = sh.AddServiceEndpoint(typeof(IService), binding, "https://localhost:20443/myservice");
sh.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpsGetEnabled = true });
sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "dc72486676c5e983589897fca5051a360376777d");
sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
sh.Open();
}
}
}
I am looking for a dotnet core WCF wsHttpBinding workaround.
I am aware that .net core WCF implementation currently does not support wsHttpBinding (see support matrix here https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.1.0.md)
I'm integrating with a legacy third party service that appears to only support wsHttpBinding. Our tech stack is .net core, so I cannot revert to the full version of .net framework or mono variant.
The question is whether it's possible to use the service via custom bindings? I am hoping that there is a workaround that maybe isn't fully functional, but at least allows me to consume the service.
var cBinding = new CustomBinding();
var textBindingElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.Soap12WSAddressing10
};
cBinding.Elements.Add(textBindingElement);
var httpBindingElement =
new HttpsTransportBindingElement
{
AllowCookies = true, MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue,
};
cBinding.Elements.Add(httpBindingElement);
var myEndpoint = new EndpointAddress("https://..../Service.svc/wss");
using (var myChannelFactory = new ChannelFactory<ISearch>(cBinding, myEndpoint))
{
myChannelFactory.Credentials.UserName.UserName = "...";
myChannelFactory.Credentials.UserName.Password = "...";
ISearch client = null;
try
{
client = myChannelFactory.CreateChannel();
var result = client.Find(new Search("Criteria")).Result;
((ICommunicationObject)client).Close();
myChannelFactory.Close();
}
catch (Exception ex)
{
(client as ICommunicationObject)?.Abort();
}
}
Client gets created and a call is made to the service, but it fails because:
Message = "The message could not be processed. This is most likely because the action '' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between binding
Forget it, they are not completely compatible with Core. Under some specified case, there may be a basic call to WsHttpBinding. You could refer to the following example.
Server.
Uri uri = new Uri("http://localhost:11011");
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
using (ServiceHost sh=new ServiceHost(typeof(MyService),uri))
{
sh.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb==null)
{
smb = new ServiceMetadataBehavior()
{
};
sh.Description.Behaviors.Add(smb);
}
Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
sh.Opened += delegate
{
Console.WriteLine("Service is ready");
};
sh.Closed += delegate
{
Console.WriteLine("Service is clsoed");
};
sh.Open();
Client(auto-generated)
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_IService))
{
System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
result.Elements.Add(textBindingElement);
System.ServiceModel.Channels.HttpTransportBindingElement httpBindingElement = new System.ServiceModel.Channels.HttpTransportBindingElement();
httpBindingElement.AllowCookies = true;
httpBindingElement.MaxBufferSize = int.MaxValue;
httpBindingElement.MaxReceivedMessageSize = int.MaxValue;
result.Elements.Add(httpBindingElement);
return result;
}
Invocation.
ServiceReference1.ServiceClient client2 = new ServiceReference1.ServiceClient();
try
{
var res = client2.SayHelloAsync();
Console.WriteLine(res.Result);
}
catch (Exception)
{
throw;
}
While in most cases it is impossible to call WCF service created by WsHttpBinding.
Officials also have no intention of continuing to support plan for wshttpbinding.
Here are related discussions.
https://github.com/dotnet/wcf/issues/31
https://github.com/dotnet/wcf/issues/1370
I have been through WCF concepts, read many and created SELF HOSTED service.
I added library to solution "CommunicationLibrary" which contains:
[ServiceContract]
interface ICommunication
{
[OperationContract]
string message();
}
and
public class Communication: ICommunication
{
public string message()
{
return "WCF Method Accessed";
}
}
then I added console project to host it "WCFCommunicationHosting" which contains
class WcfHost
{
static void Main(string[] args)
{
Uri baseadd = "sasas";
ServiceHost sh = new ServiceHost(typeof(CommunicationLibrary.Communication), baseadd);
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
sh.Description.Behaviors.Add(smb);
sh.Open();
Console.WriteLine("Host Running");
}
}
now I don't understand that what to pass in baseAdd? I saw many examples like this CodeProject article but I don't understand that why and how they are passing localhost://.
Here is a working example. Its in vb.net, but you should get the idea of how/what is implemented.
Your service address is the address that you will specify in the connection / binding properties on your client that will consume the service. This is the address where it will find and communicate with your web service.
Dim LocalIpAddress as string = "your pc ip"
Dim tcp_port as string = "the port you want to use"
Dim myServiceAddress As New Uri("http://" & localIpAddress & ":" & tcp_port & "/" & servicename)
myservicehost = New ServiceHost(GetType(yourwcfservicemethodsclass), myServiceAddress)
Dim BasicBinding As New BasicHttpBinding
BasicBinding.MaxReceivedMessageSize = 2147483647
myservicehost.AddServiceEndpoint(GetType(Iyourwcfservicemethodsclass), BasicBinding, myServiceAddress)
' Enable metadata publishing.
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
myservicehost.Description.Behaviors.Add(smb)
myservicehost.Open()