How to configure WCF services - wcf

I'm new to using WCF services and i hope you can help me out on some problems invoking an external REST webservice. I have create two applications to try and test my service.
Console application to test my class lib
An umbraco application which hosts my services
Both localhost.
Here is the code of my service:
namespace HorecaWebservices.Webservices
{
[ServiceContract]
public interface IWS_Test
{
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Agenda GetAgenda(String mobileAppKey);
}
}
namespace HorecaWebservices.Webservices
{
public class WS_Test : IWS_Test
{
public Agenda GetAgenda(String mobileAppKey)
{
return BL_Agenda.GetAgenda(mobileAppKey);
}
}
}
Web config of my service:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true"
automaticFormatSelectionEnabled="true"
defaultOutgoingResponseFormat="Json">
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="HorecaWebservices.Webservices.WS_Test"
behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="" binding="wsHttpBinding"
contract="HorecaWebservices.Webservices.IWS_Test"/>
<endpoint contract="IMetadataExchange"
binding="mexHttpBinding" address="mex"/>
</service>
</services>
</system.serviceModel>
Here is the code from my console application which invokes the service method:
public static class BL_Agenda
{
public static Agenda GetAgenda()
{
Agenda agenda = new Agenda();
WebRequest request = WebRequest.Create("http://localhost:63462/Webservices/WS_Test.svc/GetAgenda");
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
string postData = "{\"mobileAppKey\":\"HEMDZ\"}"; //encode your data
using (Stream s = request.GetRequestStream())
{
using (StreamWriter sw = new StreamWriter(s))
sw.Write(postData);
s.Close();
}
try
{
using (Stream s = request.GetResponse().GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
var jsonData = sr.ReadToEnd();
agenda = JsonConvert.DeserializeObject<Agenda>(jsonData);
}
s.Close();
}
}
catch (WebException e)
{
agenda = null;
WebExceptionStatus status = e.Status;
Console.WriteLine(status.ToString());
}
return agenda;
}
Now whenever i run this code the request.GetResponse() throws a System.Net.WebException "(415) Cannot process the message because the content type 'application/json; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'"
After a couple of hours trying to find out what the problem is i still cant figure it out.. Can someone help me out on this?

At a first glance your endpoint uses the wrong binding (wsHttpBinding):
<endpoint address="" binding="wsHttpBinding" contract="HorecaWebservices.Webservices.IWS_Test"/>
Whereas it should be webHttpBinding:
<endpoint address="" binding="webHttpBinding" contract="HorecaWebservices.Webservices.IWS_Test"/>
For a complete webHttp-sample binding take a look at this article: http://weblogs.asp.net/kiyoshi/archive/2008/10/08/wcf-using-webhttpbinding-for-rest-services.aspx
When changing the binding other issues are likely to occur. One thing is, that you'll probably don't need the <standardEndpoints>-node any more. So I'd suggest staying close to the linked sample.
Additionally it's always a good idea to activate tracing. Having tracing activated you'll get more detailed information about your 500 error (and probably others too).

This example is not exactly the same, but maybe the Factory attribute suggested will give you some clues.
HTTP/1.1 415 Cannot process the message because the content type 'application/json; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'

I've got it! I finally sorted out the bad request error. I had to replace the BodyStyle = WebMessageBodyStyle.Bare setting to BodyStyle = WebMessageBodyStyle.WrappedRequest.
Thnx for all the help guys!

Related

AJAX POST to WCF web config need another set of eyes/mind

For some reason I'm not able to get a very simple AJAX post to my web service (svc) to work.
I'm sure it's a problem with my web.config, but I tried everything I can find online.
In "MyService.svc" if is use
[OperationContract]
[WebInvoke(Method ="POST", RequestFormat = WebMessageFormat.Json, ResponseFormat =WebMessageFormat.Json, BodyStyle =WebMessageBodyStyle.Wrapped)]
public string DoWork()
{
string result = "did it";
//result = test;
return (new JavaScriptSerializer().Serialize(result)); ;
}
where DoWork only returns a value, Ajax succeeds. However, if I pass a parameter to DoWork(string test)
Ajax returns an error. Bad Request.
My ajax is:
function DoTest() {
testData = { "test": "Hello" };
var jsonData = JSON.stringify(testData);
var POSTURL = "MyService.svc/DoWork";
//alert(jsonData);
//alert(POSTURL);
$.ajax({
type: "POST",
url: POSTURL,
datatype: "json",
data: jsonData,
ContentType: "application/json; charset=utf-8",
success: function (result) {
alert("success: " + result.d);
},
error: function (xhr, status, error) {
alert("Opps: " + xhr + " " + status + " " + error);
}
})
}
});
This is in my web.config:
<behaviors>
<endpointBehaviors>
<behavior name="MyServiceAspNetAjaxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" behaviorConfiguration="MyServiceAspNetAjaxBehavior"
binding="webHttpBinding" contract="MyService" />
</service>
</services>
</system.serviceModel>
I need another set of eyes on this otherwise simple program. Thanks
"Bad Request" is usually an error in the request format. You can use the help document in WCF to view the request format. If you want to enable the help document, you need to change the WebMessageBodyStyle to bare:
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle =WebMessageBodyStyle.Bare)]
Then enable the help document in the configuration file:
<endpointBehaviors>
<behavior name="ESEndPointBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
View the requested format in the browser, you need to send the data in its format.
I removed an extra <endpoint address="" I had in my revision. The service call is being made from AJAX now. Phew. This WCF works great when it's working, and very difficult to diagnose when it does not work. Thanks for listening and good luck to everyone.

