I'm getting this strange error when I try connect to my WCF with webHttpBinding service from a web browser:
Sendera:ActionNotSupportedThe message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
My app.config:
<services>
<service name="MyNamespace.MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9091/MyService/" />
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.IMyService" />
</service>
</services>
My method simply looks like this:
[WebGet(UriTemplate = "foo/{id}")]
public string GetFoo(string id)
{ ...
OK - I would expect you're probably missing the endpoint behavior needed - try this config:
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9091/MyService/" />
</baseAddresses>
</host>
<endpoint
address=""
behaviorConfiguration="web"
binding="webHttpBinding"
contract="MyNamespace.IMyService" />
</service>
</services>
When you updated your method from GetFoo(string fooID) to GetFoo(string id), did you also update your contract in IMyService with the updated parameter name of id?
Reference of your previous question: Is there a way to have custom defined friendly URLs with WCF without IIS?
Related
I'm trying to create a WCF and consume it from another C# class.
I think I'm doing everything right but i Get the error message says Contract name is not familiar.
This is my Web.config code:
<system.serviceModel>
<services>
<service behaviorConfiguration="PNMSoft.Sequence.Invoices.InvoicesBehavior" name="PNMSoft.Sequence.Invoices.Invoices">
<endpoint name="InvoicesEndPoint" address="" binding="wsHttpBinding" contract="PNMSoft.Sequence.Invoices.IInvoices">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PNMSoft.Sequence.Invoices.InvoicesBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
This is my interface code:
namespace PNMSoft.Sequence.Invoices
{
[ServiceContract]
public interface IInvoices
{
[OperationContract]
void SendInvoicesToCustomer(int wfid, int userID, int type, string mail, DateTime startDate, DateTime endDate, string clientCode);
}
}
This is my code when I try to activate a function from the service:
InvoicesClient client = new InvoicesClient("InvoicesEndPoint");
client.SendInvoicesToCustomer(IWFID, userID2, type2, Mail, DateFrom2, DateTo2, clientCode2);
On the first row I get this error message: "Could not find endpoint element with name 'InvoicesEndPoint' and contract 'Invoices.IInvoices' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.".
This is the config file on my cient's side:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="InvoicesEndPoint" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="InvoicesEndPoint" contract="Invoices.IInvoices" name="InvoicesEndPoint">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I guess I need to add something to the config file in my client's side. What should I add?
Thank you in advance!
I solved it, I just had to add the endpoint to the client side's config.
I started working with WCF recently, and I'm having a problem that I just don't have a clue how to solve.
I start a WCF Service using Service Host, but when I use the URI in a browser it doesn't show the contract of the service, and it gives an exception when I try to connect to it using a ChannelFactory.
I created the project in Visual Studio 2017, and didn't do anything to the config file, excpet changing the base address. Both the service interface and implementation are in the root project "folder", and I've tried disabling the firewall and even my antivirus, but nothing seems to work.
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TaskExecutor.Exec">
<endpoint address="" binding="basicHttpBinding" contract="TaskExecutor.IExec">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/TaskExecutor/Exec/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Service interface:
namespace TaskExecutor
{
[ServiceContract]
public interface IExec
{
[OperationContract]
void DoWork();
}
}
Service implementation:
namespace TaskExecutor
{
public class Exec : IExec
{
public void DoWork()
{
Console.WriteLine("Doing work.");
}
}
}
Program launching the service:
using (ServiceHost host = new ServiceHost(typeof(Exec)))
{
host.Open();
Console.WriteLine("exec service started at {0}", host.BaseAddresses[0]);
}
Console.WriteLine("Press any key to end...");
Console.ReadLine();
After launching the program display the message:
exec service started at http://localhost:8001/TaskExecutor/Exec/
Press any key to end...
The service client code is the following:
EndpointAddress endpoint = new EndpointAddress("http://localhost:8001/TaskExecutor/Exec/");
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<IExec> channelFactory = new ChannelFactory<IExec>(binding, endpoint);
IExec proxy = channelFactory.CreateChannel();
proxy.DoWork();
And it gives the exception:
System.ServiceModel.EndpointNotFoundException occurred
HResult=0x80131501
Message=There was no endpoint listening at http://localhost:8001/TaskExecutor/Exec/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Inner Exception 1:
WebException: Unable to connect to the remote server
Inner Exception 2:
SocketException: No connection could be made because the target machine actively refused it
I seriously don't know what to do, and any help would be amazing.
Thank you very much!
You have exposed metadata but didnt bind it to the service.Here's how you have to.
<behaviors>
<serviceBehaviors>
<behavior name="metadadiscovery">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Now bind the behavior to the service.
<services>
<service name="TaskExecutor.Exec" behaviorConfiguration="metadadiscovery">
<endpoint address="" binding="basicHttpBinding" contract="TaskExecutor.IExec">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/TaskExecutor/Exec/" />
</baseAddresses>
</host>
</service>
</services>
Now when you type the address in the browser you should be able to see wsdl.
http://localhost:8001/TaskExecutor/Exec/
So I figured out what was wrong, It was the code starting the service. instead of what I have It should be:
using (ServiceHost host = new ServiceHost(typeof(Exec)))
{
host.Open();
Console.WriteLine("exec service started at {0}", host.BaseAddresses[0]);
Console.WriteLine("Press any key to end...");
Console.ReadLine();
}
I get this:
An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/PersistencyService/Service1/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
Why do I get this? I assume it is because the method takes about 1 min to complete. How can disable any time limit?
I get this when running in VS a Windows form project that uses a WCF service in the same solution
My WCF configuration:
edit:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="LongRunning" sendTimeout="00:10:00" />
</wsHttpBinding>
</bindings>
<client>
<endpoint name="Default"
address="http://localhost:8732/Design_Time_Addresses/PersistencyService/Service1/"
binding="wsHttpBinding"
bindingConfiguration="LongRunning"
contract="PersistencyService.IService1" />
</client>
<services>
<service name="PersistencyService.Service1">
<endpoint
address=""
binding="wsHttpBinding" bindingConfiguration=""
contract="PersistencyService.IService1" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/PersistencyService/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The exception message is An existing connection was forcibly closed by the remote host.
I must also add that I get about 70MB of data from the service
On the client side, you need to add some settings to your app.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="LongRunning" sendTimeout="00:10:00" />
</wsHttpBinding>
</bindings>
<client>
<endpoint name="Default"
address="....."
binding="wsHttpBinding"
bindingConfiguration="LongRunning"
contract="IYourServiceContract" />
</client>
</system.serviceModel>
You didn't give us much to go on - no config, nothing.... so I'm left just guessing what settings you might have.
Basically, you need to define a binding configuration for the type of binding you're using, and you need to increase the sendTimeout attribute on that binding configuration (here in my sample: 10 minutes). You cannot completely turn off the timeout - you can increase it, but not turn it off.
Then, your client side config must make a reference to that binding configuration you've defined, by specifying a bindingConfiguration="...." attribute on the <endpoint> configuration, and using the same name for the binding configuration as when you defined it.
Maybe this is enough - but maybe, you'll also need to increase some of the timeouts on the server side. Try this first - if it doesn't work, come back and ask again - and please, next time: provide us with some more useful info, like your code and config!
Every time my program runs vs adds the default configuration to my app.config file. At that run it works fine, but at the next run it actually tries to read the config.
The problem is that the default configuration has errors, it adds the attribute "Address", but attritbutes are not allowed to have capitals so it throws an exception.
This means I have to remove the bad section every run!
I've tried to configure the .config but it gives errors.
Here is the code that I use to host the server:
private static System.Threading.AutoResetEvent stopFlag = new System.Threading.AutoResetEvent(false);
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "ChessServer");
host.Open();
stopFlag.WaitOne();
host.Close();
Here is the client code that calls the server:
ChannelFactory<IChessServer> scf;
scf = new ChannelFactory<IService>
(new BasicHttpBinding(), "http://localhost:8000");
IService service = scf.CreateChannel();
Thanks for any help.
Edit: Sorry it took me so long, I've been trying to use DualWSHttpBinding instead (since I actually need the server to call client methods to anyway) but still generates the config file. Here's the entire auto-generated config file:
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Chess.ChessService">
<endpoint Address="" binding="wsHttpBinding" contract="Chess.IChessServer">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint Address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<Add baseAddress="http://localhost:8732/Design_Time_Addresses/Chess/ChessService/" />
</baseAddresses>
</host>
</service>
<service name="Chess.ChessClient">
<endpoint Address="" binding="wsHttpBinding" contract="Chess.IChessClient">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint Address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<Add baseAddress="http://localhost:8732/Design_Time_Addresses/Chess/ChessClient/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Visual Studio does not re-create the WCF configuration on every run. It will re-create the WCF configuration every time you do an Update Service Reference on your service reference in the project - but it definitely doesn't automatically do that before every run - there must be something else causing you grief here.
Furthermore, you're not connecting to the correct address - your server defines it here:
ServiceHost host = new ServiceHost(..., new Uri("http://localhost:8000"));
host.AddServiceEndpoint(..., .., "ChessServer");
and this results in your endpoint address on the server being
http://localhost:8000/ChessServer
However, you're client appears to attempt to connect to
http://localhost:8000/
and there's no service there.
A last point: if you set up all your things like endpoints, bindings etc. in code, any changes to the config shouldn't even bother you at all - there must be something else causing your problems.
You're quite mistaken. Attribute and element names may be upper or lower case.
What makes you think that the case of the attribute is the problem? And what makes you think that the app.config is changed on every run?
I am using VSTS 2008 + C# + .NET 3.0. I am using a self-hosted WCF service. When executing the following statement, there is the following "binding not found" error. I have posted my whole app.config file, any ideas what is wrong?
ServiceHost host = new ServiceHost(typeof(MyWCFService));
Error message:
Could not find a base address that matches scheme http for the
endpoint with binding MetadataExchangeHttpBinding. Registered base
address schemes are [https].
Full app.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyBinding"
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="100000000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession ordered="false"
inactivityTimeout="00:02:00"
enabled="true" />
<security mode="Transport">
<transport clientCredentialType="Digest"
proxyCredentialType="None"
realm="someRealm" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MyWCFService"
behaviorConfiguration="mexServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:9090/MyService"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="IMyService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
The base address for your service defines "HTTPS://" - but your mex address is "HTTP".
If you want your service to use https://, you'll need to use the mexHttpsBinding as well:
<services>
<service name="MyWCFService" behaviorConfiguration="mexServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:9090/MyService"/>
</baseAddresses>
</host>
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="MyBinding"
contract="IMyService"
/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"
/>
</service>
</services>
Marc
Can I go for the double score? :)
As you're using WS-Http you are binding to an HTTPS protocol, so you need to use the correct MEX binding;
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
I've asked a question in a comment for Marc_s answer
Is it possible to have IMetadataExchange for both http and https as
separate endpoints?
marc_s answered
you should be able to define a second base address, for http:// and
use that for the http mex endpoint.
So solution is to declare multiple endpoints with the SAME address="mex" and different bindings like the following
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex"/>
Recently I found that it's easier to have one configuration switch that can be used to enable MEX on test and disable on Live.
From http://msdn.microsoft.com/en-us/library/aa395224.aspx
It's possible to use the ServiceHostFactory class to create a custom
derived from ServiceHost in the Internet Information Services
(IIS custom ServiceHost that adds the ServiceMetadataBehavior, (which
enables metadata publishing), even if this behavior is not explicitly
added in the service’s configuration file.
Write the imperative code that enables metadata publishing once and
then reuse that code across several different services. This is
accomplished by creating a new class that derives from ServiceHost and
overrides the ApplyConfiguration() method to imperatively add the
metadata publishing behavior.
Example code from Custom Service Host MSDN article
//Add a metadata endpoint at each base address
//using the "/mex" addressing convention
foreach (Uri baseAddress in this.BaseAddresses)
{
if (baseAddress.Scheme == Uri.UriSchemeHttp)
{
mexBehavior.HttpGetEnabled = true;
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeHttps)
{
mexBehavior.HttpsGetEnabled = true;
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpsBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
{
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexNamedPipeBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
{
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
"mex");
}
}