Using REST GET in WCF as 2nd endpoint - c#

I trying to add 2nd endpoint in existing WCF Application and my REST method doesn't work.
I created new Interface
[ServiceContract]
public interface IRestService
{
[OperationContract]
[WebGet(UriTemplate = "RestURI", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string SomeMethod();
}
And implemented it in existing service
public string SomeMethodImplementation()
{
//some logic
}
I'm trying to access this method using basicaddress/service/RestURI but getting 400 Bad Request response.
After that I added protocolMapping, 2nd endpoint and endpoint behavior to config file but it didn't help.
Right now my config file looks like this:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="servicename">
<endpoint address="" binding="webHttpBinding" contract="IRestService" behaviorConfiguration="web"/>
<endpoint address="" binding="basicHttpBinding" contract="ISoapService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16348" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
</binding>
</basicHttpBinding>
</bindings>
I'm not getting any 400 anymore but instead of that 'cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.' error appeared. Also after adding protocolMapping, my soap methods have disappeared when I open wsdl in browser. Without it my rest method can be seen in the list like this:
<wsdl:port name="BasicHttpBinding_IRestService" binding="i0:BasicHttpBinding_IRestService">
After that I added AddressFilterMode = AddressFilterMode.Any) in attributes of my Service but it doesn't help.
I found a lot of answers here but somehow not a single one help me to resolve this problem.
What did I miss?

I found the solution after I installed WCF for visual studio. All this time I had wrong namespaces in my web.config and had no idea but VS marked it after installing module. I added right namespace and problem went away. I really suggest to install WCF in VS.

The issue boils down to the fact that we fail to host the service in Restful style.
Ordinarily, there are two ways to configure the Restful style service created by Webhttpbinding.
1.Using the service section to configure the interface and implementation.
<services>
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1" behaviorConfiguration="rest"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
There are two points we should pay attention to. In the service section, we are supposed to use the corresponding interface and implementation.
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1"
Adding a webhttp endpoint behavior also is essential then apply it by using Behaviorconfiguration property.
behaviorConfiguration="mybinding"
In the latest feature, we could create a WCF Restful style service with protocol mapping.
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http"/>
It should be noted that we need to add an endpoint behavior without a name.
Based on your configuration, since you have multiple interfaces I suggest you remove the service section and host the service with a protocol mapping feature.
1. Remove service section in the configuration.
2. Remove the name of the endpoint behavior.
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
Then we could access the service by the below Uri.
basicaddress/service.svc/RestURI
Feel free to let me know if there is anything I can help with.

Related

Creating a wcf web service and returning the xml response in android

I am an android developer. I want to create an android application which fetches the xml response from a WCF web service using soap. I have created a WCF web service, in which it fetches the XML document and return the content of that document. Here I dont know how to consume that content in android. Moreover, I am new to WCF and I am confused whether I am doing it right or wrong. Any help would be appreciated.
IService.cs
namespace WcfXML
{
[ServiceContract (Namespace="http://tempuri.org/")]
public interface IService1
{
[OperationContract, XmlSerializerFormat]
XmlElement GetData();
}
}
Service1.svc
namespace WcfXML
{
public class Service1 : IService1
{
public XmlElement GetData()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"D:\defaultGraphProperties.xml");
return xmlDoc.DocumentElement;
}
}
}
After creating this, when I run(F5), I am not able to invoke the method. How can I consume this web services in android? Please Help!!!!
You need to add configuration for webHttpBinding in web.config under the <Bindings>.
Then add the below code in web.config under the <System.serviceModel>
<services>
<service name="Test_WcfService.Service1" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingConfiguration" behaviorConfiguration="web" contract="Test_WcfService.IService1"></endpoint>
<endpoint address="Service1.svc" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" contract="Test_WcfService.IService1"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingConfiguration" maxReceivedMessageSize="2147483647" />
</webHttpBinding>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration" maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
After doing this changes in web.config you will be able to consume the wcf service from Browser.
Replace the Test_WcfService.Service1 and Test_WcfService.IService1 with your WCF Service name and interface.
To consume the WCF Service , you will have to do a Soap Request from Android.
Also if possible share your demo wcf service i will make the necessary configuaration changes at my end.

Defining baseURL and EndPoint

I made a WCF with three methods:
[ServiceContract]
public interface IService1
{
[OperationContract]
String devolverPisosA();
[OperationContract]
String devolverPisosV();
[OperationContract]
String devolverNoticias();
}
I need to define baseAddress and EndPoint in Web.config file but I don´t know how:
I´m trying this (and some variations) but this is not working... (between system.serviceModel)
<services>
<service
name="ProyectoJosephWCF.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Iservice1/"/>
</baseAddresses>
</host>
<endpoint address="devolverPisoA"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
<endpoint address="devolverPisoV"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
<endpoint address="devolverNoticias"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
</service>
</services>
EDITED: If I´m not defining the baseAddress and endpoint before (using default configuration which was created when I created the project), and I launched the Services1.svc, I can reach the result json through testing windows but I can´t (or at least I don´t know how) to reach that JSON result from Android (by Retrofit). I supposed that I configured Retrofit (baseAddress and Endpoint values wrong), so I decided to set those values by my own...
For that I set the code before in Web.config, but I can´t reach them as well...
Beside, I would like to reach JSON result by Mozilla (in browser I mean), because someone said me that could me help to understand what baseAddress and Endpoint I´m using...
EDITED2: Behaviors are settings as:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
And still don´t reach result by android or browser...
You need to set httpGetEnabled="true" for having WSDL available like below
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Include the same behavior configuration in your service declaration like
<service name="ProyectoJosephWCF.Service1"
behaviorConfiguration="NewBehavior">
See serviceMetadata for more information.
Finally... Check it out if you need it.
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
And:
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "devolverPisoA")]
List<pisosAlquiler> devolverPisosA();

