I have created the simple web service.
Code:
[ServiceContract]
public interface ITsdxService
{
[OperationContract]
void DoWork();
[OperationContract]
string Test();
}
public class TsdxService : ITsdxService
{
public void DoWork()
{
}
public string Test()
{
return "Hello World!";
}
}
Web.config:
<system.serviceModel>
<services>
<service name="Test.TSDX.UI.TsdxService">
<endpoint
address="Tsdx"
binding="wsHttpBinding"
bindingConfiguration="TestBinding"
contract="Test.TSDX.UI.ITsdxService" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="TestBinding" />
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I run from Visual Studio I put localhost:50517/TsdxService.svc?wsdl all works fine - I can see wsdl, but when I put localhost:50517/TsdxService.svc/Tsdx/Test or localhost:50517/TsdxService.svc/Tsdx/DoWork I don't see anything. The Fiddler tells me that I got 400 error. Breakpoints (on Test and DoWork methods) don't work. Why? What did I do incorrect?
Add the WebGet attribute to your service operations.
[WebGet]
public string Test()
{
...
}
For this to work, you also need to add WebScriptEnablingBehavior to the service configuration. Also, use the webHttpBinding. These things are all required to allow the service to work as an AJAX service.
Definition:
<endpointBehaviors>
<behavior name="EndpointBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
Reference:
<endpoint behaviorConfiguration="EndpointBehavior"
binding="webHttpBinding"
...
/>
Related
My web.config for WCF service looks like below
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="" name="service1Endpoint"
contract="WcfService1.IService1" />
<endpoint address=""
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="" contract="WcfService1.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="service1Endpoint" />
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2393/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="service1Endpoint"
contract="ServiceReference1.IService1"
name="service1Endpoint" />
<endpoint address="http://localhost:2393/Service1.svc"
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="webHttpBinding" contract="ServiceReference1.IService1"
/>
</client>
<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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WcfService1.AjaxAspNetAjaxBehavior">
<enableWebScript />
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I have another simple aspx page created to test whether service is accessible or not. But when I am trying to run this service error displayed is Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata. Can anyone tell me how to resolve this error.
Thanks in advance.
My web service and contract is as below
namespace WcfService1
{
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Contract looks like below
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
string GetData(int value);
}
}
You need a mex service endpoint to allow metadata to be exposed. Add a new endpoint under service node like:
<endpoint address="mex" binding="mexHttpBinding" name="MetadataEndpoint"
contract="IMetadataExchange" />
Read more about Metadata Exchange Endpoint here:
http://www.wcftutorial.net/Metadata-Exchange-Endpoint.aspx
I have a solution with three projects in C#:
CareLife.DataLayer ( Class Library )
CareLife.ServiceLayer ( WCF Service Application)
CareLife.BusinessLayer ( Serive Library )
I added the .dll (located obj folder) of project CareLife.BusinessLayer in the CareLife.ServiceLayer because of need to access methods of BusinessLayer in the project ServiceLayer.
namespace CareLife.BusinessLayer.Operations
{
public class SpecialityServices
{
void GetArea() { }
}
}
and....
namespace CareLife.ServiceLayer
{
[ServiceContract]
public class SpecialityOperations
{
[OperationContract]
[WebInvoke(UriTemplate="Area", Method="GET")]
ICollection<Area> GetArea()
{
try
{
SpecialityServices specialityServices = new SpecialityServices();
}
catch (Exception)
{
throw;
}
return null;
}
}
}
The question is: WHY when I Go to definition in the ServiceLayer of class SpecialityServices, I always am redirect to metadata class?
Have you tried adding it as a project reference instead of a dll from the obj folder ?
The resource I see defined here is Area. Are you doing a GET on http://<serviceRoot>/Area ?
Also, if you're building a rest service, why not use WebAPI?
You should explicitly declare webHttp endpoint. Here is sample system.serviceModel config section:
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="basic" binding="basicHttpBinding" contract="WcfService1.IService1" />
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IService1" behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Just to clarify, i am adding endpointBehaviors section and webHttp endpoint to service section
When this JavaScript code is run, it tells me that "0x800a1391 - JavaScript runtime error: 'InputService' is undefined".
I have tried and tried, and I just can't seem to figure out of what I am missing...
Web.Config file (just the web service part):
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="CommonEndPointBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service name="InputService">
<endpoint name="" address="" behaviorConfiguration="CommonEndPointBehavior" binding="webHttpBinding" contract="InputService" bindingConfiguration="webBinding" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<!--<security mode="Transport">-->
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
The Service:
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class InputService
{
[OperationContract]
public string EditSiteElement(int siteid, string name, string url, string description, int siteorder, bool active)
{
return Input.EditSiteElement(siteid, name, url, description, siteorder, active);
}
}
The references in the web form:
scriptManagerProxy.Services.Add(new ServiceReference("~/User/Input.svc"));
scriptManagerProxy.Scripts.Add(new ScriptReference("~/User/Input.js"));
JavaScript file:
//When edit button is clicked on row.
function EditSiteElement(siteid) {
InputService.GetSiteIdInfo(siteid, function (result) {
var stuff = result.split('ยค');
$('[id$=TextBox_name]').val(stuff[0]);
$('[id$=TextBox_link]').val(stuff[1]);
$('[id$=TextBox_description]').val(stuff[2]);
$('[id$=CheckBox_active]').prop('checked', (stuff[3] == 'True'));
$('[id$=TextBox_order]').val(stuff[4]);
//Open the dialog
$("[id$=panel_Input]").dialog('open');
SiteIdForSave = siteid;
});
}
So, there are a couple of changes you have to do.
First, decorate the service method with the WebInvoke attribute which resides in the System.ServiceModel.Web namespace (you may have to add the reference to your project).
[OperationContract]
[System.ServiceModel.Web.WebInvoke] //add this attribute
public string EditSiteElement(int siteid, string name, string url, string description, int siteorder, bool active)
{
return Input.EditSiteElement(siteid, name, url, description, siteorder, active);
}
Second, in the InputService.svc file (in Visual Studio, right click on the InputService.svc file and select View Markup), add the Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" attribute:
<%# ServiceHost Language="C#" Debug="true" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" Service="WebApplication6.InputService" CodeBehind="InputService.svc.cs" %>
Make sure that the target framework version for your application is 4.5.
[EDIT]
I suggest you modify the web.config's <system.serviceModel> section as follows. Please pay attention to the use of your namespaces (MyNamespace) and to the fact that I moved the behavior definition from the end point to the service level.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="InputServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service behaviorConfiguration="InputServiceBehavior" name="MyNamespace.InputService">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.InputService" bindingConfiguration="webBinding"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<!--<security mode="Transport">-->
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
I am trying to make a simple WCF RESTful for the first time to be consumed via JSON. I have my interface below, but what would be the URL I would call to invoke my MemberLogon() method?
I thought it would be this:
http://localhost:49701/Exchange.svc/?membershipNumber=6519548&blah=abc
but I get a 404. I have a feeling it is to do with my service configuraiton in my Web.Config. Help!
My interface and class is:
[ServiceContract]
public interface IExchange
{
[System.ServiceModel.OperationContract(Name = "MemberLogon")]
[WebInvoke(UriTemplate = "/?membershipNumber={membershipNumber}&blah={blah}", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
Member MemberLogon(string membershipNumber, string blah);
}
[System.Runtime.Serialization.DataContract]
public class Member
{
[System.Runtime.Serialization.DataMember]
public string Username { get; set; }
}
Configuration is:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyNamespace.MyClass.ExchangeBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyNamespace.MyClass.ExchangeBehavior" name="MyNamespace.MyClass.Exchange">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.MyClass.IExchange" />
</service>
</services>
The code and interface look good. Can you try this configuration?
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyNamespace.MyClass.ExchangeBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.MyClass.Exchange">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyNamespace.MyClass.ExchangeBehavior" contract="MyNamespace.MyClass.IExchange" />
</service>
</services>
</system.serviceModel>
Hello and thank you for reading.
I'm trying to get a service hosted in IIS 7.5, that has multiple endpoints exposed.
I have a feeling the problem lies within my web.config, but I'll post my service code in here. There's no interface file, as I'm using the newer features of WCF 4, there's also no .svc file.
All the routing, from my understanding is handled in Global.asax.cs using the RouteTable feature.
Regardless, onto the code / config -
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
// NOTE: If the service is renamed, remember to update the global.asax.cs file
public class Service1
{
// TODO: Implement the collection resource that will contain the SampleItem instances
[WebGet(UriTemplate = "HelloWorld")]
public string HelloWorld()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
return "Hello World!";
}
}
And now, the config with the changes I thought would need to be made (I'm not sure if I needed to keep the standardEndpoints block, but with or without it I'm still getting error messages. -
<services>
<service name="AiSynthDocSvc.Service1" behaviorConfiguration="HttpGetMetadata">
<endpoint name="rest"
address=""
binding="webHttpBinding"
contract="AiSynthDocSvc.Service1"
behaviorConfiguration="REST" />
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
contract="AiSynthDocSvc.Service1" />
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="HttpGetMetadata">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
The Global.asax.cs file was left alone.
Again I'm pretty sure it has something to do with my config. The error I'm getting when I try to access any of the endpoints defined is -
The endpoint at '' does not have a Binding with the None MessageVersion. 'System.ServiceModel.Description.WebHttpBehavior' is only intended for use with WebHttpBinding or similar bindings.
Anyone have any ideas on this one?
Thanks,
Zachary Carter
OK, I tried to replicate your stuff - works like a charm for me :-)
I used your service class - no changes
I used your RegisterRoutes call in global.asax.cs
When I launch the web app from within Visual Studio, I get Cassini (the built-in web server) come up on http://localhost:3131/ - this might wary in your case.
Now, I can easily navigate there with a second browser window, and I do get a simple response on this URL:
http://localhost:3131/Service1/HelloWorld
+--------------------+
from Cassini
+--------+
name (first param) in ServiceRoute registration
+-----------+
from your URI template on the WebGet attribute
Does the same URL work for you??
Update: here's my config - I can connect to http://localhost:3131/Service1/HelloWorld in the browser using REST, and I can connect to http://localhost:3131/Service1/soap with the WCF Test Client to make a SOAP call (my Service1 lives in the RestWebApp namespace - thus my service and contract names are a tad different than yours - but other than that, I believe it's identical to your own config):
<system.serviceModel>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true" />
<services>
<service name="RestWebApp.Service1" behaviorConfiguration="Meta">
<endpoint name="rest"
address=""
binding="webHttpBinding"
contract="RestWebApp.Service1"
behaviorConfiguration="REST" />
<endpoint name="SOAP"
address="soap"
binding="basicHttpBinding"
contract="RestWebApp.Service1" />
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Meta">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
Thanks for this it helped me a lot.
The issue in my case was that I had a default behaviour configured that contains webHttp. After giving it the name="REST" and setting my webHttpBinding endpoint behaviourConfiguration ="REST" I had no further errors.
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_IMobileService">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost:6862/silverlight/services/MobileService.svc"
binding="customBinding" bindingConfiguration="CustomBinding_IMobileService"
contract="AlchemyMobileService.IMobileService" name="CustomBinding_IMobileService" />
</client>
<services>
<service name="MobileService.Alchemy">
<endpoint address="http://localhost:8732/mobileservice" binding="webHttpBinding" contract="MobileService.IAlchemy" behaviorConfiguration="REST">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>