Method Not Found in WCF service? - c#

I am newbie in creating WCF web service. I am using VS2012 with target framework 4.5. I have added a WCF Service file in my project.
In "IService.cs" I have written the following code
namespace _3TWebServ
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "Calculate")]
String Calculate(Inputs ip1);
}
[DataContract]
public class Inputs
{
[DataMember(Name = "Coil_type")]
public string Coil_type { get; set;}
[DataMember(Name = "Finned_length")]
public string Finned_length { get; set;}
}
}
and in "Service.svc.cs"
namespace _3TWebServ
{
public class Service1 : IService1
{
[DataMember]
public string input;
public String Calculate(Inputs ip1)
{
String str = ip1.Coil_type + ip1.Finned_length;
return str;
}
}
}
But the problem comes when I run my service its not showing my method Calulate, When I pass my URL as Following
localhost:2121/Service1.svc/Calculate it shows "method not allowed" error.
I have done some Googling and enabled my IIS manager Directory Browsing. My config file is following
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="_3TWebServ.IService1" name="_3TWebServ.Service1">
<endpoint address="" behaviorConfiguration="Rest" binding="webHttpBinding" contract="_3TWebServ.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!--endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="_3TWebServ.IService1">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="Rest">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

I can see a few possible issues.
Your Calculate method is set for a HTTP POST request. You should make a HTTP POST request to get proper response.
Your request format is JSON (RequestFormat attribute property value), so make sure your request body contains the parameters in JSON format ({ "Coil_type" : "type", "Finned_length": 12 }).
Why do you have the [DataMember] public string input on the service implementation? Service implementations should generally carry operation contracts.

Related

Dead simple WCF - 405 Method not allowed

As far as I can tell I have mimicked the accepted solutions of this post and this post. Unless I'm blind (and I hope I am at this point), I have a spotless app.config for my very simple WCF service:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RESTBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="Vert.Host.VertService.RSVPService">
<endpoint
address="/RSVP"
binding="webHttpBinding"
contract="Vert.Host.VertService.IRSVP"
behaviorConfiguration="RESTBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Vert" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Here's the corresponding Service Contract and Implementation:
namespace Vert.Host.VertService
{
[ServiceContract]
public interface IRSVP
{
[OperationContract]
bool Attending();
[OperationContract]
bool NotAttending();
}
public class RSVPService : IRSVP
{
public bool Attending()
return true;
public bool NotAttending()
return true;
}
}
I'm hosting everything via a console app:
class Program
{
public static void Main()
{
// Create a ServiceHost
using (ServiceHost serviceHost = new ServiceHost(typeof(RSVPService)))
{
serviceHost.Open();
// The service can now be accessed.
Console.ReadLine();
}
}
}
All I want to do is stand this tiny service up, but I can't hit this endpoint with http://localhost:8080/Vert/RSVP/Attending. I still get 405 Method not allowed as a response.I'm using Visual Studio Community 2015, IIS10, targeting .NET 4.6
Things I've tried from suggestions:
I've given my service an explicitly-named behavior. No luck.
What am I missing?
Honestly not sure if this will make the difference, but mine has a link to service behaviour. Give your service behaviour a name:
<serviceBehaviors>
<behavior name="ServiceBehavior">
Then link it to your service:
<service name="Vert.Host.VertService.RSVPService" behaviorConfiguration="ServiceBehavior">
Be sure to decorate the service methods with the [WebGet] attribute (reference System.ServiceModel.Web.dll)
I.e. changing the service from
public class RSVPService : IRSVP
{
public bool Attending()
return true;
public bool NotAttending()
return true;
}
to
public class RSVPService : IRSVP
{
[WebGet]
public bool Attending()
return true;
[WebGet]
public bool NotAttending()
return true;
}
Solves the issue.

Calling restful wcf web service bad request

