cant get fiddler to record requests from wcftestclient.exe? - wcf

I build a very basic wcf service using visual studio development server just to see fiddler working:
c#
public class Service1 : IService1
{
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;
}
}
web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
when I run the wcftestclient it shows up the getdata() works but does not show up in fiddler? how can i amend this?
thanks
P

What is address of your service? If you use localhost or 127.0.0.1 these messages won't be captured. Use your machine name or network IP address. You can set it in Project properties or directly on the endpoint.

Related

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.?

trying to build a RestFull service with wcf running in the WcfTestClient.exe. The problem is that I get an error:
Failed to add a service. Service metadata may not be accessible.
I added a mex endpoint in the config file but does not solve it:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="MyRest.Service" behaviorConfiguration="ServBehave">
<!--Endpoint for REST-->
<endpoint
address="XMLService"
binding="webHttpBinding"
behaviorConfiguration="restPoxBehavior"
contract="MyRest.IService"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave" >
<!-- 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 for the REST endpoint for Help enability-->
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "/Employees", ResponseFormat = WebMessageFormat.Xml)]
Employee[] GetEmployees();
}
[DataContract]
public class Employee
{
[DataMember]
public int EmpNo { get; set; }
[DataMember]
public string EmpName { get; set; }
[DataMember]
public string DeptName { get; set; }
}
Service1.cs
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class Service1 : IService1
{
public Employee[] GetEmployees()
{
return new Employee[]
{
new Employee() {EmpNo=101,EmpName="Mahesh",DeptName="CTD"},
new Employee() {EmpNo=102,EmpName="Akash",DeptName="HRD"}
};
}
}
With WCF Restful service, do you actually need meta-data to expose service or to work on it? The answer is "NO". It's against the principles of Rest. Meta-data represents the interface(the operations), and for REST interface is fixed(http methods). WcfTestClient is for testing SOAP based Service(as they have to expose their interface through mex bindings).
Testing a RESTFUL service for http get could be vary easy. you just have to invoke it from your browser, using the URL. To test other http methods, you have to build your custom client.
If this seems a big task, then you could also use tools like Fiddler to build request data. An example could be seen here

WCF HTTP 504 Error

I have the following problem. I am using Entity Framework to connect to a SQL Azure and that works(I tested it in a Test Project).
But when i try to get it through WCF RESTful service it throws Error 504.
My Operation Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "/Artikli", ResponseFormat = WebMessageFormat.Json)]
IEnumerable<Artikal> GetArtikli();
}
Implementation of [ServiceContract] :
public class Service : IService
{
public IEnumerable<Artikal> GetArtikli()
{
using (var context = new CijenolomciEntities())
{
var result = context.Artikals.ToList();
result.ForEach(a => context.Detach(a));
return result;
}
}
}
The whole thing is hosted on local IIS. I use Fiddler, an what it says when i try to reach
http://localhost:17916/Service.svc/Artikli
is
[Fiddler] ReadResponse() failed: The server did not return a response for this request.
The WCF App.Config looks like:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="CijenolomciEntities" connectionString="My_Connection_String" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding" />
</protocolMapping>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
EDIT:
When i try to access URL through browser i get the following:
Request Error
The server encountered an error processing the request. See server logs for more details.
Try to enable Tracing and see if your request is exceeding the default values due to which you are getting a timeout error.
Inspect the trace log for detailed error on why it is failing and then appropriately perform the needed steps to increase either the timeout values or the default size limits
If your network environment is set to make all HTTP traffic go through a proxy server then it's likely the account the IIS app pool is running under isn't allow to send HTTP traffic. As a test, change the app pool account to your login account and see if the WCF service connects successfully. The 504 message is usually a proxy or network issue.
I don't think it is the network error. The issue is in the service. Might be you receive 504 not from IIS, but from Fiddler. Read this. Might be you have to increase maxItemsInObjectGraph

simultaneous calls handling in WCF

I'm new to .net and knows very little about WCF, so bear with me if any silly questions asked. I'm wondering how WCF handles simultaneous calls in SELF-HOST scenario if my code doesn't explicitly spawn any thread. So after read a lot on the stackoverflow, I created a test app but it seems not working. Please advise. Thanks a lot.
Please note ...
My question is only about WCF SELF HOSTING, so please don't refer to any IIS related.
I'm using webHttpBinding.
I understand there are maxConnection and service throttling settings, but I'm only interested in 2 simultaneous calls in my research setup. So there should be no max conn or thread pool concern.
My test service is NOT using session.
Code as below ...
namespace myApp
{
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate="test?id={id}")]
string Test(int id);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class TestService : ITestService
{
private static ManualResetEvent done = new ManualResetEvent(false);
public string Test(int id)
{
if (id == 1)
{
done.Reset();
done.WaitOne();
}
else
{
done.Set();
}
}
}
}
app.config ...
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name = "TestEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name = "myApp.TestService">
<endpoint address = "" behaviorConfiguration="TestEndpointBehavior"
binding = "webHttpBinding"
contract = "myApp.ITestService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/test/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<system.web>
<sessionState mode = "Off" />
</system.web>
How I tested ...
Once had the application running, I opened my browser, FF in case, made one call to http://localhost:8080/test/test?id=1 . This request put the app to suspend waiting for signal, i.e. WaitOne. Then made another call in another browser tab to http://localhost:8080/test/test?id=2. What's expected is that this request will set the signal and thus the server will return for both requests.
But I saw the app hang and the Test function never got entered for the 2nd request. So apparently my code doesn't support simultaneous/concurrent calls. Anything wrong?
You can use single class to setup your wcf service and discard interface. You need to add global.asax file also. After you make the second call, all of them will return "finished".
This configuration does what you want.
Create TestService.cs with :
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public class TestService
{
private static ManualResetEvent done = new ManualResetEvent(false);
[OperationContract]
[WebGet(UriTemplate = "test?id={id}")]
public string Test(int id)
{
if (id == 1)
{
done.Reset();
done.WaitOne();
}
else
{
done.Set();
}
return "finished";
}
}
web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.serviceModel>
<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="false" > </standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<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>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Global.asax file:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("testservice", new WebServiceHostFactory(), typeof(TestService)));
}
}

