explanation of system.servicemodel endpoint.address element for rest service - wcf

I have a WCF rest webservice. It is working fine. I am wanting to understand the different configuration values available within the endpoint element.
In particular, I'm trying to understand the purpose of the address element. Changing the value doesn't seem to change how I can address the service. For this, I'm running the service from visual studio 2010 and cassini. the port number is set to 888.
with address set to an empty string i get...
http://localhost:888/restDataService.svc/hello will return "hello world".
with address set to "localhost" i get...
http://localhost:888/restDataService.svc/hello will return "hello world".
with address set to "pox" i get...
http://localhost:888/restDataService.svc/hello will return "hello world".
It doesn't matter what value I set into the address field. It doesn't impact the url. My only explanation that I have is that the value is more for non-REST services.
<system.serviceModel>
<services>
<service behaviorConfiguration="MobileService2.DataServiceBehaviour" name="MobileService2.DataService">
<endpoint address="pox" binding="webHttpBinding" contract="MobileService2.IRestDataService" behaviorConfiguration="webHttp">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MobileService2.DataServiceBehaviour" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I also have the following service contract
[ServiceContract]
public interface IRestDataService
{
[OperationContract]
[WebGet(UriTemplate = "hello")]
string Hello();
}
And in the .svc
<%# ServiceHost Language="C#" Debug="true"
Service="MobileService2.RestDataService"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
CodeBehind="RestDataService.svc.cs" %>
And the 'code-behind'
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestDataService : IRestDataService
{
public string Hello()
{
return "hello";
}
}

Can you also show service element of your configuration? I think that your configuration is not used or you are accessing other instance of the application (did you configure Cassini to use port 80?) because your second and third test should return HTTP 404 Resource not found.
Correct addresses for your tests are:
http://localhost/restDataService.svc/hello
http://localhost/restDataService.svc/localhost/hello
http://localhost/restDataService.svc/pox/hello
Check that your name in service element is exactly the same as name of service type (including namespaces) as used in ServiceHost directive in .svc markup.

Related

WCF Service Error 400 Bad Request In VS2017

I have a very simple WCF Service Project in VS2017. But I keep getting error 400 when I try to visit the endpoints. I have read the other questions posted here about the same issue and I have tried them with no luck so far.
My Service Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetData/{value}")]
string GetData(string value);
}
My Service:
public class Service : IService
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
My Web.Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myBehavior" name="WCGFService1.Service">
<endpoint address="" contract="WCGFService1.IService" binding="webHttpBinding">
</endpoint>
</service>
</services>
When I visit http://localhost:61648/Service.svc/GetData/12, I get HTTP 400 Bad Request. I've tried with browser and POSTman. What am I doing wrong?
I am using VS2017. My IService.cs and Service.cs are inside the App_Code folder whereas the
Service.svc is in the root folder. Also, when I try to add the name & contract in web.config, VS2013 suggests me the namespace and the interface/class name, whereas, VS2017 is not suggesting me anything so I have to manually type it.
Also, in VS2013, the Interface and Class were located in the root folder instead of the App_Code folder. The project is a WCF Application in VS2017. My .NET Version is 4.5.2.
Fixed it, had a few problems in the web.config file:
<system.serviceModel>
<behaviors>
<!-- Fix 1: Added a endpointBehavoir with webHttp -->
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- Fix 2: Instead of using the full name (WCGFService1.Service), used just the class name (Service) -->
<service behaviorConfiguration="myBehavior" name="Service">
<!-- Fix 3: Same thing here, used just the IService instead of full name, also, used the aforementioned endpointBehavoir -->
<endpoint address="" contract="IService" binding="webHttpBinding" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
That did it for me, for whatever reason, in VS2013, it would not work if you don't provide the full name (namespace and class/interface name) but in VS2017, it works only if you provide just the class/interface name.

How to return an xml response from a WCF Service