Inserting Data in WCF REST Service showing Error : The remote server returned an error: (404) Not Found

I have created the Two Methods one is to Get and another one is to Create,
For Getting the Data is working fine, but when i trying to post the Data is showing the Error like Method not Found(404)
The Code is as following.
Contract Methods :
public interface IContactPositionService {
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "GET",RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetContactPositionList")]
List<ContactPosition> GetContactPositionList();
[OperationContract]
[WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.WrappedRequest,RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "AddContactPosition")]
int AddContactPosition(ContactPosition position);}
And Corresponding Serivice class is like :
public class ContactPositionService : IContactPositionService
{
public List<ContactPosition> GetContactPositionList()
{
DataSet ds = clsObj.GetContactPositionsList();
return ConverterHelper.Convert<ContactPosition>(ds.Tables[0]);
}
public int AddContactPosition(ContactPosition position)
{
// throw new System.NotImplementedException();
}
And in Web.config file i have configured the End Points As :
<services>
<service name="VirtusMobileService.ContactPositionService" behaviorConfiguration="VMS.Position.ServiceBehaviour">
<endpoint address="" behaviorConfiguration="VMS.Position.EndPointBehaviour"
binding="webHttpBinding" bindingConfiguration="" name="VMS.Position.EndPoint"
contract="VirtusMobileService.IContactPositionService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="VMS.Position.EndPointBehaviour">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="VMS.ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="VMS.Position.ServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
From the Client Asp.net page we call the Services for adding the Contact person object as like below :
private void AddData()
{
string sURL = "http://localhost:51293/ContactPositionService.svc/AddContactPosition";
ContactPosition order = new ContactPosition
{
PositionCode="10550",
PositionFinbaseId=11,
PositionTitle="Manager"
};
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ContactPosition));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, order);
string data = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadData(sURL, "PUT", mem.ToArray()); // Here it is showing Error
Console.WriteLine("Order placed successfully...");
}
While it comes to , " uploadData " it is showing error like "
remote server returned an error: (404) Not Found."
If i am trying to Get the Data using the "GetContactPositionList"
it showing the data Correctly , but when i am trying to work with
"PUT" method it is showing that error.
I tested the url in Fiddler , it is showing the same error in Response
Header "HTTP/1.1 405 Method Not Allowed"
<div id="content">
<p class="heading1">Service</p>
<p xmlns="">Method not allowed. Please see the <a rel="help-page" href="http://localhost:51293/ContactPositionService.svc/help">service help page</a> for constructing valid requests to the service.</p>
</div>
Please Suggest the answer.
Thanks.
In fiddler you have to specify application/json as Content Type and it will hit the service Try this link
Instead of "webClient.UploadData", try this..
webClient.UploadString(sURL, "PUT", data);
I think you could probably make this much easier on yourself by using System.ServiceModel.ChannelFactory. It will simplify greatly your interaction with the service, as you will have strongly-typed variables, the method names themselves, and not have to mess with the serialization yourself.
You can replace your AddData method as:
private void AddData()
{
// Create the service channel; 'factory' and/or 'svc' can be class members so we can re-use them.
var factory = new ChannelFactory<IContactPositionService>(new WebHttpBinding(), new EndpointAddress("http://localhost:51293/ContactPositionService.svc"));
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
var svc = factory.CreateChannel();
ContactPosition order = new ContactPosition
{
PositionCode = "10550",
PositionFinbaseId = 11,
PositionTitle = "Manager"
};
try
{
var result = svc.AddContactPosition(order);
Console.WriteLine("Order# " + result.ToString() + " placed successfully...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Note: This will require your calling project to have a reference to System.ServiceModel.dll and System.ServiceModel.Web.dll. Additionally, the calling project will need to know about IContactPositionService and ContactPosition. I your calling project is not the same as your WCF project, and does not already reference your WCF project, then you can move your service interfaces and objects into a third class library, which you could then share between the WCF host and any consumers.

WCF Rest service not working

ILeaveManagement class
[ServiceContract]
public interface ILeaveManagement
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "get")]
List<ServiceReference1.LeaveRequest> GetLeaveDetails();
}
LeaveManagement class
public class LeaveManagement : ILeaveManagement
{
public List<ServiceReference1.LeaveRequest> GetLeaveDetails()
{
try
{
var entities = new ServiceReference1.leaverequest_Entities(new Uri(serviceUrl));
var result = entities.LeaveRequestCollection;
return result.ToList();
}
catch
{
return new List<ServiceReference1.LeaveRequest>();
}
}
}
configuration
<service behaviorConfiguration="DRLExternalList.LeaveManagementBehavior" name="DRLExternalList.LeaveManagement">
<endpoint address="" binding="wsHttpBinding" contract="DRLExternalList.ILeaveManagement"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<behavior name="DRLExternalList.LeaveManagementBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
I have deployed the project in IIS 7.5. When i run the application , it is saying BadRequest.
I have verrified in fiddler. i saw 400 error.
Please help me on this.
Try using webHttpBinding in your endpoint instead of the wsHttpBinding, or add it as an additional one and change the address. I use a bindingNamespace in my project, but I don't think you need it.
<endpoint address="XMLService"
binding="webHttpBinding"
behaviorConfiguration="restXMLBehavior"
contract="DRLExternalList.ILeaveManagement">
</endpoint>
Add an Endpoint Behavior
<endpointBehaviors>
<!-- Behavior for the REST endpoint -->
<behavior name="restXMLBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
I also annotate the OperationContract slightly differently, but it shouldn't make all that much of a difference. I'll give it to you just in case...
[WebGet(UriTemplate = "/GetLeaveDetails", ResponseFormat = WebMessageFormat.Xml)]
To call the service, it would look like this using the XMLService endpoint name:
http://myWebHost.com/WebService/MyService.svc/XMLService/GetLeaveDetails
Hosting an wcf service into a website issue : System.ArgumentException: ServiceHost only supports class service types
the above link helped me to solve my issue.
<%# ServiceHost Language="C#" Debug="true" Service="restleave.ProductRESTService" %>