My restful wcf web service is written in Visual Studio 2010.
This is the code in Service1.svc.cs
namespace ContactRegistration
{
public class Service1 : IService1
{
public string JSONDataPost(Contact ContactObject)
{
//code to put the data in the database goes here
//we'll pretend it all went okay and return
return "0|Data added okay";
}
}
}
This is the code in IService1.cs
namespace ContactRegistration
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/JSONDataPost",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string JSONDataPost(Contact ContactObject);
}
[DataContract]
public class Contact
{
[DataMember]
public string Organisation { get; set; }
[DataMember]
public string FirstName { get; set; }
public Contact(string organisation, string firstName)
{
this.Organisation = organisation;
this.FirstName = firstName;
}
}
}
Here is the web config.
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="ContactRegistration.Service1Behavior"
name="ContactRegistration.Service1">
<endpoint address="" binding="webHttpBinding"
contract="ContactRegistration.IService1" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ContactRegistration.Service1Behavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
When I call the web service from a web application the URI I am using is:
Uri address = new Uri("http://www.myserver/ContactRegistration/Service1.svc/JSONDataPost");
And I am getting a bad request 400 back from the server.
Is the [OperationContract] written correctly? Is there something wrong with the URITemplate? I have looked at dozens of examples today and they seem to have the URITemplate as '/NameOfMethod' which is what I have done.
EDIT: Bit of code to show the beginning of how it is called
Uri address = new Uri("http://www.myserver/ContactRegistration/Service1.svc/JSONDataPost");
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
// Create the data we want to send
Contact myContact = new Contact();
myContact.Organisation = "Society of Fruit Flies";
myContact.FirstName = "Fred";

500 Interval Server Error while accessing WCF service from http and Google Chrome Extension Simple REST Client

THis is the service which I created for Android device to post data but this service doesn't work for me. I called this service through an Android but nothing happens just received an error message of -500 in LogCat. I also check this service on HTTP and SIMPLE REST Client (Google Chrome Extension) but received an error message. Error message is given below. and this service is also published on IIS.
Error Message
The 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)
These are the params which im passing to the service:
{"mycar":{"Name":"a","Make":"gfgfd ","Model":"web "}}
and here is the service source code
namespace CarSercive
{
[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]
public class Service1 : IService1
{
// myCar test = new myCar();
public void UpdateMyCar(myCar mycar) {
string strConnectionString = ConfigurationManager.ConnectionStrings["Database1"].ConnectionString;
SqlConnection conn = new SqlConnection(strConnectionString);
conn.Open();
using (SqlCommand cmd = new SqlCommand("Insert into TestingTable (Name,Make,Model) Values (#Name,#Make,#Model)", conn)) {
cmd.Parameters.AddWithValue("#Name", mycar.Name);
cmd.Parameters.AddWithValue("#Make", mycar.Make);
cmd.Parameters.AddWithValue("#Model", mycar.Model);
int queryResult = cmd.ExecuteNonQuery();
} conn.Close();
}
}
}
web.config
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true" targetFramework="4.0">
</compilation>
<authentication mode="Windows"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
<system.serviceModel>
<services>
<service name="CarSercive.Service1" behaviorConfiguration="web">
<!-- Service Endpoints -->
<endpoint address="" binding="webHttpBinding" contract="CarSercive.IService1"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="web">
<!-- 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>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
IService1.cs
namespace CarSercive
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(
Method = "POST",
UriTemplate = "MyCar",
//BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
void UpdateMyCar(myCar mycar);
}
[DataContract]
public class myCar
{
[DataMember(Name = "Name")]
public string Name
{
get;
set;
}
[DataMember(Name="Model")]
public string Model
{
get;
set;
}
[DataMember(Name="Make")]
public string Make
{
get;
set;
}
}
}
You need to add a JSON endpoint to your web.config file.
<system.serviceModel>
<domainServices>
<endpoints>
<add name="JSON" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
make sure to link to the assembly Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory in your project

Is it possible to set up a WCF service as REST & SOAP this way?