I'm not fluent in WCF Services so I'm struggling to return XmlElement as the return type.
I'm getting the message from the WCF Test Client (running in debug mode):
The operation is not supported from the wcf test client because it uses type XmlElement.
[ServiceContract]
public interface IClientService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
XmlElement GetClientXml(int value);
}
namespace testWCF
{
public class testSvc: IClientService
{
public XmlElement GetClientXml(int value)
{
string appDir = AppContext.BaseDirectory;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(appDir + #"Xml\ResponseTempl.xml");
return xDoc.DocumentElement;
}
}
}
I've referred to this as well but it might be too old, as I'm using 4.6.1 framework: Returning XML From a WCF Service
my Web.Debug.config file :
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
</system.web>
<system.serviceModel>
<services>
<service name="AucklandRegionalPatientWCF.PatientDemographicService" >
<!-- these endpoint are necessary to return SOAP service -->
<endpoint address=""
binding="basicHttpBinding"
contract="AucklandRegionalPatientWCF.IPatientDemographicService" />
<endpoint address="mex"
contract="IMetadataExchange" binding="mexHttpBinding"/>
<!-- REST service return xml -->
<!--To call this endpoint use: [service].svc/xml/[method_Name]-->
<endpoint address="xml"
binding="webHttpBinding" behaviorConfiguration="xmlBehavior"
contract="AucklandRegionalPatientWCF.IPatientDemographicService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<!-- use XML serialization -->
<behavior name="xmlBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Best way to get XML element from WCf as response use XML formatted string.. Best at performance as well as light weight.....
Create response class and use XML serialization.... It will be helpful

Metadata publishing for this service is currently disabled - Again

I'm new to WCF and I've been hitting my head for the past week trying to get everything to work. When browsing the service.svc file I receive the message about the metadata not being enabled. There's hundreds of posts on this but I must be missing something. I think I followed the instructions correctly but I still can't find my error. Where am I going wrong? Any help is appreciated.
service.svc
<%# ServiceHost Service="BiteSizeLearningWS.TranscriptService" Debug="true" %>
web.config
<services>
<service name="BiteSizeLearningWS.iServiceInterface" behaviorConfiguration="TranscriptServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="BiteSizeLearningWS.TranscriptService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TranscriptServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
ServiceContract
namespace BiteSizeLearningWS
{
[ServiceContract (Name="TranscriptService")]
public interface iServiceInterface{...
Implementation
public class TranscriptService : iServiceInterface
Global.asax
namespace BiteSizeLearningWS
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("TranscriptService", new WebServiceHostFactory(), typeof(TranscriptService)));
}
I think you have your:
<service name="BiteSizeLearningWS.iServiceInterface"...
name attribute value and the
<endpoint address="" ... contract="BiteSizeLearningWS.TranscriptService" />
contract attribute value mixed up. Try this:
<service name="BiteSizeLearningWS.TranscriptService"...
and
<endpoint address="" ... contract="BiteSizeLearningWS.iServiceInterface" />
If that works, then what happened is that WCF used the automatic default configuration values for the service instead of the invalid configuration shown in the question. The metadata endpoint is not enabled by default which would be why you're seeing the "disabled" message.

how to access multiple endpoints

I have created a test WCF service WcfSampleLib with contract as IWcfSampleLib and ny service class is clsWcfSampleLib.
namespace WcfSampleLib
{
public class clsWcfSampleLib:IWcfSampleLib
{
public string getMsg(string name)
{
return " HI " + name;
}
}
[ServiceContract]
public interface IWcfSampleLib
{
[OperationContract]
string getMsg(string name);
}
}
Now I have added a window form application to host my WCF. I have created a App.config as
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Beh">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://{server}:9097"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name ="WcfSampleLib.clsWcfSampleLib" behaviorConfiguration="Beh">
<endpoint address="http://{server}:9096/SomeName" binding="basicHttpBinding" contract ="WcfSampleLib.IWcfSampleLib"/>
<endpoint address="net.tcp://{server}:9095/SomeName1" binding="netTcpBinding" contract ="WcfSampleLib.IWcfSampleLib"/>
</service>
</services>
</system.serviceModel>
</configuration>
I have two endpoints to use WCF from two different clients with different end point.
I have added following lines of code in Form1_Load event of Host Application
host = new ServiceHost(typeof(WcfSampleLib.clsWcfSampleLib));
host.Open();
MessageBox.Show("started");
Now I can add reference of service with http://{server}:9097 only. Is there any way so that I can use both endpoints with different URL means net.tcp://{server}:9095/SomeName1 and http://{server}:9096/SomeName

How to use a WCF service with HTTP Get (within Visual studio 2010)

We've tried to use a very very simple WCF service with a HTTp Get and we can't get it work.
We've followed those "guide" but it doesn't work
http://msdn.microsoft.com/en-us/library/bb412178.aspx
http://www.dotnetfunda.com/articles/article779-simple-5-steps-to-expose-wcf-services-using-rest-style-.aspx
When we call our service with the following url, we get a page not found error:
http://localhost:9999/Service1.svc/GetData/ABC
The base url (http://localhost:9999/Service1.svc) works fine and returns the wcf service information page correctly.
Those are the steps and code to reproduce our example.
In Visual Studio 2010, create a new "WCF Service Application" Project
Replace the IService interface with this code
[ServiceContract()]
public interface IService1
{
[OperationContract()]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "GetData/{value}")]
string GetData(string value);
}
Replace the Service class with this code
public class Service1 : IService1
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
The web.config look like this
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Service1">
<endpoint address="" binding="webHttpBinding" contract="IService1" behaviorConfiguration="WebBehavior1">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior1">
<webHttp helpEnabled="True"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
Press Run and try to call the Get method
If someone get this or something similar working, it would be very kind if you could reply information about the working example.
Thank you very much
I recreated your sample - works like a charm.
One point: do your service contract (public interface IService1) and service implementation (public class Service1 : IService1) exist inside a .NET namespace??
If so, you need to change your *.svc and your web.config to include:
<services>
<service name="Namespace.Service1">
<endpoint address="" binding="webHttpBinding"
contract="Namespace.IService1"
behaviorConfiguration="WebBehavior1">
</endpoint>
</service>
</services>
The <service name="..."> attribute and the <endpoint contract="..."> must include the .NET namespace for this to work.