1

Since i am new to WCF and Having configured a WCF service endpoint in IIS at Virtual Directory Api ( url goes like http://localhost/api/taskapi.svc) i was looking for ways to make request through web browser something like http://localhost/api/taskapi.svc/GetCompleted would respond with JSON that lists all completed tasks hence these two posts here gave me some answers

ok hmm so i changed my OperationContract to like below

    [OperationContract]
    [WebGet(UriTemplate = "/GetCompleted", ResponseFormat = WebMessageFormat.Json)]
    IList<Task> GetCompleted();

but still the url http://localhost/api/tasksapi.svc/GetCompleted in browser responds with 400 Bad Request.

Service Contract

[ServiceContract]
public interface ITaskContract
{

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/task", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    TaskLibrary.Task CreateTask(TaskLibrary.Task myTask);

    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "/task", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    IList<TaskLibrary.Task> GetTasks();

    [OperationContract]
    [WebInvoke(Method = "DELETE", UriTemplate = "/task", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    bool DeleteTask(string taskId);

    [OperationContract]
    [WebInvoke(Method = "PUT", UriTemplate = "/task", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    bool UpdateTask(TaskLibrary.Task myTask);

    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "/task/{taskId}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    IList<TaskLibrary.Task> GetById(string taskId);

    [OperationContract]
    [WebInvoke(UriTemplate = "/task/completed", ResponseFormat = WebMessageFormat.Json, Method = "GET", RequestFormat = WebMessageFormat.Json)]
    IList<TaskLibrary.Task> GetCompleted();

}

Service Config

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="TaskApi.ServiceBehavior" name="TaskService.TaskService">
        <endpoint address="" binding="wsHttpBinding" contract="TaskService.ITaskContract">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="TaskApi.ServiceBehavior">
          <!-- 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>
  </system.serviceModel>

Reference Directive

<%@ ServiceHost Language="C#" Debug="true" Service="TaskService.TaskService" %>

the service is picked from assembly which is output of WCF Service library

Url rewrite to hide svc extension

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <rewrite>
      <rules>
        <rule name="Svc Extension remove pattern">
          <match url="^([0-9a-zA-Z\-]+)/([0-9a-zA-Z\-\.\/\(\)]+)" />
          <action type="Rewrite" url="{R:1}.svc/{R:2}" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
  • What should i do to make this work?
Community
  • 1
  • 1
Deeptechtons
  • 10,945
  • 27
  • 96
  • 178

1 Answers1

2

OK your binding is wsHttpBinding. You need to change it to webHttpBinding (or add another endpoint). Then you need to add an endpointBehavior in the behaviors section as follows

   <endpointBehavior>
       <behavior name="rest">
           <webHttp/>
       </behavior>
   </endpointBehavior>

This behavior wires in the functionality to map Uris to methods. Then you need to reference this behavior from the webHttpBinding endpoint using the behaviorConfiguration XML attribute

Richard Blewett
  • 6,089
  • 1
  • 18
  • 23
  • Seems there is another configuration mistake The message with To `URL/api/taskapi.svc/tasks` cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree. – Deeptechtons May 18 '12 at 10:54
  • two things: I thought you had a URL rewriter in to remove the .svc; you are using tasks as your uri but your contract states GetCompleted - can you give us the new config just in case there is now a typo in it or something – Richard Blewett May 18 '12 at 11:32
  • Updated the source . all i though is from the service contract that when i call `/Tasks` with `GET` request then `GetTasks` method is invoked. Am i right? – Deeptechtons May 18 '12 at 11:37
  • GetTask would be called with /task (no s) according to your contract but I think the error is coming from the fact that something is assuming SOAP - can we see your service config – Richard Blewett May 18 '12 at 11:47
  • I am totally new to wcf by service config do you mean web.config or app.config file? i got app.config in wcf service library project and web.config in wcf service application – Deeptechtons May 18 '12 at 11:49
  • The service library config is ignored - the only config that matters is the web one - in .NET dlls dont have config only apps do - which does beg the point of why a config is created for a lib project but maybe someone form the WCF team should answer that ;-) – Richard Blewett May 18 '12 at 13:02
  • You havent got the endpointBehavior that I showed in my answer in the config file - without this the mapping of Uris to contract operations won't work – Richard Blewett May 19 '12 at 09:42