CraigB
CraigB

Reputation: 65

Using the Json.NET serializer in an MVC4 project

I'm starting to learn Json.NET, but I'm having trouble using its serializer. I have a new MVC4 project with a Web.API service:

public class PTE_TestsController : ApiController {

  PTE_TestsRepository _repository = new PTE_TestsRepository();

  // GET /api/PTE_Tests/5
  public HttpResponseMessage<string> Get(int id) {
    try {
       PTE_Test test = _repository.GetTest(id);
       return new HttpResponseMessage<string>(JsonConvert.SerializeObject(test));
    } catch {
       return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
    }
  }
}

JsonConvert.SerializeObject() works as expected and returns a string. My Web.API controller returns that as part of an HttpResponseMessage. The end result, when viewed in Fiddler, is not JSON data, but JSON data being serialized again (I think):

"{\"ID\":1,\"Name\":\"Talar Tilt\",\"TagID\":1,\"PracticeID\":1,
   \"SpecificAreaID\":1,\"TypeID\":1,\"VideoID\":1,\"PicID\":1}"

Does someone know how to turn off the default serializer so I can use Json.NET directly? By the way, I'm not using the default serializer because I can't figure out how to make it work with complex objects (PTE_Test will eventually contain members of type List).

Alternately, it will also solve my problem if someone can explain how to use the default serializer with complex objects. MSDN's explanation didn't help me.

Upvotes: 6

Views: 19060

Answers (3)

EBarr
EBarr

Reputation: 12026

As others have pointed out, you need to create a formatter and replace the DataContractSerializer with the JSON.NET serializer. Although, if you're not in a rush for JSON.NET specifically, rumor has it that next beta/rc is going to have support for JSON.NET built in.

Conceptually, however, you're missing part of the magic of WebAPI. With WebAPI you return your object in it's native state (or IQueryable if you want OData support). After your function call finishes the Formatter's take over and convert it into the proper shape based on the client request.

So in your original code, you converted PTE_Test into a JSON string and returned it, at which point the JSON Formatter kicked in and serialized the string. I modified your code as follows:

  public class PTE_TestsController : ApiController {
    PTE_TestsRepository _repository = new PTE_TestsRepository();

    public HttpResponseMessage<PTE_Test> Get(int id)  {
        try {
            PTE_Test test = _repository.GetTest(id);
            return new HttpResponseMessage(test);
        } catch {
            return new HttpResponseMessage<string>(HttpStatusCode.NotFound);
        }
     }
   }

Notice how your function returns PTE_Test instead of string. Assuming the request came in with a request header of Accept = application/json then the JSON formatter will be invoked. If the request had a header of : Accept = text/xml the XML formatter is invoked.

There's a decent article on the topic here. If you're a visual learner, Scott Gu shows some examples using fiddler in this video, starting around 37 minutes. Pedro Reys digs a little deeper into content negotiation here.

Upvotes: 2

Aliostad
Aliostad

Reputation: 81700

Rick Strahl has a blog on that here with a code that works.

Upvotes: 5

David Peden
David Peden

Reputation: 18464

The way to do this is to use formatters.

Check out: https://github.com/WebApiContrib/WebAPIContrib/tree/master/src/WebApiContrib.Formatting.JsonNet.

Json.NET support will be in the RC release of Web API.

Upvotes: 0

Related Questions