Im trying to combine SOAP and REST under one roof with some modification. But I dont know whether its possbile. My code is below, it used to work when REST only but since I tried to add the extra web service as SOAP (using configuration) it doesnt work. Not sure how to configure it...
I have the interfaces:
[ServiceContract]
public interface IVLSContentServiceREST
{
[OperationContract]
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
[ServiceContract]
public interface IVLSContentServiceSOAP
{
[OperationContract]
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
Then I have a file called VLSContentService.svc with this:
<%# ServiceHost Language="C#" Debug="true" Service="VLSContentService" CodeBehind="VLSContentService.svc.cs" %>
And the cs(codebehind) file:
public class VLSContentService : IVLSContentServiceSOAP, IVLSContentServiceREST
{
string IVLSContentServiceSOAP.EchoWithGet(string s)
{
return "You said " + s;
}
string IVLSContentServiceSOAP.EchoWithPost(string s)
{
return "You said " + s;
}
string IVLSContentServiceREST.EchoWithGet(string s)
{
return "You said " + s;
}
string IVLSContentServiceREST.EchoWithPost(string s)
{
return "You said " + s;
}
}
And the configuration:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<!---Add the service-->
<services>
<service behaviorConfiguration="VLSContentServiceBehaviour" name="VLSContentService">
<endpoint address="rest" behaviorConfiguration="VLSContentServiceEndpointBehaviour" binding="webHttpBinding" contract="IVLSContentServiceREST"/>
<endpoint address="soap" behaviorConfiguration="VLSContentServiceEndpointBehaviour" binding="basicHttpBinding" contract="IVLSContentServiceSOAP"/>
</service>
</services>
<!---Add the behaviours-->
<behaviors>
<serviceBehaviors>
<behavior name="VLSContentServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<!---Add the behaviours-->
<endpointBehaviors>
<behavior name="VLSContentServiceEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
You don't need two versions of the contract - just host the same contract at two endpoints using different bindings
<services>
<service behaviorConfiguration="VLSContentServiceBehaviour" name="VLSContentService">
<endpoint address="rest" behaviorConfiguration="VLSContentServiceEndpointBehaviour" binding="webHttpBinding" contract="IVLSContentService"/>
<endpoint address="soap" behaviorConfiguration="VLSContentServiceEndpointBehaviour" binding="basicHttpBinding" contract="IVLSContentService"/>
</service>
</services>

Bad Request to RESTful WCF Service Forces IIS to Recycle App Pool

I am attempting to create and host a simple RESTful WCF Service. The service works perfectly except for 1 situation. I attempt to perform a POST to insert a new object into my static List using the JSON request of:
{"sampleItem":{"Id":1,"StartValue":2,"EndValue":3}}
If I then change the request to be:
{"sampleItemBlah":{"Id":1,"StartValue":2,"EndValue":3}}
I get a 500 response and all future POST's return a 500 error until I recycle my IIS App Pool and then it starts to work again.
It doesn't appear that the service is in a faulted state because I can still perform GET's and get data back. I turned on trace debugging and I do not see any errors in my log file.
Does anyone have any ideas?
Here is my Service Contract:
[ServiceContract]
public interface IWcfRestService
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
SampleItem Insert(SampleItem sampleItem);
}
[DataContract]
public class SampleItem
{
[DataMember]
public int Id { get; set; }
[DataMember]
public int StartValue { get; set; }
[DataMember]
public int EndValue { get; set; }
}
And here is my implementation:
public class WcfRestService : IWcfRestService
{
private static readonly List<SampleItem> Items = new List<SampleItem>();
public SampleItem Insert(SampleItem sampleItem)
{
return BaseInsert(sampleItem);
}
private static SampleItem BaseInsert(SampleItem sampleItem)
{
if (Items.Exists(x => x.Id == sampleItem.Id))
Items.RemoveAll(x => x.Id == sampleItem.Id);
Items.Add(sampleItem);
return sampleItem;
}
}
And finally here is my ServiceModel section of my Web.config:
<services>
<service behaviorConfiguration="Services.ServiceBehavior"
name="WcfRestServiceApp.WcfRestService">
<endpoint address=""
behaviorConfiguration="RESTBehavior"
binding="webHttpBinding"
contract="WcfRestServiceApp.IWcfRestService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RESTBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Services.ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Any and all help is greatly appreciated.
It turned out that the problem was with using the tag:
BodyStyle = WebMessageBodyStyle.Wrapped
When I removed it, the requirement to have:
{"sampleItem":{"Id":1,"StartValue":2,"EndValue":3}}
turned into:
{"Id":1,"StartValue":2,"EndValue":3}
This forced the cast to the correct object type and if the field wasn't present, it set the value to null or the type's default empty value.

Categories