What is the correct url for service reference?

I have two projects, one is WCF Service, which is to speak a text/sentence in a text box.
public class Service1 : IService1
{
public string RunTts(string text)
{
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
// Configure the audio output.
synth.SetOutputToDefaultAudioDevice();
synth.Speak(text);
return "";
}
}
}
Then I call it with ajax in the _Layout.cshtml page in the second project, which is asp.net mvc.
<script type="text/javascript">
function ttsFunction() {
serviceUrl = "Service1.svc/RunTts";
$.ajax({
type: "POST",
url: serviceUrl,
data: '{"text": "' + $('#speak').val() + '"}',
contentType: "text/xml; charset=utf-8",
dataType: "text/xml",
error: function (xhr,status,error) {
console.log("Status: " + status); // got "error"
console.log("Error: " + error); // got "Not Found"
console.log("xhr: " + xhr.readyState); // got "4"
},
statusCode: {
404: function() {
console.log("page not found"); // got
}
}
});
}
</script>
Because I got 404 error, so I think the url is wrong. Please see the structure of files, the web reference is called 'ServiceReference1' I guess.
As shown in your screenshot, the service is not hosted in your web application. You cannot access such a service (hosted outside of your web application) directly from the client side, because you're violating the same origin policy restriction. It's one of the underlying concepts of trust, on which web security is based on (e.g. protection aganist XSS) - you cannot send cross domain AJAX requests. This essentially states that if content from one site (e.g. https://bank.ny.com) is granted permission to access resources on the system, then any content from that site will share these permissions, while content from another site (https://nsa.ny.com) will have to be granted permissions separately (in general, the term origin is defined using the domain name, application layer protocol, and port number).
Nevertheless, you have at least 4 solutions to solve your problem:
First - talk to your service through the middle-controller layer. Going this way implies to have proxy class generated (by svcutil.exe, what you have done by adding service reference using Visual Studio). Communication with this client looks like below:
public class TtsController
{
public JsonResult RunTts(string text)
{
using(var client = new ServiceReference1.Service1Client())
{
var response = client.RunTts(text);
return Json(response);
...
The JavaScript side should then use such an URL: var serviceUrl = "/Tts/RunTts" (along with proper JSON data passing to the AJAX request, which I'll go through a bit further).
Second - talk directly to the service. If you want to communicate directly with the service, you have to host this service in your web application. The correct WCF configuration should be followed to support RESTful services:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Namespace.Service1">
<endpoint address=""
behaviorConfiguration="webby"
binding="webHttpBinding"
contract="Namespace.IService1" />
</service>
</services>
</system.serviceModel>
For a RESTful endpoint, the binding you should use is WebHttpBinding along with appropriate behavior. Alternatively there is configuration-free experience for many RESTful services - WebServiceHostFactory. Your .svc file should look like below (MSDN):
<%# ServiceHost Language="C#" Debug="true" Service="Namespace.Service1"
CodeBehind="Service1.svc.cs"
Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
WebServiceHostFactory creates an instance of the WebServiceHost, and since the WebServiceHost will auto-configure the endpoint using WebHttpBinding and related behavior, there doesn't need to be any configuration for this endpoint in the web.config at all (of course, if you need to customize the binding, you have to use the configuration) (MSDN).
Then to access the service use appropriate full URL: http://localhost:[port]/Service1.svc/RunTts or relative one: /Service1.svc/RunTts.
Since you're using ASP.NET MVC, based on your routes definitions, the request will dispatched to some controller, where such an action doesn't exist. You have to tell MVC to ignore route to your service:
routes.IgnoreRoute("{resource}.svc/{*pathInfo}");
(BTW: If you put your .svc file under different directory within your application, modify respectively URL and route to ignore.)
Your code needs some additional fixes:
If you want to send message in JSON format, specify dataType and contentType parameters correctly:
$.ajax({
url: serviceUrl,
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
...
Do not construct your JSON strings manually, as it can lead to further parsing errors - use converters e.g.:
var data = new Object();
data.text = $('#speak').val();
var jsonString = JSON.stringify(data);
$.ajax({
...
data: jsonString,
...
Provide additional declarative information to your service:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
string RunTts(string text);
...
Remove service reference from the project. You don't need it as there is no usage of middle-controller here.
Third - JSONP (look here and here) can be used to overcome origin policy restriction. But you can't POST using JSONP because it just doesn't work that way - it creates a <script> element to fetch data, which has to be done via GET request. JSONP solution doesn't use XmlHttpRequest object, so it is not an AJAX request in the standard way of understanding, but the content is still accessed dynamically - no difference for the end user.
$.ajax({
url: serviceUrl,
dataType: "jsonp",
contentType: "application/json; charset=utf-8",
data: data,
...
[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate="RunTts?text={text}")]
public string RunTts(string text);
RESTful WCF configuration with cross domain requests allowed:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="jsonp" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Namespace.Service1">
<endpoint address=""
behaviorConfiguration="webby"
binding="webHttpBinding"
bindingConfiguration="jsonp"
contract="Namespace.IService1" />
</service>
</services>
</system.serviceModel>
Fourth - CORS. Implemented in modern browsers alternative to JSON with Padding.

how to log JSON response in WCF at service level

I have a WCF service that returns JSON to the clients.
This is the app.config
<system.serviceModel>
<services>
<service name="MyServices.MyService">
<endpoint address="" behaviorConfiguration="JsonBehavior" binding="webHttpBinding"
contract="Myervices.IMyervice">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MyEmulator/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="JsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
This is a sample opertaion exposed by the service
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "me/{id}")]
JsonObject GetObject(string id, string connection_type);
Now, I would like to log every request that the service receives from clients and response that is being sent back to clients...in this case it sin JSOn.
I have create a custom MessageInspector as follows
public class MyMessageInspector : IDispatchMessageInspector
{
private bool LoggingEnabled;
#region IDispatchMessageInspector Members
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
Guid correlationState = Guid.NewGuid();
if (this.LoggingEnabled)
{
StringBuilder message = new StringBuilder();
message.AppendFormat("CorrelationState = {0}{1}", correlationState, Environment.NewLine);
message.AppendFormat("Local Address = {0}{1}", channel.LocalAddress, Environment.NewLine);
message.AppendFormat("Remote Address = {0}{1}", channel.RemoteAddress, Environment.NewLine);
message.AppendLine("Request");
message.AppendLine(request.ToString());
message.AppendLine();
this.logger.LogMessage(message.ToString());
}
return correlationState;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
if (this.LoggingEnabled)
{
StringBuilder message = new StringBuilder();
message.AppendFormat("CorrelationState = {0}{1}", correlationState, Environment.NewLine);
message.AppendLine("Reply");
message.AppendLine(reply.ToString());
message.AppendLine();
this.logger.LogMessage(message.ToString());
}
}
#endregion
}
But this doesnt seem to log any of the resposne.. the response.Tostring() only says "...stream"
the Above works if my service returns data in SOAP XML format..but i want it to log JSON response which is the text inside the *.js file downloaded in the browser when i call the REST service endpoint. ex: http://localhost:8080/MyService/me/2/
any ideas how I can achieve this?
This code provides a mechanism for working with REST messages, and as a bonus allows SOAP to pass through as normal. It's a little intrusive (the stream is destroyed by reading so the code needs to regenerate it) but I haven't found any better way.
http://code.msdn.microsoft.com/WCF-REST-Message-Inspector-c4b6790b