C# 4.0 WCF REST JSON - HTTP GET CODE 400 Bad Request

When trying to create a simple service to return a simple JSON string by following several tutorials. I get stuck on two different machines with a HTTP Statuscode 400 bad request.
Example tutorials
RESTful WCF Service with JSON pt.1 & pt.2 - http://www.youtube.com/watch?v=5BbDxB_5CZ8
I have also Google and searched here (StackOverflow) for similar problem without success.
The problem is I get the 400 bad request when trying to do a sanity check to browse to the WCF service and execute the method. By compiling the service and browse this address: http://localhost:49510/Service1.svc/GetPerson
Just like the tutorial. I have tried finding a solution for like 3 days. Any help is appreciated.
This is what I do.
First i create a new project a simple WCF Service application. I delete the default Service1.svc and add a new WCF Service, that generate a new Service1.svc and a IService1.cs
Here is the code for the interface (IService1.cs)
namespace WcfService1
{
// 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", BodyStyle=WebMessageBodyStyle.Bare, ResponseFormat=WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json, UriTemplate="GetPerson")]
Person GetPerson();
}
[DataContract(Name="Person")]
public class Person
{
[DataMember(Name="name")]
public string Name { get; set; }
}
}
Here is the code for the Service1.svc
namespace WcfService1
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class Service1 : IService1
{
public Person GetPerson()
{
return new Person() { Name = "Tobbe" };
}
}
}
And the Web.config is untouched and look likes this web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
For REST WCF You have to do binding and endpoint setting in web.config
Replace your whole web.config by following and it will work
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<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>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
You were remaining with following 2 things
Use webHttpBinding (change default http port mapping to webHttpBinding)
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<system.serviceModel>
Specify webHttp End Point Behaviors
<system.serviceModel>
-----
</protocolMapping>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior >
</endpointBehaviors>
<behaviors>
------
<system.serviceModel>
You didn't specify any endpoint... By default on WCF 4, an endpoint using basicHttpBinding will be used. It'll not work here because it is a SOAP-based binding. What you want to use is webHttpBinding which is REST-based...
Here is how to override default binding with WCF 4 :
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
</system.serviceModel>
You also have to enable webHttp by adding this endpoint behavior in your config :
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior >
</endpointBehaviors>
<behaviors>
http://msdn.microsoft.com/en-us/library/bb924425.aspx
I'm not entirely sure why, but when I added the 'Factory' attribute to my .SVC file (you need to explicitly drag it to Visual Studio), everything just works - without any changes to default settings in Web.config!
I added Factory="System.ServiceModel.Activation.WebServiceHostFactory" so my .SVC file went from this:
<%# ServiceHost Language="C#" Debug="true" Service="ServiceNameSpace.ServiceName" CodeBehind="ServiceName.svc.cs" %>
to this:
<%# ServiceHost Language="C#" Debug="true" Service="ServiceNameSpace.ServiceName" CodeBehind="ServiceName.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
The only side effect seems to be that when you click on the .SVC file in the browser, you get an 'Endpoint not found' error, but the service works fine when you invoke it correctly anyway. As mentioned previously, I'm using a default Web.config with .NET 4.6 (Simplified WCF configuration), so I may yet need to add endpoint details for that to work again.
Note to moderator: my apologies for posting this answer on a couple of questions. Won't do it again. However, I don't think that deleting it from BOTH questions was very balanced. This is why I have re-posted this answer here only.

WCF callback not being executed

I've been Googling this for a day now and can't seem to find the answer. Hoping someone can shed some light on this. I'm trying to implement a simple WCF client-server callback, with console apps at both the client and server sides. The operation executes on the server and everything seems to work fine except that the callback doesn't execute on the client. I.e. it never writes "Callback called!!!", and a breakpoint placed in the callback never trips. The client simply writes "Done." and waits for user input.
I'm sure it's something simple. Any help would be greatly appreciated. Thanks!
//SERVER CODE:
namespace NodeServiceLib
{
public interface ISomeCallbackContract
{
[OperationContract]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
public interface IMyContract
{
[OperationContract]
void DoSomething();
}
public class NodeService : IMyContract
{
public void DoSomething()
{
Console.WriteLine("I'm doing something!!!");
}
}
}
<configuration>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings/>
<services>
<service name="NodeServiceLib.NodeService" behaviorConfiguration="MEX">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Node" />
<add baseAddress="net.tcp://localhost:8001/Node" />
</baseAddresses>
</host>
<endpoint
address="MyContract"
binding="netTcpBinding"
contract="NodeServiceLib.IMyContract"
/>
<endpoint
address="MEX"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEXGET">
<!-- 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>
<behavior name="MEX">
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup</configuration>
//CLIENT CODE:
namespace TestConsole
{
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class Callback : NodeServices.IMyContractCallback
{
public void OnCallback()
{
Console.WriteLine("Callback called!!!");
}
}
class Program
{
static void Main(string[] args)
{
System.Threading.Thread.Sleep(5000); // Give server time to spin up
Console.WriteLine("=== CLIENT ===");
InstanceContext context = new InstanceContext(new Callback());
NodeServices.MyContractClient proxy = new NodeServices.MyContractClient(context);
proxy.DoSomething();
Console.WriteLine("Done.");
Console.ReadLine();
}
}
}
Shouldn't you be calling the callback method in the server's DoSomething method?