Having trouble connecting to a web service with a windows 8.1 phone app

This is my first time doing something like this so I'm probably going to sound stupid but here it goes.
Here is my method that is supposed to connect to the web service.
public async void getWebData()
{
var uri = new Uri("http://localhost:9011/Service.svc?singleWsdl");
var httpClient = new HttpClient();
// Always catch network exceptions for async methods
try
{
var result = await httpClient.GetStringAsync(uri);
doSomething(result);
}
catch
{
// Details in ex.Message and ex.HResult.
}
// Once your app is done using the HttpClient object call dispose to
// free up system resources (the underlying socket and memory used for the object)
httpClient.Dispose();
}
Here is my config info from the web.config file where I believe I added the rest endpoint correctly because I read that you have to use a rest endpoint to access web services in windows 8.1 phone apps.
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" />
</basicHttpBinding>
<webHttpBinding>
<binding name="WebHttpBinding_IService" />
</webHttpBinding>
</bindings>
<services>
<service name="WcfService.Service1" behaviorConfiguration="MyServiceBehavior">
<endpoint address="http://localhost:9011/Service.svc?singleWsdl" name="rest"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding_IService" contract="WcfService.IService" />
<endpoint address="http://localhost:9011/Service.svc?singleWsdl" name="soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService" contract="WcfService.IService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
So can anyone tell me what I'm doing wrong to access my webservice because nothing I try has been working...

WCF NetNamedPipeBinding Service NorthwindService example vs MyService

I have complete exhausted resources on trying to get NetNamedPipeBinding for my WCF Service working. I was able to get the NorthwindService example working found here.
For the NorthwindService example, I have the following:
namespace NorthwindServices
{
public class Customer : ICustomer
{
public string GetCustomerName(int CustomerID)
{
return CustomerID.ToString();
}
}
}
namespace NorthwindServices
{
[ServiceContract]
public interface ICustomer
{
[OperationContract]
string GetCustomerName(int CustomerID);
}
}
And the configuration for the example is the following:
<system.serviceModel>
<services>
<service name="NorthwindServices.Customer"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/NorthwindServices/Customer"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="CustomerService" binding="netNamedPipeBinding" contract="NorthwindServices.ICustomer"/>
<endpoint address="CustomerService/mex" binding="mexNamedPipeBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="False" httpsGetEnabled="False"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
I have an IIS Site defined for this with the details below:
So when I go to 'Add Service Reference' I can pull in the reference perfectly fine.
However, when I try to do the same in my actual application, I still cannot seem to figure it out. I am unable to pull in the reference.
The site structure is the following:
The top level site is an MVC site, and there is an "API" virtual directory below it where the service resides that I am trying to expose over NetNamedPipeBinding.
The bindings for the site are the following:
The config for the service I am trying to expose over named pipes is the following:
<system.serviceModel>
<services>
<service name="Site.API.Service.WorkItemQueueService"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/WorkItemQueueService"/>
</baseAddresses>
</host>
<endpoint address="QueueService"
binding="netNamedPipeBinding"
contract="Site.API.Service.IWorkItemQueueService"/>
<endpoint address="QueueService/mex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="True" aspNetCompatibilityEnabled="True"/>
The service implementation is the same as the customer service above, but obviously renamed to match the configuration above.
When I try to add a service reference, or find the metadata for this, It cannot find it.
IMPORTANT - All of the pre configuration items such as starting the Net Pipe listerner and role service have been completed, hence the NorthwindServices example works.

Error: Cannot obtain Metadata from WCF service

I have a successfully running WCF service that I can call using javascript. However I want to invoke it using the WCF test client and im having difficulty doing this. I am told that I need to make sure I have enabled meta data publishing at the specified address. After reading the documentation I just cant see what im meant to do this is my configuration:
<system.serviceModel>
<services>
<service name="CommentSessionIDWCFService"
behaviorConfiguration="CommentSessionIDBehavior">
<endpoint
address=""
behaviorConfiguration="CountryProvinceBehavior"
binding="webHttpBinding"
contract="ICommentSessionIDWCFService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CommentSessionIDBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="CountryProvinceBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I've read other posts but I can't see what to populate and I just keep getting errors. Q's..
Am I right in saying that I need to configure a complete new service in my config to show the metadata?
What do I add to the configuration to make this meta data published so I can invoke with the client?
You need a metadata endpoint for your service, here`s an example.
<services>
<service name="MyService" behaviorConfiguration="MEX">
<endpoint
address="http://localhost:8000/MEX"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX">
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
I had a similar problem after changing the config file in the TestClient with right click and "edit with svceditor" to increase my maxbuffersize. If someone did that mistake as well, try rebuilding your project.
Add
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
Set httpGetEnabled to true and set the includeExceptionDetailInFaults to false:
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>

Categories