I am working on wcf first time so created just sinple wcf ,problem is when i run service from visual studio its working fine but when i deploy it on iis it giving HTTTP 500 Error
my web config file is as below
<?xml version="1.0"?>
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<httpRuntime/>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>
<system.serviceModel>
<services>
<service name="WcfService2.Service1" behaviorConfiguration="servicebehavior">
<endpoint address="" binding="webHttpBinding" contract="WcfService2.IService1" behaviorConfiguration="web"/>
</service>
</services>
<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>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
and svc file is as below
namespace WcfService2
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
public string JSONData(string id)
{
return "you requested prduct" + id ;
}
public void DoWork()
{
}
}
}
and interface is as below
namespace WcfService2
{
// 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 = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/json/{id}")]
string JSONData(string id);
void DoWork();
}
}
https://stackoverflow.com/a/11460220/2211593
my iis server was not having feature of HTTP activation enabled so after lot of googling i found this solution. very useful for me i spent almost half of day to find the solution of this small issue
Related
I created a basic WCF REST service with default methods.
It is working when i request for svc file, but it returns 404 error while placing a request with rest parameters.
i.e. it gives response when i call http://localhost/FirstWCFRestApp/RestServiceImpl.svc but returns 404 error when i called http://localhost/FirstWCFRestApp/RestServiceImpl.svc/xml/12.
It is very basic service with only 1 method and confusing me as why its not working.
I have pasted the code below.
Please let me know where it went wrong and why its not working.
Interface`
using System.ServiceModel;
using System.ServiceModel.Web;
namespace FirstWCFRestApp
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IRestServiceImpl" in both code and config file together.
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method="Get",UriTemplate="/xml/{id}",RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json)]
string DoWork(string id);
}
}
Class File`
namespace FirstWCFRestApp
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "RestServiceImpl" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select RestServiceImpl.svc or RestServiceImpl.svc.cs at the Solution Explorer and start debugging.
public class RestServiceImpl : IRestServiceImpl
{
public string DoWork(string id)
{
return "You requested Id is "+ id;
}
}
}
SVC file
<%# ServiceHost Language="C#" Debug="true" Service="FirstWCFRestApp.RestServiceImpl" CodeBehind="RestServiceImpl.svc.cs" %>
Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior name="FWRBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="htBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="FirstWCFRestApp.RestServiceImpl" behaviorConfiguration="htBehaviour">
<endpoint address="Stud" binding="webHttpBinding"
contract="FirstWCFRestApp.IRestServiceImpl" behaviorConfiguration="FWRBehaviour"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
The address http://localhost/FirstWCFRestApp/RestServiceImpl.svc is the service metadata address.
The practical service address should base on the UriTemplate property and the Address property of the service address.
UriTemplate="/xml/{id}"
binding="webHttpBinding"
contract="FirstWCFRestApp.IRestServiceImpl" >behaviorConfiguration="FWRBehaviour">
In addition, the Method property of the WebInvoke should be capitalized.
[WebInvoke(Method ="GET",ResponseFormat =WebMessageFormat.Json,UriTemplate ="/xml/{id}")]
In summary, the service address should be,
http://localhost/FirstWCFRestApp/RestServiceImpl.svc/Stud/xml/12
Feel free to let me know if there is anything I can help with.
Like Abraham said:
Web Invoke Format:{SVC Path}/{webHttpBinding Endpoint Address}/{WebInvoke UriTemplate}
In your case, it should be:
http://localhost/FirstWCFRestApp/RestServiceImpl.svc/Stud/xml/12
Was trying alot and brows-ing around but I fail to figure out what is wrong with my WCF service.
What I am trying to acchive:
I am builindg a WCF that would expose some data as a json structure over HTTP
I will evenutally use that in an andorid app to show the data.
The mockup:
1.) The interface:
namespace WcfSyncDBService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ISyncDBService" in both code and config file together.
[ServiceContract]
public interface ISyncDBService
{
[OperationContract]
[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetTodoItems")]
TodoItem[] GetTodoItems();
}
[DataContract(Name = "TodoItems")]
public class TodoItem
{
[DataMember(Name = "Id")]
public int Id { get; set;}
[DataMember(Name = "Category")]
public string Category { get; set; }
[DataMember(Name = "Summary")]
public string Summary { get; set; }
[DataMember(Name = "Description")]
public string Description { get; set; }
}
}
2.) The Service:
namespace WcfSyncDBService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "SyncDBService" in code, svc and config file together.
public class SyncDBService : ISyncDBService
{
public TodoItem[] GetTodoItems()
{
var context = new SyncDBEntities();
var query = from i in context.todo select i;
var itemList = query.ToList();
List<TodoItem> todoList = new List<TodoItem>();
foreach (var item in itemList)
{
TodoItem i = new TodoItem
{
Id = item.C_id,
Category = item.category,
Summary = item.summary,
Description = item.description
};
todoList.Add(i);
}
return todoList.ToArray();
}
}
}
3.) Web config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfSyncDBService.SyncDBService">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="webHttpBinding" contract="WcfSyncDBService.ISyncDBService" behaviorConfiguration="web" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<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="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<connectionStrings>
<add name="SyncDBEntities" connectionString="metadata=res://*/SyncDBmodel.csdl|res://*/SyncDBmodel.ssdl|res://*/SyncDBmodel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=SyncDB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
When I run the service I get the definition and the wsdl:
http://localhost:18131/SyncDBService.svc
But when I try to call the function http://localhost:18131/SyncDBService.svc/GetTodoItems/ I get an error "Endpoint not found."
I know the error is probably in the web.config but I simply fail to find it hope someone can help me out.
EDIT1: (web.config after Siva's sugesstion)
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfSyncDBService.SyncDBService">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="webHttpBinding" contract="WcfSyncDBService.ISyncDBService" behaviorConfiguration="web" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<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="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="SyncDBService.svc" service="WcfSyncDBService.SyncDBService" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<connectionStrings>
<add name="SyncDBEntities" connectionString="metadata=res://*/SyncDBmodel.csdl|res://*/SyncDBmodel.ssdl|res://*/SyncDBmodel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=SyncDB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
You need to configure relative address on service host,
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="SyncDBService.svc" service="WcfSyncDBService.SyncDBService" />
</serviceActivations>
</serviceHostingEnvironment>
I have used VS2012 to create a new WCF website (Add->New Web Site->WCF Service).
'Out of the box' this gives me the following web.config file:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<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>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
It also gives me an initial Service class as follows:
public class Service : IService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
I then F5 to start the project and it fires up a browser window listing the dir contents, including Service.svc.
I want to type in a URL to call the GetData method. What do I type into the browser address bar, and how to I configure and/or decorate the service so I can type a URL into the browser and see a JSON format string being returned?
Mark the Operation in your contract (IService interface) with following attribute - [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, UriTemplate="GetData/{id}")]
And then try invoking your service from browser by adding GetData/[any number]
I'm trying to write a backend for my app in asp.net but I can't get my WCF service return a POST response after Ajax request from Ext. Instead I'm getting a 405 'Method not allowed' error.
This is my request :
Ext.Ajax.request({
type: 'POST',
url: 'http://localhost:35798/RestServiceImpl.svc/export',
params: {
html : {'array': document.body.innerHTML}
},
success : function(response){
console.log('RESPONSE !', response);
//me.onSuccess(response, callback, errback);
},
failure : function(response){
console.log('RESPONSE FAIL !', response);
}
});
This is my interface :
namespace RestService
{
public class RestServiceImpl : IRestServiceImpl
{
#region IRestServiceImpl Members
public string JSONData()
{
return "Your POST request";
}
#endregion
}
}
and the service code :
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Web.Script.Services;
namespace RestService
{
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[ScriptMethod]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "export")]
string JSONData();
}
}
And finally the config :
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- 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>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
This may be a cross-domain issue. E.g if your service is at http://localhost:35798 and the web page making the AJAX request is at http://localhost:80 , it's still considered a different domain by the browser (even though only the port number is different). Some browsers in this case issue a CORS request, and if your service doesn't handle it, will return a 405. Your options then are to either (1)avoid cross-domain requests, (2)implement CORS (will not help browsers that don't support it), or (3) use JSONP.
I am writing a WCF service, (json REST) and I have it working fine when using the wcftestclient.exe
When I run that test tool it triggers my break points while debugging and everything works as expected.
but, when using a browser to navigate to the the service and method, no break point is triggered. it seems as though the request isnt even getting to the code.
I receieve no errors on when navigating with web browser to the service, it just doesn't get any data, or trigger the break points.
Apologies if this is a duplicate, I have read and tried many many different configurations found in answers to similar questions, but nothing seems to work.
Many thanks for any help, I've posted my code below.
Martyn
I have setup:
ServiceContract
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
List<Country> GetAllCountries();
The Service CLass:
public List<Country> GetAllCountries()
{
ControlServiceRepository rep = new ControlServiceRepository();
return rep.GetAllCountries().ToList() ;
}
and my web config
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="OmniData" behaviorConfiguration="ServiceConfig">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:55641/"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="ControlService.IOmniData" behaviorConfiguration="rest" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceConfig">
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false" defaultOutgoingResponseFormat="Json"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
I think there are some things missing in your contract
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetAllCountries", RequestFormat = WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Country> GetAllCountries();
Try this.Let me know if it helps.
I got this working in the end by deleting all the end points in the config and using
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(OmniData)));
if anyone else has issues, this is even easier than setting up end points because you can just specify the type of responses and end points within the classes themselves.
so:
Add a global.asax if one does exist and include this:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(OmniData)));
}
decorate your Service class with
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
here is mine:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class OmniData : IOmniData
{
public Country[] GetAllCountries()
{
ControlServiceRepository rep = new ControlServiceRepository();
return rep.GetAllCountries().ToArray() ;
}
}
then the interface you setup your endpoing and types using WebGet or WebInvoke
public interface IOmniData
{
[OperationContract]
[WebGet(UriTemplate = "OmniData/GetAllCountries", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Country[] GetAllCountries();
}
the UriTemplate is the end point, so to access the method you would use: http://MyService.com/OmniData/GetAllCountries
and finally, web config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false"/>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="OmniData">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:55641"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="ControlService.IOmniData" behaviorConfiguration="rest" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Alot of help from here
but, importantly for what I wanted, json results, you need to make sure:
automaticFormatSelectionEnabled="false" is in there so it will use the response format specified in the interface. Otherwise you end up with XML instead.
hopefully this helps someone else
And thanks again for fiddler!
Martyn