WCF RESTFul Service - 404 with endpoint not found with 2 services - c#

I have two WCF services Exchange1.svc and Exchange2.svc both setup to be RESTful JSON consummables. Exchange1.svc works fine, but when I try to post to Exchange2.svc, I get an Endpoint not found message.
What am I doing wrong?
My IExchange2 interface is:
[ServiceContract]
public interface IExchange2
{
[System.ServiceModel.OperationContract(Name = "InsertReading")]
[WebInvoke(UriTemplate = "/InsertReading?memberID={memberID}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
void InsertReading(string memberID);
}
The URL I'm trying to hit is: http://localhost:49701/Exchange2.svc/DiaInsertReading?memberID=6519548
My config is:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyNamespace.Exchange1Behavior">
<webHttp/>
</behavior>
<behavior name="MyNamespace.Exchange2Behavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.Exchange1">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyNamespace.Exchange1Behavior" contract="MyNamespace.IExchange1" />
</service>
<service name="MyNamespace.Exchange2">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyNamespace.Exchange2Behavior" contract="MyNamespace.IExchange2" />
</service></services></system.serviceModel>

I have edited my post since the answer did not help. Since you are hosting in IIS with svc you don't need to set an address in your binding as I was saying in my previous answer. The baseaddress will be the location of you server. Ex: http://localhost:49701/Exchange2.svc. If you hit this address you should get to a WCF Service webpage.
Since you are using POST method you can send the data in the request body. If you have fiddler installed, in the composer you can set the method to post and address to http://localhost:49701/Exchange2.svc/InsertReading if this is your address to your service.
In the body of the request body you set { memberID:"123" } change 123 to whatever value you want to send to your service.
Or you can send the data in the address like: http://localhost:49701/Exchange2.svc/InsertReading?memberID=123
If you now execute your request it should return a response 200 OK.

In web.config file specify your endpoint
<service name="MyNamespace.Exchange2">
<endpoint address="Exchange2" binding="webHttpBinding" behaviorConfiguration="MyNamespace.Exchange2Behavior" contract="MyNamespace.IExchange2" />
Then, add this end point in your URL as:
http://localhost:49071/Exchange2/DiaInsertReading?memberID=6519548

Related

Creating HTTPS secure soap web service in asp.net that requires certificate to be invoked

I am trying to create a soap web service that will have one web method which takes name as input and will return "hello "+name over HTTPS and will require some certificate to be added in order to be invoked.
I have created a self signed certificate in IIS and have added HTTPS binding with certificate. I have added my application under default web site and have enabled SSL on it.
In the visual studio, I have created WCF service application, enabled SSL on it. Added asmx file that contains only one method in class. Here is the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace POCSoap
{
[WebService(Namespace = "https://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld(string name)
{
return "Hello "+name;
}
}
}
I have added binding and service declaration to web.config as well.
<services>
<service name="POCSoap.Service1">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="POCSoap.IService1"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Still, Call through http is working and call through https is not working. What is missing here.
WCF service is a web service other than XML web service(ASMX). They are different web service specification.
In order to make WCF service work over HTTPS, we should define a service endpoint with transport security like you do and the service contract, service implementation. Moreover, An Https binding in IIS site binding is required for working over HTTPS.
IService.cs
namespace POCSoap
{
[ServiceContract]
public interface IService1
{
string HelloWorld(string name);
}}
Service1.cs
public class Service1 : IService1
{
public string HelloWorld(string name)
{
return "Hello " + name;
}
However, the invocation is completed by a client-side proxy instead of directly sending an HTTP request.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client#add-service-reference-in-visual-studio
As for the ASMX service, we need to call it with a client proxy either. therefore, I would like to know why the call through https is not working when you have already added an https binding in IIS.
To create a Rest API in WCF, which can directly called with a simple Http request(http verb,request body), we need to change the way to create the WCF service.
<system.serviceModel>
<services>
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1" behaviorConfiguration="rest"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
At last, what do you mean that requiring certificate to be invoked? you want to authenticate client with a certificate, is that correct? This depends on which web service you use, WCF service or Xml web service.
Feel free to let me know if there is anything I can help with.

Adding a new WCF service to an existing project

I'm adding a new WCF service to a project, but the new one doesn't act the same as the old one.
Each has a similar SVC file:
<%# ServiceHost Language="C#" Debug="true" Service="Company.Project.Service1" %>
Each has an Interface that defines the ServiceContract and OperationContracts:
[ServiceContract]
[ServiceKnownType(typeof(Service1))]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "json/method1", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
ResponseObject Method1(RequestObject req);
}
Each is defined in the web.config file:
<service name="Company.Project.Service1" behaviorConfiguration="ServiceBehavior">
<endpoint address="rest" binding="webHttpBinding" contract="Company.Project.IService1" behaviorConfiguration="web"/>
<endpoint address="soap" binding="basicHttpBinding" contract="Company.Project.IService1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
However, when I visit the URL for the original service in one of my pre-production environments using Chrome, I see the "Method Not Allowed" error I expect (since I'm using GET).
When I visit the new service, I get a 404 error:
Server Error in [Snipped]
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /[Snipped]/Service2.svc/rest/json/method2
The other oddity is that it worked in my previous pre-production environments, so it could just be something in the deployment process.
Make sure you have routing defined in your Global.asax file for the new service that you have added in existing project. This could be easily missed and resulting in unable to locate resource via Asp.net pipline in hosting environment.
So, if you have new version of service ,let say ApiService2, you would require to add an entry like:
routes.Add(new ServiceRoute("api2", new ServiceHostFactory(), typeof(ApiService2)));
I observed that your method is called Method1 but you are trying to get to the method2
Does your web config also have a section for endpointBehavior like the following. You need this to enable REST endpoints for your webHttpBinding . You should probably add a service behavior as well
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="web">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>

Error creating wcf .svc service

I have created following svc service given below-
public class NewsRest : INewsRest
{
public string getHomePageNews1()
{
DataTable dt = new DataTable();
try
{
dt = new ManageNews().getHomePageNews1();
string json = new Utills().dataTableToJsonString(dt);
json = json.Replace("task-photo-846b6edc-3b2e-4ff6-ba10-734d64143c1d.png", "task-photo-8d5feed4-d6a1-4ae9-9a72-387ccfda1dc5.jpg");
return json;
}
catch (Exception ex)
{
return "{}";
}
}
}
[ServiceContract]
public interface INewsRest
{
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
string getHomePageNews1();
}
and web config configuration is-
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewsRestBehavior">
<serviceMetadata httpGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="UPNews.WebServices.NewsRest" behaviorConfiguration="NewsRestBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="UPNews.WebServices.INewsRest" />
<endpoint address="mex" binding="mexHttpBinding" name="MetadataEndpoint"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
but when I am testing this service on WCF test client it gives following error.-
Error: Cannot obtain Metadata from http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1
If this is a Windows (R) Communication Foundation service to which you have access,
please check that you have enabled metadata publishing at the specified address.
For help enabling metadata publishing,
please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error
URI: http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1 Metadata contains a reference that cannot be resolved:
'http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1'. Content Type application/soap+xml;
charset=utf-8 was not supported by service http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1.
The client and service bindings may be mismatched. The remote server returned an error:
(415) Unsupported Media Type.HTTP GET Error URI: http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1 There was an error downloading
'http://localhost:57358/WebServices/NewsRest.svc/getHomePageNews1'. The request failed with HTTP status 400: Bad Request.
Please tell whats wrong happening here.
You must add to your server configuration to allow MEX (meta data exchange) so that the client can retrieve the generated WSDL. Something like this:
<service name="UPNews.WebServices.NewsRest" behaviorConfiguration="NewsRestBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="UPNews.WebServices.INewsRest" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

invoke WCF service method from web browser

I want to run my service from the web browser: http://localhost:443/TestService//RunTest/data/test
It doesn`t work for me
This page can’t be displayed
•Make sure the web address http://localhost:443 is correct.
•Look for the page with your search engine.
•Refresh the page in a few minutes.
How to solve that - redefine endpoint - how?
The WCF service:
//TestService.svc.cs
public class TestService : ITestService
{
public string RunTest(string data)
{
return string.Format("You entered: {0}", data);
}
}
//ITestService.cs
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/RunTest/data/{data}")]
string RunTest(string data)
{
return string.Format("You entered: {0}", proxyDomain);
}
//Web.config
<system.serviceModel>
<services>
<!-- This section is optional with the default configuration introduced
in .NET Framework 4.5.1 -->
<service
name="TestService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:443/TestService/"/>
</baseAddresses>
</host>
<endpoint address="http://localhost:443/TestService"
binding="wsHttpBinding"
contract="ITestService" />
</service>
</services>
</system.serviceModel>
Also when I run it a WCF client is opened with port 54388
In my experience, you wouldn't be able to test directly via the browser.
Instead you should use a WCF Test Client:
http://msdn.microsoft.com/en-us/library/bb552364(v=vs.110).aspx
What you can do using your browser, is to see if you can reach the WSDL.
An example of a WSDL call in a browser:
http://localhost:8080/DecisionService/ws/PreTradeChecksRuleApp/1.0/PreTradeChecks/1.0?WSDL
You should add/change the endpoint "binding" attribute to "webHttpBinding" like this:
<endpoint address="http://localhost:443/TestService"
binding="webHttpBinding"
contract="ITestService" behaviorConfiguration="web" />
Or
<endpoint address="http://localhost:443/TestService"
binding="wsHttpBinding"
contract="ITestService" />
<endpoint address="http://localhost:443/TestService/web"
binding="webHttpBinding"
contract="ITestService" behaviorConfiguration="web"/>
In Both Cases you Have to Add:
<behaviors>
...
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
...
</behaviors>
notes:
1) You have to add the attribute behaviorConfiguration to the webBinding and Add the behavior configuration
2) In the second solution, You have to change the name of the baseAddress because you can't have two endpoints configured to the same baseAddress (if anyone knows how to do it, please it would help me too)
Best Regards

There was no channel actively listening

maybe you can help me set up my WCF service.
First, here is my config file:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings />
<services>
<service name="AuthenticatorService.Authenticator">
<endpoint address="auth" binding="basicHttpBinding" bindingConfiguration=""
name="AuthEndpoint" contract="AuthInterface.IAuthenticator" />
<endpoint address="mex" binding="mexHttpBinding" name="MetadataEndpoint"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
And this is how I call my service from c#:
//This creates a link to the WCF service using basicHttpBingind
httpFactory = new ChannelFactory<IAuthenticator>(new BasicHttpBinding(), new EndpointAddress("http://myUrl/auth.svc"));
httpProxy = httpFactory.CreateChannel();
It worked fine when I was doing this on localhost but now it keeps telling me no endpoint was found.
Also, the server generated the following error:
System.ServiceModel.EndpointNotFoundException: There was no channel actively listening at 'http://myURL/auth.svc/$metadata'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening.
Im really confused, I have no idea why this is happening. Do I need to create another service file for the metadata exchange?
Do I need to set a baseAddress?
Thanks
How did you deploy the service? I assume the service is running in IIS on your box - did you try hitting the service URL (http://myUrl/auth.svc) in a browser to see if it is indeed up?

Categories