I've followed this video series on WCF and have the demo working. It involves building a WCF service that manages student evaluation forms, and implements CRUD operations to operate on a list of those evaluations. I've modified my code a little according to this guide so it will return JSON results to a browser or Fiddler request. My goal is to figure out how to use the service by building my own requests in Fiddler, and then use that format to consume the service from an app on a mobile device.
I'm having trouble using the SubmitEval
method (save an evaluation) from Fiddler. The call works, but all the fields of Eval
are null (or default) except Id
, which is set in the service itself.
Here is my Eval
declaration (using properties instead of fields as per this question):
[DataContract]
public class Eval //Models an evaluation
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Submitter { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public DateTime TimeSubmitted { get; set; }
}
And here is the relevant part of IEvalService
:
[ServiceContract]
public interface IEvalService
{
...
[OperationContract]
[WebInvoke(RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json, UriTemplate = "eval")]
void SubmitEval(Eval eval);
}
And EvalService
:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
class EvalService : IEvalService
{
...
public void SubmitEval(Eval eval)
{
eval.Id = Guid.NewGuid().ToString();
Console.WriteLine("Received eval");
evals.Add(eval);
}
}
In Fiddler's Request Builder, I set the Method to POST and the address to http://localhost:49444/EvalServiceSite/Eval.svc/eval
. I added the header Content-Type: application/json; charset=utf-8
to the default headers. The request body is:
{"eval":{"Comment":"testComment222","Id":"doesntMatter",
"Submitter":"Tom","TimeSubmitted":"11/10/2011 4:00 PM"}}
The response I get from sending that request is 200
, but when I then look at the Evals that have been saved, the one I just added has a valid Id
, but Comment
and Submitter
are both null, and TimeSubmitted
is 1/1/0001 12:00:00 AM
.
It seems like WCF is getting the request, but is not deserializing the object correctly. But if that's the case, I don't know why it's not throwing some sort of exception. Does it look like I'm doing this right, or am I missing something?
UPDATE: Here is the endpoint declaration in App.config:
<endpoint binding="webHttpBinding" behaviorConfiguration="webHttp"
contract="EvalServiceLibrary.IEvalService" />
And the endpoint behavior referred to:
<behavior name="webHttp">
<webHttp defaultOutgoingResponseFormat="Json"/>
</behavior>
The default body style in the
WebInvoke
attribute is Bare, meaning that the object should be sent without a wrapper containing the object name:Or you can set the request body style to
Wrapped
, and that would make the input require the wrapping{"eval"...}
object:Update: there's another problem in your code, since you're using
DateTime
, and the format expected by the WCF serializer for dates in JSON is something like\/Date(1234567890)\/
. You can change your class to support the format you have by following the logic described at MSDN Link (fine-grained control of serialization format for primitives), and shown in the code below.For POST you need to use BodyStyle = WebMessageBodyStyle.Bare NOT
WebMessageBodyStyle.Wrapped